00001
00002
00003
00004
00005
00006
00007 #ifndef _SIMULATOR_H
00008 #define _SIMULATOR_H
00009
00010 #include <list>
00011 #include <map>
00012 #include <set>
00013 #include <boost/shared_ptr.hpp>
00014 #include <Inventor/nodes/SoSeparator.h>
00015 #include <Physsim/Base.h>
00016 #include <Physsim/VectorN.h>
00017
00018 namespace Physsim {
00019
00020 class RigidBody;
00021 class ArticulatedBody;
00022 class Integrator;
00023 class RecurrentForce;
00024 class VisualizationData;
00025 class DynamicBody;
00026
00028
00033 class Simulator : public Base
00034 {
00035 public:
00036 Simulator();
00037 virtual ~Simulator();
00038 virtual void determine_external_forces();
00039 virtual bool is_struct_identical(BaseConstPtr object) const;
00040 virtual void clone(BasePtr& cloned, bimap<BasePtr, BasePtr>* obj_map = NULL) const;
00041 virtual void load_state(BaseConstPtr object, bimap<BasePtr, BasePtr>* correspondence = NULL);
00042 virtual void save_state(BasePtr object, bimap<BasePtr, BasePtr>* correspondence = NULL) const;
00043 virtual Real step(Real step_size);
00044 DynamicBodyPtr find_dynamic_body(const std::string& name) const;
00045 RigidBodyPtr find_rigid_body(const std::string& name) const;
00046 ArticulatedBodyPtr find_articulated_body(const std::string& name) const;
00047 std::list<RigidBodyPtr> get_all_rigid_bodies() const;
00048 void add_dynamic_body(DynamicBodyPtr body);
00049 void set_dynamic_bodies(const std::vector<DynamicBodyPtr>& bodies);
00050 void update_visualization();
00051 virtual void save_to_xml(XMLTreePtr node, std::list<BaseConstPtr>& shared_objects) const;
00052 virtual void load_from_xml(XMLTreeConstPtr node, std::map<std::string, BasePtr>& id_map);
00053 void set_recurrent_forces(const std::vector<RecurrentForcePtr>& forces);
00054 void add_recurrent_force(RecurrentForcePtr force);
00055 void set_recurrent_forces_enabled(bool flag);
00056
00058 const std::vector<RecurrentForcePtr>& get_recurrent_forces() const { return _recurrent_forces; }
00059
00060
00061 bool get_recurrent_force_enabled(RecurrentForcePtr force) { return _active_forces.find(force) != _active_forces.end(); }
00062
00064 void set_recurrent_force_enabled(RecurrentForcePtr force, bool flag) { if (flag) _active_forces.insert(force); else _active_forces.erase(force); }
00065
00067
00071 const std::vector<DynamicBodyPtr>& get_dynamic_bodies() const { return _bodies; }
00072
00074 IntegratorPtr get_integrator() { return _integrator; }
00075
00077 Real get_time() const { return _current_time; }
00078
00080
00086 Real get_regression_factor() const { return _regression_factor; }
00087
00089 void set_integrator(IntegratorPtr integrator) { _integrator = integrator; }
00090
00092 void set_time(Real time) { assert(time >= 0.0); _current_time = time; }
00093
00095
00101 void set_regression_factor(Real regression_factor) { assert(regression_factor >= 1.0); _regression_factor = regression_factor; }
00102
00104 void add_transient_vdata(SoNode* vdata) { _transient_vdata->addChild(vdata); }
00105
00107 SoSeparator* get_persistent_vdata() const { return _persistent_vdata; }
00108
00110 SoSeparator* get_transient_vdata() const { return _transient_vdata; }
00111
00112 protected:
00113 SoSeparator* _persistent_vdata;
00114 SoSeparator* _transient_vdata;
00115 std::vector<DynamicBodyPtr> _bodies;
00116 std::vector<RecurrentForcePtr> _recurrent_forces;
00117 std::set<RecurrentForcePtr> _active_forces;
00118 void integrate(Real step_size);
00119 Real _regression_factor;
00120
00122
00129 bool _external_forces_determined;
00130
00131 private:
00132 Real _current_time;
00133 IntegratorPtr _integrator;
00134
00136 static VectorN ode(const VectorN& x, Real t, void* data) { return *((VectorN*) data); }
00137 static void* set_dynamic_body_state(void* arg);
00138 static void* get_dynamic_body_state_deriv(void* arg);
00139 };
00140 }
00141
00142 #endif
00143