TDME2 1.9.121
World.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <iostream>
5#include <map>
6#include <string>
7#include <unordered_set>
8
9#include <tdme/tdme.h>
10#include <ext/reactphysics3d/src/collision/shapes/AABB.h>
11#include <ext/reactphysics3d/src/collision/ContactManifold.h>
12#include <ext/reactphysics3d/src/collision/OverlapCallback.h>
13#include <ext/reactphysics3d/src/collision/RaycastInfo.h>
14#include <ext/reactphysics3d/src/constraint/ContactPoint.h>
15#include <ext/reactphysics3d/src/engine/CollisionWorld.h>
16#include <ext/reactphysics3d/src/engine/DynamicsWorld.h>
17#include <ext/reactphysics3d/src/engine/EventListener.h>
18#include <ext/reactphysics3d/src/mathematics/Ray.h>
19#include <ext/reactphysics3d/src/mathematics/Vector3.h>
28#include <tdme/engine/Engine.h>
29#include <tdme/engine/Entity.h>
32#include <tdme/math/Math.h>
33#include <tdme/math/Matrix4x4.h>
35#include <tdme/math/Vector3.h>
38
39using std::find;
40using std::map;
41using std::remove;
42using std::string;
43using std::to_string;
44using std::unordered_set;
45
65
66World::World(): world(reactphysics3d::Vector3(0.0, -9.81, 0.0))
67{
68}
69
71{
72 for (auto worldListener: worldListeners) delete worldListener;
73 reset();
74}
75
77{
78 auto _bodies = bodies;
79 for (auto body: _bodies) removeBody(body->getId());
80 bodies.clear();
81 rigidBodiesDynamic.clear();
82 bodiesById.clear();
84}
85
86Body* World::addRigidBody(const string& id, bool enabled, uint16_t collisionTypeId, const Transformations& transformations, float restitution, float friction, float mass, const Vector3& inertiaTensor, vector<BoundingVolume*> boundingVolumes)
87{
88 removeBody(id);
89 auto body = new Body(this, id, Body::TYPE_DYNAMIC, enabled, collisionTypeId, transformations, restitution, friction, mass, inertiaTensor, boundingVolumes);
90 bodies.push_back(body);
91 rigidBodiesDynamic.push_back(body);
92 bodiesById[id] = body;
93 for (auto listener: worldListeners) {
94 listener->onAddedBody(id, Body::TYPE_DYNAMIC, enabled, collisionTypeId, transformations, restitution, friction, mass, inertiaTensor, boundingVolumes);
95 }
96 return body;
97}
98
99Body* World::addCollisionBody(const string& id, bool enabled, uint16_t collisionTypeId, const Transformations& transformations, vector<BoundingVolume*> boundingVolumes) {
100 removeBody(id);
101 auto body = new Body(this, id, Body::TYPE_COLLISION, enabled, collisionTypeId, transformations, 0.0f, 0.0f, 0.0f, Body::getNoRotationInertiaTensor(), boundingVolumes);
102 bodies.push_back(body);
103 bodiesById[id] = body;
104 for (auto listener: worldListeners) {
105 listener->onAddedBody(id, Body::TYPE_COLLISION, enabled, collisionTypeId, transformations, 0.0f, 0.0f, 0.0f, Body::getNoRotationInertiaTensor(), boundingVolumes);
106 }
107 return body;
108}
109
110Body* World::addStaticRigidBody(const string& id, bool enabled, uint16_t collisionTypeId, const Transformations& transformations, float friction, vector<BoundingVolume*> boundingVolumes)
111{
112 removeBody(id);
113 auto body = new Body(this, id, Body::TYPE_STATIC, enabled, collisionTypeId, transformations, 0.0f, friction, 0.0f, Body::getNoRotationInertiaTensor(), boundingVolumes);
114 bodies.push_back(body);
115 bodiesById[id] = body;
116 for (auto listener: worldListeners) {
117 listener->onAddedBody(id, Body::TYPE_STATIC, enabled, collisionTypeId, transformations, 0.0f, friction, 0.0f, Body::getNoRotationInertiaTensor(), boundingVolumes);
118 }
119 return body;
120}
121
122Body* World::getBody(const string& id)
123{
124 auto bodyByIdIt = bodiesById.find(id);
125 if (bodyByIdIt != bodiesById.end()) {
126 return bodyByIdIt->second;
127 }
128 return nullptr;
129}
130
131void World::removeBody(const string& id) {
132 auto bodyByIdIt = bodiesById.find(id);
133 if (bodyByIdIt != bodiesById.end()) {
134 auto body = bodyByIdIt->second;
135 if (body->rigidBody != nullptr) {
136 world.destroyRigidBody(body->rigidBody);
137 } else {
138 world.destroyCollisionBody(body->collisionBody);
139 }
140 bodies.erase(remove(bodies.begin(), bodies.end(), body), bodies.end());
141 rigidBodiesDynamic.erase(remove(rigidBodiesDynamic.begin(), rigidBodiesDynamic.end(), body), rigidBodiesDynamic.end());
142 bodiesById.erase(bodyByIdIt);
143 for (auto listener: worldListeners) {
144 listener->onRemovedBody(id, body->getType(), body->getCollisionTypeId());
145 }
146 delete body;
147 }
148}
149
150void World::update(float deltaTime)
151{
152 if (deltaTime < Math::EPSILON) return;
153
154 // do the job
155 world.update(deltaTime);
156
157 // collision events
158 {
159 // fire on collision begin, on collision
160 map<string, BodyCollisionStruct> bodyCollisionsCurrentFrame;
161 CollisionResponse collision;
162 auto manifolds = world.getContactsList();
163 for (auto manifold: manifolds) {
164 auto body1 = static_cast<Body*>(manifold->getBody1()->getUserData());
165 auto body2 = static_cast<Body*>(manifold->getBody2()->getUserData());
166 BodyCollisionStruct bodyCollisionStruct;
167 bodyCollisionStruct.body1Id = body1->getId();
168 bodyCollisionStruct.body2Id = body2->getId();
169 string bodyKey = bodyCollisionStruct.body1Id + "," + bodyCollisionStruct.body2Id;
170 string bodyKeyInverted = bodyCollisionStruct.body2Id + "," + bodyCollisionStruct.body1Id;
171 bodyCollisionsCurrentFrame[bodyKey] = bodyCollisionStruct;
172 for (int i=0; i<manifold->getNbContactPoints(); i++) {
173 auto contactPoint = manifold->getContactPoints();
174 while (contactPoint != nullptr) {
175 // construct collision
176 auto entity = collision.addResponse(-contactPoint->getPenetrationDepth());
177 auto normal = contactPoint->getNormal();
178 entity->setNormal(Vector3(normal.x, normal.y, normal.z));
179 auto shape1 = manifold->getShape1();
180 auto shape2 = manifold->getShape2();
181 auto& shapeLocalToWorldTransform1 = shape1->getLocalToWorldTransform();
182 auto& shapeLocalToWorldTransform2 = shape2->getLocalToWorldTransform();
183 auto& localPoint1 = contactPoint->getLocalPointOnShape1();
184 auto& localPoint2 = contactPoint->getLocalPointOnShape2();
185 auto worldPoint1 = shapeLocalToWorldTransform1 * localPoint1;
186 auto worldPoint2 = shapeLocalToWorldTransform2 * localPoint2;
187 entity->addHitPoint(Vector3(worldPoint1.x, worldPoint1.y, worldPoint1.z));
188 entity->addHitPoint(Vector3(worldPoint2.x, worldPoint2.y, worldPoint2.z));
189 contactPoint = contactPoint->getNext();
190 // fire events
191 if (bodyCollisionsLastFrame.find(bodyKey) == bodyCollisionsLastFrame.end() &&
192 bodyCollisionsLastFrame.find(bodyKeyInverted) == bodyCollisionsLastFrame.end()) {
193 // fire on collision begin
194 body1->fireOnCollisionBegin(body2, collision);
195 }
196 // fire on collision
197 body1->fireOnCollision(body2, collision);
198 // reset collision
199 collision.reset();
200 }
201 }
202 }
203
204 // fire on collision end
205 // check each collision last frame that disappeared in current frame
206 for (auto it: bodyCollisionsLastFrame) {
207 BodyCollisionStruct* bodyCollisionStruct = &it.second;
208 {
209 string bodyKey = bodyCollisionStruct->body1Id + "," + bodyCollisionStruct->body2Id;
210 auto bodyCollisionsCurrentFrameIt = bodyCollisionsCurrentFrame.find(bodyKey);
211 if (bodyCollisionsCurrentFrameIt != bodyCollisionsCurrentFrame.end()) continue;
212 }
213 {
214 string bodyKey = bodyCollisionStruct->body2Id + "," + bodyCollisionStruct->body1Id;
215 auto bodyCollisionsCurrentFrameIt = bodyCollisionsCurrentFrame.find(bodyKey);
216 if (bodyCollisionsCurrentFrameIt != bodyCollisionsCurrentFrame.end()) continue;
217 }
218 auto body1It = bodiesById.find(bodyCollisionStruct->body1Id);
219 auto body1 = body1It == bodiesById.end()?nullptr:body1It->second;
220 auto body2It = bodiesById.find(bodyCollisionStruct->body2Id);
221 auto body2 = body2It == bodiesById.end()?nullptr:body2It->second;
222 if (body1 == nullptr || body2 == nullptr) continue;
223 body1->fireOnCollisionEnd(body2);
224 }
225 // swap rigid body collisions current and last frame
226 bodyCollisionsLastFrame = bodyCollisionsCurrentFrame;
227 }
228
229 // update transformations for rigid body
230 for (auto i = 0; i < rigidBodiesDynamic.size(); i++) {
231 auto body = rigidBodiesDynamic[i];
232 // skip if disabled
233 if (body->isEnabled() == false) {
234 continue;
235 }
236 // skip if static or sleeping
237 if (body->isSleeping() == true) {
238 continue;
239 }
240
241 // rp3d transform
242 auto transform = body->rigidBody->getTransform();
243 auto transformPosition = transform.getPosition();
244 auto transformOrientation = transform.getOrientation();
245
246 // tdme2 transformations
247 auto& physicsTransformations = body->transformations;
248
249 // rotations
250 // keep care that only 1 rotation exists
251 while (physicsTransformations.getRotationCount() > 1) {
252 physicsTransformations.removeRotation(physicsTransformations.getRotationCount() - 1);
253 }
254 if (physicsTransformations.getRotationCount() < 1) {
255 physicsTransformations.addRotation(Vector3(0.0f, 1.0f, 0.0f), 0.0f);
256 }
257
258 // rotations
259 Quaternion rotationsQuaternion(transformOrientation.x, transformOrientation.y, transformOrientation.z, transformOrientation.w);
260 physicsTransformations.getRotation(0).fromQuaternion(rotationsQuaternion);
261 // scale
262 physicsTransformations.setScale(body->transformationsScale);
263 // translation
264 physicsTransformations.setTranslation(Vector3(transformPosition.x, transformPosition.y, transformPosition.z));
265 // done
266 physicsTransformations.update();
267 }
268}
269
270void World::synch(Engine* engine)
271{
272 for (auto i = 0; i < rigidBodiesDynamic.size(); i++) {
273 // update rigid body
274 auto body = rigidBodiesDynamic[i];
275
276 // skip on sleeping objects
277 if (body->isSleeping() == true) continue;
278
279 // synch with engine entity
280 auto engineEntity = engine->getEntity(body->id);
281 if (engineEntity == nullptr) {
282 Console::println(
283 string("World::entity '") +
284 body->id +
285 string("' not found")
286 );
287 continue;
288 }
289
290 // enable
291 engineEntity->setEnabled(body->isEnabled());
292
293 //apply inverse local transformation for engine update
294 if (body->isEnabled() == true) {
295 engineEntity->fromTransformations(body->transformations);
296 }
297 }
298}
299
300Body* World::determineHeight(uint16_t collisionTypeIds, float stepUpMax, const Vector3& point, Vector3& dest, float minHeight, float maxHeight)
301{
302 class CustomCallbackClass : public reactphysics3d::RaycastCallback {
303 public:
304 CustomCallbackClass(float stepUpMax, const Vector3& point, float height = 10000.0f): stepUpMax(stepUpMax), point(point), height(height), body(nullptr) {
305 }
306 virtual reactphysics3d::decimal notifyRaycastHit(const reactphysics3d::RaycastInfo& info) {
307 Vector3 hitPoint(info.worldPoint.x, info.worldPoint.y, info.worldPoint.z);
308 auto _body = static_cast<Body*>(info.body->getUserData());
309 if (hitPoint.getY() < height && hitPoint.getY() <= point.getY() + stepUpMax) {
310 height = hitPoint.getY();
311 body = static_cast<Body*>(info.body->getUserData());
312 }
313 return reactphysics3d::decimal(info.hitFraction);
314 };
315 Body* getBody() {
316 return body;
317 }
318 float getHeight() {
319 return height;
320 }
321 private:
322 float stepUpMax;
323 Vector3 point;
324 float height;
325 Body* body;
326 };
327 reactphysics3d::Vector3 startPoint(point.getX(), maxHeight, point.getZ());
328 reactphysics3d::Vector3 endPoint(point.getX(), minHeight, point.getZ());
329 reactphysics3d::Ray ray(startPoint, endPoint);
330 CustomCallbackClass customCallbackObject(stepUpMax, point, maxHeight);
331 world.raycast(ray, &customCallbackObject, collisionTypeIds);
332 if (customCallbackObject.getBody() != nullptr) {
333 dest.set(point);
334 dest.setY(customCallbackObject.getHeight());
335 return customCallbackObject.getBody();
336 } else {
337 return nullptr;
338 }
339}
340
341Body* World::doRayCasting(uint16_t collisionTypeIds, const Vector3& start, const Vector3& end, Vector3& hitPoint, const string& actorId)
342{
343 class CustomCallbackClass : public reactphysics3d::RaycastCallback {
344 public:
345 CustomCallbackClass(const string& actorId): actorId(actorId), body(nullptr) {
346 }
347 virtual reactphysics3d::decimal notifyRaycastHit(const reactphysics3d::RaycastInfo& info) {
348 auto _body = static_cast<Body*>(info.body->getUserData());
349 if (actorId.size() == 0 || _body->getId() != actorId) {
350 body = _body;
351 hitPoint.set(info.worldPoint.x, info.worldPoint.y, info.worldPoint.z);
352 return reactphysics3d::decimal(info.hitFraction);
353 } else {
354 return reactphysics3d::decimal(1.0);
355 }
356 };
357 Body* getBody() {
358 return body;
359 }
360 const Vector3& getHitPoint() {
361 return hitPoint;
362 }
363 private:
364 string actorId;
365 Vector3 hitPoint;
366 Body* body;
367 };
368 reactphysics3d::Vector3 startPoint(start.getX(), start.getY(), start.getZ());
369 reactphysics3d::Vector3 endPoint(end.getX(), end.getY(), end.getZ());
370 reactphysics3d::Ray ray(startPoint, endPoint);
371 CustomCallbackClass customCallbackObject(actorId);
372 world.raycast(ray, &customCallbackObject, collisionTypeIds);
373 if (customCallbackObject.getBody() != nullptr) {
374 hitPoint.set(customCallbackObject.getHitPoint());
375 return customCallbackObject.getBody();
376 } else {
377 return nullptr;
378 }
379}
380
381bool World::doesCollideWith(uint16_t collisionTypeIds, Body* body, vector<Body*>& rigidBodies) {
382 // callback
383 class CustomOverlapCallback: public reactphysics3d::OverlapCallback {
384 public:
385 CustomOverlapCallback(vector<Body*>& rigidBodies): rigidBodies(rigidBodies) {
386 }
387
388 virtual void notifyOverlap(reactphysics3d::CollisionBody* collisionBody) {
389 rigidBodies.push_back(static_cast<Body*>(collisionBody->getUserData()));
390 }
391 private:
392 vector<Body*>& rigidBodies;
393 };
394
395 // do the test
396 CustomOverlapCallback customOverlapCallback(rigidBodies);
397 world.testOverlap(body->collisionBody, &customOverlapCallback, collisionTypeIds);
398
399 // done
400 return rigidBodies.size() > 0;
401}
402
403bool World::doesCollideWith(uint16_t collisionTypeIds, const Transformations& transformations, vector<BoundingVolume*> boundingVolumes, vector<Body*>& rigidBodies) {
404 auto collisionBody = addCollisionBody("tdme.world.doescollidewith", true, 32768, transformations, boundingVolumes);
405 doesCollideWith(collisionTypeIds, collisionBody, rigidBodies);
406 removeBody("tdme.world.doescollidewith");
407 return rigidBodies.size() > 0;
408}
409
410bool World::doCollide(Body* body1, Body* body2) {
411 return world.testOverlap(body1->collisionBody, body2->collisionBody);
412}
413
414bool World::getCollisionResponse(Body* body1, Body* body2, CollisionResponse& collision) {
415 // callback
416 class CustomCollisionCallback: public reactphysics3d::CollisionCallback {
417 public:
418 CustomCollisionCallback(CollisionResponse& collision): collision(collision) {
419 }
420
421 void notifyContact(const CollisionCallbackInfo& collisionCallbackInfo) {
422 auto manifold = collisionCallbackInfo.contactManifoldElements;
423 while (manifold != nullptr) {
424 auto contactPoint = manifold->getContactManifold()->getContactPoints();
425 while (contactPoint != nullptr) {
426 // construct collision
427 auto entity = collision.addResponse(-contactPoint->getPenetrationDepth());
428 auto normal = contactPoint->getNormal();
429 entity->setNormal(Vector3(normal.x, normal.y, normal.z));
430 auto shape1 = manifold->getContactManifold()->getShape1();
431 auto shape2 = manifold->getContactManifold()->getShape2();
432 auto& shapeLocalToWorldTransform1 = shape1->getLocalToWorldTransform();
433 auto& shapeLocalToWorldTransform2 = shape2->getLocalToWorldTransform();
434 auto& localPoint1 = contactPoint->getLocalPointOnShape1();
435 auto& localPoint2 = contactPoint->getLocalPointOnShape2();
436 auto worldPoint1 = shapeLocalToWorldTransform1 * localPoint1;
437 auto worldPoint2 = shapeLocalToWorldTransform2 * localPoint2;
438 entity->addHitPoint(Vector3(worldPoint1.x, worldPoint1.y, worldPoint1.z));
439 entity->addHitPoint(Vector3(worldPoint2.x, worldPoint2.y, worldPoint2.z));
440 contactPoint = contactPoint->getNext();
441 }
442 manifold = collisionCallbackInfo.contactManifoldElements->getNext();
443 }
444 }
445
446 private:
447 CollisionResponse& collision;
448 };
449 // do the test
450 CustomCollisionCallback customCollisionCallback(collision);
451 world.testCollision(body1->collisionBody, body2->collisionBody, &customCollisionCallback);
452 return collision.getEntityCount() > 0;
453}
454
455World* World::clone(uint16_t collisionTypeIds)
456{
457 auto clonedWorld = new World();
458 for (auto i = 0; i < bodies.size(); i++) {
459 auto body = bodies[i];
460 // clone obv
461 Body* clonedBody = nullptr;
462 auto bodyType = body->getType();
463
464 // test type
465 if (((body->getCollisionTypeId() & collisionTypeIds) == body->getCollisionTypeId()) == false) continue;
466
467 // clone rigid body
468 switch(bodyType) {
470 clonedBody = clonedWorld->addStaticRigidBody(body->id, body->isEnabled(), body->getCollisionTypeId(), body->transformations, body->getFriction(), body->boundingVolumes);
471 break;
473 clonedBody = clonedWorld->addRigidBody(body->id, body->isEnabled(), body->getCollisionTypeId(), body->transformations, body->getRestitution(), body->getFriction(), body->getMass(), body->inertiaTensor, body->boundingVolumes);
474 break;
476 clonedBody = clonedWorld->addCollisionBody(body->id, body->isEnabled(), body->getCollisionTypeId(), body->transformations, body->boundingVolumes);
477 break;
478 default:
479 Console::println("World::clone(): Unsupported type: " + to_string(bodyType));
480 continue;
481 }
482
483 // set cloned
484 clonedBody->setCloned(true);
485
486 // synch additional properties
487 synch(clonedBody, clonedBody);
488 }
489 return clonedWorld;
490}
491
492void World::synch(Body* clonedBody, Body* body)
493{
494 clonedBody->setCollisionTypeIds(body->getCollisionTypeIds());
495 clonedBody->setEnabled(body->isEnabled());
496 clonedBody->setMass(body->getMass());
497 clonedBody->fromTransformations(body->transformations);
498 if (clonedBody->getType() == Body::TYPE_DYNAMIC) {
499 clonedBody->setLinearVelocity(body->getLinearVelocity());
500 clonedBody->setAngularVelocity(body->getAngularVelocity());
501 }
502}
503
504void World::synch(World* world)
505{
506 for (auto i = 0; i < rigidBodiesDynamic.size(); i++) {
507 auto body = rigidBodiesDynamic.at(i);
508 auto clonedBody = world->getBody(body->id);
509 if (clonedBody == nullptr) {
510 Console::println(
511 string("Cloned world::entity '") +
512 body->id +
513 string("' not found")
514 );
515 continue;
516 }
517 // synch rigid bodies
518 synch(clonedBody, body);
519 }
520}
521
523{
524 worldListeners.push_back(listener);
525}
526
528{
529 worldListeners.erase(remove(worldListeners.begin(), worldListeners.end(), listener), worldListeners.end());
530 delete listener;
531}
Engine main class.
Definition: Engine.h:122
Entity * getEntity(const string &id)
Returns a entity by given id.
Definition: Engine.h:981
TDME engine entity.
Definition: Entity.h:31
Rotation representation.
Definition: Rotation.h:18
Transformations which contain scale, rotations and translation.
Dynamic rigid/static rigid/collision body class.
Definition: Body.h:43
uint16_t getCollisionTypeIds()
Definition: Body.cpp:187
void setCloned(bool cloned)
Set cloned.
Definition: Body.cpp:152
void setMass(float mass)
Set up mass.
Definition: Body.cpp:369
void setAngularVelocity(const Vector3 &angularVelocity)
Set angular velocity.
Definition: Body.cpp:413
Transformations transformations
Definition: Body.h:73
void setEnabled(bool enabled)
Set up if rigid body is enabled.
Definition: Body.cpp:205
void setLinearVelocity(const Vector3 &linearVelocity)
Set linear velocity.
Definition: Body.cpp:392
reactphysics3d::CollisionBody * collisionBody
Definition: Body.h:64
static constexpr int32_t TYPE_DYNAMIC
Definition: Body.h:48
int getType()
Return type, see TYPE_*.
Definition: Body.cpp:170
const Vector3 getAngularVelocity()
Definition: Body.cpp:400
static const Vector3 getNoRotationInertiaTensor()
Definition: Body.cpp:118
void setCollisionTypeIds(uint16_t collisionTypeIds)
Set up collision type ids.
Definition: Body.cpp:192
void fromTransformations(const Transformations &transformations)
Synchronizes this rigid body with transformations.
Definition: Body.cpp:461
static constexpr int32_t TYPE_STATIC
Definition: Body.h:47
const Vector3 getLinearVelocity()
Definition: Body.cpp:379
static constexpr int32_t TYPE_COLLISION
Definition: Body.h:50
CollisionResponse_Entity * addResponse(float distance)
Adds a collision response entity.
Dynamic physics world class.
Definition: World.h:38
Body * addRigidBody(const string &id, bool enabled, uint16_t collisionTypeId, const Transformations &transformations, float restitution, float friction, float mass, const Vector3 &inertiaTensor, vector< BoundingVolume * > boundingVolumes)
Add a rigid body.
Definition: World.cpp:86
Body * addStaticRigidBody(const string &id, bool enabled, uint16_t collisionTypeId, const Transformations &transformations, float friction, vector< BoundingVolume * > boundingVolumes)
Add a static rigid body.
Definition: World.cpp:110
Body * getBody(const string &id)
Returns body identified by id.
Definition: World.cpp:122
Body * doRayCasting(uint16_t collisionTypeIds, const Vector3 &start, const Vector3 &end, Vector3 &hitPoint, const string &actorId=string())
Do a ray cast from given start to given end point, if there is any body with given collision type in ...
Definition: World.cpp:341
Body * determineHeight(uint16_t collisionTypeId, float stepUpMax, const Vector3 &point, Vector3 &dest, float minHeight=-10000.0f, float maxHeight=10000.0f)
Determine height on x,y,u while respecting step up max.
Definition: World.cpp:300
bool doCollide(Body *body1, Body *body2)
Check if body 1 collides with body 2.
Definition: World.cpp:410
void removeBody(const string &id)
Removes body identified by id.
Definition: World.cpp:131
map< string, Body * > bodiesById
Definition: World.h:51
bool getCollisionResponse(Body *body1, Body *body2, CollisionResponse &collision)
Get collision response.
Definition: World.cpp:414
reactphysics3d::DynamicsWorld world
Definition: World.h:47
World()
Public constructor.
Definition: World.cpp:66
bool doesCollideWith(uint16_t collisionTypeIds, Body *body, vector< Body * > &rigidBodies)
Check if world collides with given body.
Definition: World.cpp:381
void addWorldListener(WorldListener *listener)
Add a world listener.
Definition: World.cpp:522
map< string, BodyCollisionStruct > bodyCollisionsLastFrame
Definition: World.h:52
void synch(Body *clonedBody, Body *body)
Synch into cloned body from body.
Definition: World.cpp:492
vector< Body * > rigidBodiesDynamic
Definition: World.h:50
World * clone(uint16_t collisionTypeIds=~0)
Clone this world.
Definition: World.cpp:455
Body * addCollisionBody(const string &id, bool enabled, uint16_t collisionTypeId, const Transformations &transformations, vector< BoundingVolume * > boundingVolumes)
Add a collision body.
Definition: World.cpp:99
vector< WorldListener * > worldListeners
Definition: World.h:53
void removeWorldListener(WorldListener *listener)
Remove a world listener.
Definition: World.cpp:527
void update(float deltaTime)
Update world.
Definition: World.cpp:150
void reset()
Resets the physic world.
Definition: World.cpp:76
vector< Body * > bodies
Definition: World.h:49
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Definition: BoundingBox.h:25
Line segment helper functions.
Definition: LineSegment.h:17
Oriented bounding box physics primitive.
Standard math functions.
Definition: Math.h:21
4x4 3D Matrix class
Definition: Matrix4x4.h:24
Quaternion class.
Definition: Quaternion.h:22
3D vector 3 class
Definition: Vector3.h:22
float getY() const
Definition: Vector3.h:119
float getX() const
Definition: Vector3.h:103
float getZ() const
Definition: Vector3.h:136
Vector3 & set(float x, float y, float z)
Set up vector.
Definition: Vector3.h:73
Vector3 & setY(float y)
Set Y.
Definition: Vector3.h:128
Console class.
Definition: Console.h:26
Vector iterator template to be used to iterate multiple vectors at a single invocation.
World listener which is about notifying adding or removing bodies.
Definition: WorldListener.h:22