dynamics3d_engine.cpp
Go to the documentation of this file.
1 
7 #include "dynamics3d_engine.h"
8 
9 #include <argos3/core/simulator/simulator.h>
10 #include <argos3/core/simulator/space/space.h>
11 #include <argos3/core/simulator/entity/embodied_entity.h>
12 #include <argos3/plugins/simulator/physics_engines/dynamics3d/dynamics3d_model.h>
13 #include <argos3/plugins/simulator/physics_engines/dynamics3d/dynamics3d_plugin.h>
14 
15 #include <algorithm>
16 
17 namespace argos {
18 
19  /****************************************/
20  /****************************************/
21 
23  m_pcRNG(nullptr),
24  m_cRandomSeedRange(0,1000),
25  m_fDefaultFriction(1.0f),
26  m_cBroadphase(),
27  m_cConfiguration(),
28  m_cDispatcher(&m_cConfiguration),
29  m_cSolver(),
30  m_cWorld(&m_cDispatcher,
31  &m_cBroadphase,
32  &m_cSolver,
33  &m_cConfiguration) {}
34 
35  /****************************************/
36  /****************************************/
37 
39  /* Initialize parent */
40  CPhysicsEngine::Init(t_tree);
41  /* Create the random number generator */
42  m_pcRNG = CRandom::CreateRNG("argos");
43  /* Set random seed */
44  m_cSolver.setRandSeed(m_pcRNG->Uniform(m_cRandomSeedRange));
45  /* Disable gravity by default */
46  m_cWorld.setGravity(btVector3(0.0,0.0,0.0));
47  /* Load the plugins */
48  TConfigurationNodeIterator tPluginIterator;
49  for(tPluginIterator = tPluginIterator.begin(&t_tree);
50  tPluginIterator != tPluginIterator.end();
51  ++tPluginIterator) {
52  CDynamics3DPlugin* pcPlugin = CFactory<CDynamics3DPlugin>::New(tPluginIterator->Value());
53  pcPlugin->SetEngine(*this);
54  pcPlugin->Init(*tPluginIterator);
55  AddPhysicsPlugin(tPluginIterator->Value(), *pcPlugin);
56  }
57  GetNodeAttributeOrDefault(t_tree, "debug_file", m_strDebugFilename, m_strDebugFilename);
58  GetNodeAttributeOrDefault(t_tree, "default_friction", m_fDefaultFriction, m_fDefaultFriction);
59  }
60 
61  /****************************************/
62  /****************************************/
63 
65  /* Call reset to set up the simulation */
66  Reset();
67  }
68 
69  /****************************************/
70  /****************************************/
71 
73  /* Remove and reset all physics models */
74  for(auto itModel = std::begin(m_tPhysicsModels);
75  itModel != std::end(m_tPhysicsModels);
76  ++itModel) {
77  /* Remove model from plugins */
78  for(auto itPlugin = std::begin(m_tPhysicsPlugins);
79  itPlugin != std::end(m_tPhysicsPlugins);
80  ++itPlugin) {
81  itPlugin->second->UnregisterModel(*itModel->second);
82  }
83  /* Remove model from world */
84  itModel->second->RemoveFromWorld(m_cWorld);
85  /* Reset the model */
86  itModel->second->Reset();
87  }
88  /* Run the destructors on bullet's components */
89  m_cWorld.~btMultiBodyDynamicsWorld();
90  m_cSolver.~btMultiBodyConstraintSolver();
91  m_cDispatcher.~btCollisionDispatcher();
92  m_cConfiguration.~btDefaultCollisionConfiguration();
93  m_cBroadphase.~btDbvtBroadphase();
94  /* Rerun the constructors for the bullet's components */
95  new (&m_cBroadphase) btDbvtBroadphase;
96  new (&m_cConfiguration) btDefaultCollisionConfiguration;
97  new (&m_cDispatcher) btCollisionDispatcher(&m_cConfiguration);
98  new (&m_cSolver) btMultiBodyConstraintSolver;
99  new (&m_cWorld) btMultiBodyDynamicsWorld(&m_cDispatcher,
100  &m_cBroadphase,
101  &m_cSolver,
102  &m_cConfiguration);
103  /* Provide the same random seed to the solver */
104  m_cSolver.setRandSeed(m_pcRNG->Uniform(m_cRandomSeedRange));
105  /* Reset the plugins */
106  for(auto itPlugin = std::begin(m_tPhysicsPlugins);
107  itPlugin != std::end(m_tPhysicsPlugins);
108  ++itPlugin) {
109  itPlugin->second->Reset();
110  }
111  /* Set up the call back for the plugins */
112  m_cWorld.setInternalTickCallback([] (btDynamicsWorld* pc_world, btScalar f_time_step) {
113  auto* pc_engine = static_cast<CDynamics3DEngine*>(pc_world->getWorldUserInfo());
114  pc_world->clearForces();
115  for(std::pair<const std::string, CDynamics3DPlugin*>& c_plugin :
116  pc_engine->GetPhysicsPlugins()) {
117  c_plugin.second->Update();
118  }
119  }, static_cast<void*>(this), true);
120  /* Add the models back into the engine */
121  for(auto itModel = std::begin(m_tPhysicsModels);
122  itModel != std::end(m_tPhysicsModels);
123  ++itModel) {
124  /* Add model to plugins */
125  for(auto itPlugin = std::begin(m_tPhysicsPlugins);
126  itPlugin != std::end(m_tPhysicsPlugins);
127  ++itPlugin) {
128  itPlugin->second->RegisterModel(*itModel->second);
129  }
130  /* Add model to world */
131  itModel->second->AddToWorld(m_cWorld);
132  }
133  /* Initialize any multi-body constraints */
134  for (SInt32 i = 0; i < m_cWorld.getNumMultiBodyConstraints(); i++) {
135  m_cWorld.getMultiBodyConstraint(i)->finalizeMultiDof();
136  }
137  }
138 
139  /****************************************/
140  /****************************************/
141 
143  /* Destroy all physics models */
144  for(auto itModel = std::begin(m_tPhysicsModels);
145  itModel != std::end(m_tPhysicsModels);
146  ++itModel) {
147  /* Remove model from the plugins first */
148  for(auto itPlugin = std::begin(m_tPhysicsPlugins);
149  itPlugin != std::end(m_tPhysicsPlugins);
150  ++itPlugin) {
151  itPlugin->second->UnregisterModel(*itModel->second);
152  }
153  /* Destroy the model */
154  itModel->second->RemoveFromWorld(m_cWorld);
155  delete itModel->second;
156  }
157  /* Destroy all plug-ins */
158  for(auto itPlugin = std::begin(m_tPhysicsPlugins);
159  itPlugin != std::end(m_tPhysicsPlugins);
160  ++itPlugin) {
161  itPlugin->second->Destroy();
162  delete itPlugin->second;
163  }
164  /* Empty the maps */
165  m_tPhysicsPlugins.clear();
166  m_tPhysicsModels.clear();
167  }
168 
169  /****************************************/
170  /****************************************/
171 
173  /* Update the physics state from the entities */
174  for(auto it = m_tPhysicsModels.begin();
175  it != std::end(m_tPhysicsModels); ++it) {
176  it->second->UpdateFromEntityStatus();
177  }
178  /* Step the simuation forwards */
179  m_cWorld.stepSimulation(GetSimulationClockTick(),
180  GetIterations(),
182  /* Update the simulated space */
183  for(auto it = std::begin(m_tPhysicsModels);
184  it != std::end(m_tPhysicsModels);
185  ++it) {
186  it->second->UpdateEntityStatus();
187  }
188  /* Dump the state of the world to a bullet file (if requested) */
189  if(!m_strDebugFilename.empty()) {
190  btDefaultSerializer cSerializer;
191  m_cWorld.serialize(&cSerializer);
192  std::ofstream cDebugOutput(m_strDebugFilename);
193  if(cDebugOutput.is_open()) {
194  cDebugOutput.write(reinterpret_cast<const char*>(cSerializer.getBufferPointer()),
195  cSerializer.getCurrentBufferSize());
196  }
197  }
198  }
199 
200  /****************************************/
201  /****************************************/
202 
204  const CRay3& c_ray) const {
205  /* Convert the start and end ray vectors to the bullet coordinate system */
206  btVector3 cRayStart(c_ray.GetStart().GetX(), c_ray.GetStart().GetZ(), -c_ray.GetStart().GetY());
207  btVector3 cRayEnd(c_ray.GetEnd().GetX(), c_ray.GetEnd().GetZ(), -c_ray.GetEnd().GetY());
208  btCollisionWorld::ClosestRayResultCallback cResult(cRayStart, cRayEnd);
209  /* The default flag/algorithm 'kF_UseSubSimplexConvexCastRaytest' is too approximate for
210  our purposes */
211  cResult.m_flags |= btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest;
212  /* Run the ray test */
213  m_cWorld.rayTest(cRayStart, cRayEnd, cResult);
214  /* Examine the results */
215  if (cResult.hasHit() && cResult.m_collisionObject->getUserPointer() != nullptr) {
216  Real f_t = (cResult.m_hitPointWorld - cRayStart).length() / c_ray.GetLength();
217  auto* pcModel =
218  static_cast<CDynamics3DModel*>(cResult.m_collisionObject->getUserPointer());
219  t_data.push_back(SEmbodiedEntityIntersectionItem(&(pcModel->GetEmbodiedEntity()), f_t));
220  }
221  }
222 
223  /****************************************/
224  /****************************************/
225 
227  return m_tPhysicsModels.size();
228  }
229 
230  /****************************************/
231  /****************************************/
232 
234  SOperationOutcome cOutcome =
235  CallEntityOperation<CDynamics3DOperationAddEntity, CDynamics3DEngine, SOperationOutcome>
236  (*this, c_entity);
237  return cOutcome.Value;
238  }
239 
240  /****************************************/
241  /****************************************/
242 
244  SOperationOutcome cOutcome =
245  CallEntityOperation<CDynamics3DOperationRemoveEntity, CDynamics3DEngine, SOperationOutcome>
246  (*this, c_entity);
247  return cOutcome.Value;
248  }
249 
250  /****************************************/
251  /****************************************/
252 
253  void CDynamics3DEngine::AddPhysicsModel(const std::string& str_id,
254  CDynamics3DModel& c_model) {
255  /* Add model to world */
256  c_model.AddToWorld(m_cWorld);
257  /* Notify the plugins of the added model */
258  for(auto itPlugin = std::begin(m_tPhysicsPlugins);
259  itPlugin != std::end(m_tPhysicsPlugins);
260  ++itPlugin) {
261  itPlugin->second->RegisterModel(c_model);
262  }
263  /* Add a pointer to the model to the map of models */
264  m_tPhysicsModels[str_id] = &c_model;
265  }
266 
267  /****************************************/
268  /****************************************/
269 
270  void CDynamics3DEngine::RemovePhysicsModel(const std::string& str_id) {
271  auto itModel = m_tPhysicsModels.find(str_id);
272  if(itModel != std::end(m_tPhysicsModels)) {
273  /* Notify the plugins of model removal */
274  for(auto itPlugin = std::begin(m_tPhysicsPlugins);
275  itPlugin != std::end(m_tPhysicsPlugins);
276  ++itPlugin) {
277  itPlugin->second->UnregisterModel(*(itModel->second));
278  }
279  /* Remove the model from world */
280  itModel->second->RemoveFromWorld(m_cWorld);
281  /* Destroy the model */
282  delete itModel->second;
283  /* Remove the model from the map */
284  m_tPhysicsModels.erase(itModel);
285  }
286  else {
287  THROW_ARGOSEXCEPTION("The model \"" << str_id <<
288  "\" was not found in the dynamics 3D engine \"" <<
289  GetId() << "\"");
290  }
291  }
292 
293  /****************************************/
294  /****************************************/
295 
296  void CDynamics3DEngine::AddPhysicsPlugin(const std::string& str_id,
297  CDynamics3DPlugin& c_plugin) {
298  m_tPhysicsPlugins[str_id] = &c_plugin;
299  }
300 
301  /****************************************/
302  /****************************************/
303 
304  void CDynamics3DEngine::RemovePhysicsPlugin(const std::string& str_id) {
305  auto it = m_tPhysicsPlugins.find(str_id);
306  if(it != std::end(m_tPhysicsPlugins)) {
307  delete it->second;
308  m_tPhysicsPlugins.erase(it);
309  }
310  else {
311  THROW_ARGOSEXCEPTION("The plugin \"" << str_id <<
312  "\" was not found in the dynamics 3D engine \"" <<
313  GetId() << "\"");
314  }
315  }
316 
317  /****************************************/
318  /****************************************/
319 
321  "dynamics3d",
322  "Michael Allwright [allsey87@gmail.com]",
323  "1.0",
324  "A 3D dynamics physics engine",
325  "This physics engine is a 3D dynamics engine based on the Bullet Physics SDK\n"
326  "(https://github.com/bulletphysics/bullet3).\n\n"
327 
328  "REQUIRED XML CONFIGURATION\n\n"
329  " <physics_engines>\n"
330  " ...\n"
331  " <dynamics3d id=\"dyn3d\" />\n"
332  " ...\n"
333  " </physics_engines>\n\n"
334 
335  "The 'id' attribute is necessary and must be unique among the physics engines.\n\n"
336 
337  "Multiple physics engines of this type cannot be used, and defining '<boundaries>'\n"
338  "as a child tag under the '<dynamics3d>' tree will result in an initialization error.\n\n"
339 
340  "OPTIONAL XML CONFIGURATION\n\n"
341 
342  "It is possible to change the default friction used in the simulation from\n"
343  "its initial value of 1.0 using the default_friction attribute as shown\n"
344  "below. For debugging purposes, it is also possible to provide a filename\n"
345  "via the debug_file attribute which will cause the Bullet world to be\n"
346  "serialized and written out to a file at the end of each step. This file can\n"
347  "then be opened using the Bullet example browser and can provide useful\n"
348  "insights into the stability of a simulation.\n\n"
349 
350  " <physics_engines>\n"
351  " ...\n"
352  " <dynamics3d id=\"dyn3d\"\n"
353  " default_friction=\"1.0\"\n"
354  " debug_file=\"dynamics3d.bullet\"/>\n"
355  " ...\n"
356  " </physics_engines>\n\n"
357 
358  "The physics engine supports a number of plugins that add features to the\n"
359  "simulation. In the example below, a floor plane has been added which has a\n"
360  "height of 1 cm and the dimensions of the floor as specified by the arena\n"
361  "node. It is possible to change the coefficient of friction of the floor\n"
362  "using the friction attribute. This will override the default friction used\n"
363  "by the physics engine. By default, there will be no gravity in the\n"
364  "simulation. This can be changed by adding a gravity node with a single\n"
365  "attribute 'g' which is the downwards acceleration caused by gravity.\n"
366  "Finally, there is a magnetism plugin. This plugin applies forces and\n"
367  "torques to bodies in the simulation that contains magnetic dipoles. The\n"
368  "'max_distance' attribute is an optional optimization that sets the maximum\n"
369  "distance at which two magnetic dipoles will interact with each other. In\n"
370  "the example below, this distance has been set to 4 cm.\n\n"
371 
372  " <physics_engines>\n"
373  " ...\n"
374  " <dynamics3d id=\"dyn3d\" default_friction=\"2.0\">\n"
375  " <floor height=\"0.01\" friction=\"0.05\"/>\n"
376  " <gravity g=\"10\" />\n"
377  " <magnetism max_distance=\"0.04\" />\n"
378  " </dynamics3d>\n"
379  " ...\n"
380  " </physics_engines>\n\n",
381 
382  "Usable (multiple engines not supported)"
383  );
384 
385  /****************************************/
386  /****************************************/
387 
388 }
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
signed int SInt32
32-bit signed integer.
Definition: datatypes.h:93
float Real
Collects all ARGoS code.
Definition: datatypes.h:39
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
ticpp::Iterator< ticpp::Element > TConfigurationNodeIterator
The iterator for the ARGoS configuration XML node.
void GetNodeAttributeOrDefault(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer, const T &t_default)
Returns the value of a node's attribute, or the passed default value.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
REGISTER_PHYSICS_ENGINE(CDynamics2DEngine, "dynamics2d", "Carlo Pinciroli [ilpincy@gmail.com]", "1.0", "A 2D dynamics physics engine.", "This physics engine is a 2D dynamics engine based on the Chipmunk library\n" "(http://code.google.com/p/chipmunk-physics) version 6.0.1.\n\n" "REQUIRED XML CONFIGURATION\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\" />\n" " ...\n" " </physics_engines>\n\n" "The 'id' attribute is necessary and must be unique among the physics engines.\n" "If two engines share the same id, initialization aborts.\n\n" "OPTIONAL XML CONFIGURATION\n\n" "It is possible to set how many iterations this physics engine performs between\n" "each simulation step. By default, this physics engine performs 10 steps every\n" "two simulation steps. This means that, if the simulation step is 100ms, the\n" "physics engine step is, by default, 10ms. Sometimes, collisions and joints are\n" "not simulated with sufficient precision using these parameters. By increasing\n" "the number of iterations, the temporal granularity of the solver increases and\n" "with it its accuracy, at the cost of higher computational cost. To change the\n" "number of iterations per simulation step use this syntax:\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\"\n" " iterations=\"20\" />\n" " ...\n" " </physics_engines>\n\n" "The plane of the physics engine can be translated on the Z axis, to simulate\n" "for example hovering objects, such as flying robots. To translate the plane\n" "2m up the Z axis, use the 'elevation' attribute as follows:\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\"\n" " elevation=\"2.0\" />\n" " ...\n" " </physics_engines>\n\n" "When not specified, the elevation is zero, which means that the plane\n" "corresponds to the XY plane.\n\n" "The friction parameters between the ground and movable boxes and cylinders can\n" "be overridden. You can set both the linear and angular friction parameters.\n" "The default value is 1.49 for each of them. To override the values, use this\n" "syntax (all attributes are optional):\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\">\n" " <friction box_linear_friction=\"1.0\"\n" " box_angular_friction=\"2.0\"\n" " cylinder_linear_friction=\"3.0\"\n" " cylinder_angular_friction=\"4.0\" />\n" " </dynamics2d>\n" " ...\n" " </physics_engines>\n\n" "For the the robots that use velocity-based control, such as ground robots with\n" "the differential_steering actuator (e.g. the foot-bot and the e-puck), it is\n" "possible to customize robot-specific attributes that set the maximum force and\n" "torque the robot has. The syntax is as follows, taking a foot-bot as example:\n\n" " <arena ...>\n" " ...\n" " <foot-bot id=\"fb0\">\n" " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n" " <controller config=\"mycntrl\" />\n" " <!-- Specify new value for max_force and max_torque -->\n" " <dynamics2d>\n" " <differential_steering max_force=\"0.1\" max_torque=\"0.1\"/>\n" " </dynamics2d>\n" " </foot-bot>\n" " ...\n" " </arena>\n\n" "The attributes 'max_force' and 'max_torque' are both optional, and they take the\n" "robot-specific default if not set. Check the code of the dynamics2d model of the\n" "robot you're using to know the default values.\n\n" "Multiple physics engines can also be used. If multiple physics engines are used,\n" "the disjoint union of the area within the arena assigned to each engine must cover\n" "the entire arena without overlapping. If the entire arena is not covered, robots can\n" "\"escape\" the configured physics engines and cause a fatal exception (this is not an\n" "issue when a single physics engine is used, because the engine covers the entire arena\n" "by default). To use multiple physics engines, use the following syntax (all attributes\n" "are mandatory):\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d0\">\n" " <boundaries>\n" " <top height=\"1.0\"/>\n" " <botton height=\"0.0\"/>\n" " <sides>\n" " <vertex point=\"0.0, 0.0\"/>\n" " <vertex point=\"4.0, 0.0\"/>\n" " <vertex point=\"4.0, 4.0\"/>\n" " <vertex point=\"0.0, 4.0\"/>\n" " </sides>\n" " </boundaries>\n" " </dynamics2d>\n" " <dynamics2d id=\"dyn2d1\">\n" " ..." " </dynamics2d>\n" " ...\n" " </physics_engines>\n\n" "The 'top' and 'bottom' nodes are relevant for 3D physics engines. For 2D\n" "engines, it safe to set their height to 1.0 and 0.0, respectively. A physics\n" "engine can be defined having any number of sides >= 3, as long as the sides form\n" "a closed polygon in the 2D plane. The vertices must be declared in\n" "counter-clockwise order. In the above example, the physics engine \"dyn2d0\" is\n" "assigned to the area within the arena with lower-left coordinates (0,0) and\n" "upper-right coordinates (4,4) and vertices are specified in counter clockwise\n" "order: south-east, south-west, north-west, north-east.\n\n" "OPTIMIZATION HINTS\n\n" "1. A single physics engine is generally sufficient for small swarms (say <= 50\n" " robots) within a reasonably small arena to obtain faster than real-time\n" " performance with optimized code. For larger swarms and/or large arenas,\n" " multiple engines should be used for maximum performance.\n\n" "2. In general, using the same number of ARGoS threads as physics engines gives\n" " maximum performance (1-thread per engine per CPU core).\n\n" "3. Using multiple engines in simulations with any of the following\n" " characteristics generally incurs more overhead (due to thread context\n" " switching) than the performance benefits from multiple engines:\n" " - Small swarms\n" " - Small arenas\n" " - Less available ARGoS threads than assigned physics engines\n" " - Less available CPU cores than assigned ARGoS threads\n\n" "4. A good starting strategy for physics engine boundary assignment is to assign\n" " each physics engine the same amount of area within the arena. This will be\n" " sufficient for most cases. Depending on the nature of the simulation, using\n" " non-homogeneous physics engine sizes may yield increased performance. An\n" " example would be a narrow hallway between larger open areas in the arena--the\n" " hallway will likely experience increased robot density and assigning more\n" " physics engines to that area than the relatively unpopulated open areas may\n" " increase performance.\n\n" "5. By default, this engine uses the bounding-box tree method for collision shape\n" " indexing. This method is the default in Chipmunk and it works well most of\n" " the times. However, if you are running simulations with hundreds or thousands\n" " of identical robots, a different shape collision indexing is available: the\n" " spatial hash. The spatial hash is a grid stored in a hashmap. To get the max\n" " out of this indexing method, you must set two parameters: the cell size and\n" " the suggested minimum number of cells in the space. According to the\n" " documentation of Chipmunk, the cell size should correspond to the size of the\n" " bounding box of the most common object in the simulation; the minimum number\n" " of cells should be at least 10x the number of objects managed by the physics\n" " engine. To use this indexing method, use this syntax (all attributes are\n" " mandatory):\n\n" " <physics_engines>\n" " ...\n" " <dynamics2d id=\"dyn2d\">\n" " <spatial_hash>\n" " <cell_size=\"1.0\"/>\n" " <cell_num=\"2.0\"/>\n" " </spatial_hash>\n" " </dynamics2d>\n" " ...\n" " </physics_engines>\n", "Usable")
std::vector< SEmbodiedEntityIntersectionItem > TEmbodiedEntityIntersectionData
The basic entity type.
Definition: entity.h:90
Type to use as return value for operation outcome.
Definition: entity.h:352
static Real GetSimulationClockTick()
Returns the simulation clock tick.
const std::string & GetId() const
Returns the id of this physics engine.
virtual void Init(TConfigurationNode &t_tree)
Initializes the resource.
Real GetPhysicsClockTick() const
Returns the length of the physics engine tick.
UInt32 GetIterations() const
Returns the number of iterations per simulation clock tick.
Real GetLength() const
Definition: ray3.h:96
CVector3 & GetEnd()
Definition: ray3.h:45
CVector3 & GetStart()
Definition: ray3.h:37
static CRNG * CreateRNG(const std::string &str_category)
Creates a new RNG inside the given category.
Definition: rng.cpp:347
CRadians Uniform(const CRange< CRadians > &c_range)
Returns a random value from a uniform distribution.
Definition: rng.cpp:87
Real GetX() const
Returns the x coordinate of this vector.
Definition: vector3.h:105
Real GetY() const
Returns the y coordinate of this vector.
Definition: vector3.h:121
Real GetZ() const
Returns the z coordinate of this vector.
Definition: vector3.h:137
static TYPE * New(const std::string &str_label)
Creates a new object of type TYPE
Definition: factory_impl.h:48
virtual size_t GetNumPhysicsModels()
void AddPhysicsModel(const std::string &str_id, CDynamics3DModel &c_model)
void RemovePhysicsModel(const std::string &str_id)
virtual bool AddEntity(CEntity &c_entity)
Adds an entity to the physics engine.
virtual void CheckIntersectionWithRay(TEmbodiedEntityIntersectionData &t_data, const CRay3 &c_ray) const
Check which objects in this engine intersect the given ray.
virtual bool RemoveEntity(CEntity &c_entity)
Removes an entity from the physics engine.
virtual void Reset()
Resets the resource.
virtual void Destroy()
Undoes whatever was done by Init().
void AddPhysicsPlugin(const std::string &str_id, CDynamics3DPlugin &c_plugin)
void RemovePhysicsPlugin(const std::string &str_id)
virtual void PostSpaceInit()
Executes extra initialization activities after the space has been initialized.
virtual void Init(TConfigurationNode &t_tree)
Initializes the resource.
virtual void AddToWorld(btMultiBodyDynamicsWorld &c_world)=0
virtual void SetEngine(CDynamics3DEngine &c_engine)
virtual void Init(TConfigurationNode &t_tree)