Merge branch 'dynamicscollision' into develop

This commit is contained in:
Daniel Chappuis 2012-10-03 22:40:24 +02:00
commit f47298d7eb
38 changed files with 1099 additions and 710 deletions

View File

@ -31,25 +31,11 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
Body::Body(const Transform& transform, CollisionShape *collisionShape, decimal mass, bodyindex id) Body::Body(bodyindex id) : id(id) {
: collisionShape(collisionShape), mass(mass), transform(transform), isActive(true), id(id), hasMoved(false) {
assert(mass > 0.0);
assert(collisionShape);
isMotionEnabled = true;
isCollisionEnabled = true;
interpolationFactor = 0.0;
// Initialize the old transform
oldTransform = transform;
// Create the AABB for broad-phase collision detection
aabb = new AABB(transform, collisionShape->getLocalExtents(OBJECT_MARGIN));
} }
// Destructor // Destructor
Body::~Body() { Body::~Body() {
// Delete the AABB
delete aabb;
} }

View File

@ -29,9 +29,6 @@
// Libraries // Libraries
#include <stdexcept> #include <stdexcept>
#include <cassert> #include <cassert>
#include "../mathematics/Transform.h"
#include "../collision/shapes/AABB.h"
#include "../collision/shapes/CollisionShape.h"
#include "../configuration.h" #include "../configuration.h"
// Namespace reactphysics3d // Namespace reactphysics3d
@ -45,49 +42,21 @@ namespace reactphysics3d {
------------------------------------------------------------------- -------------------------------------------------------------------
*/ */
class Body { class Body {
protected : protected :
CollisionShape* collisionShape; // Collision shape of the body
decimal mass; // Mass of the body
Transform transform; // Position and orientation of the body
Transform oldTransform; // Last position and orientation of the body
decimal interpolationFactor; // Interpolation factor used for the state interpolation
bool isActive; // True if the body is active (not sleeping because of deactivation)
bool isMotionEnabled; // True if the body is able to move
bool isCollisionEnabled; // True if the body can collide with others bodies
AABB* aabb; // Axis-Aligned Bounding Box for Broad-Phase collision detection
bodyindex id; // ID of the body bodyindex id; // ID of the body
bool hasMoved; // True if the body has moved during the last frame
public : public :
Body(const Transform& transform, CollisionShape* collisionShape, decimal mass, bodyindex id); // Constructor Body(bodyindex id); // Constructor
virtual ~Body(); // Destructor virtual ~Body(); // Destructor
bodyindex getID() const; // Return the id of the body bodyindex getID() const; // Return the id of the body
bool getHasMoved() const; // Return true if the body has moved during the last frame
void setHasMoved(bool hasMoved); // Set the hasMoved variable (true if the body has moved during the last frame)
CollisionShape* getCollisionShape() const; // Return the collision shape
void setCollisionShape(CollisionShape* collisionShape); // Set the collision shape
decimal getMass() const; // Return the mass of the body
void setMass(decimal mass); // Set the mass of the body
bool getIsActive() const; // Return true if the body is active
void setIsActive(bool isActive); // Set the isActive variable
const Transform& getTransform() const; // Return the current position and orientation
void setTransform(const Transform& transform); // Set the current position and orientation
const AABB* getAABB() const; // Return the AAABB of the body
Transform getInterpolatedTransform() const; // Return the interpolated transform for rendering
void setInterpolationFactor(decimal factor); // Set the interpolation factor of the body
bool getIsMotionEnabled() const; // Return if the rigid body can move
void setIsMotionEnabled(bool isMotionEnabled); // Set the value to true if the body can move
bool getIsCollisionEnabled() const; // Return true if the body can collide with others bodies
void setIsCollisionEnabled(bool isCollisionEnabled); // Set the isCollisionEnabled value
void updateOldTransform(); // Update the old transform with the current one
void updateAABB(); // Update the Axis-Aligned Bounding Box coordinates
// Operators // Operators
bool operator<(const Body& body2) const; // Smaller than operator bool operator<(const Body& body2) const; // Smaller than operator
bool operator>(const Body& body2) const; // Larger than operator bool operator>(const Body& body2) const; // Larger than operator
bool operator==(const Body& body2) const; // Equal operator bool operator==(const Body& body2) const; // Equal operator
bool operator!=(const Body& body2) const; // Equal operator bool operator!=(const Body& body2) const; // Not equal operator
}; };
// Return the id of the body // Return the id of the body
@ -95,115 +64,6 @@ inline bodyindex Body::getID() const {
return id; return id;
} }
// Return true if the body has moved during the last frame
inline bool Body::getHasMoved() const {
return hasMoved;
}
// Set the hasMoved variable (true if the body has moved during the last frame)
inline void Body::setHasMoved(bool hasMoved) {
this->hasMoved = hasMoved;
}
// Return the collision shape
inline CollisionShape *Body::getCollisionShape() const {
assert(collisionShape);
return collisionShape;
}
// Set the collision shape
inline void Body::setCollisionShape(CollisionShape *collisionShape) {
assert(collisionShape);
this->collisionShape = collisionShape;
}
// Method that return the mass of the body
inline decimal Body::getMass() const {
return mass;
};
// Method that set the mass of the body
inline void Body::setMass(decimal mass) {
this->mass = mass;
}
// Return true if the body is active
inline bool Body::getIsActive() const {
return isActive;
}
// Set the isActive variable
inline void Body::setIsActive(bool isActive) {
this->isActive = isActive;
}
// Return the interpolated transform for rendering
inline Transform Body::getInterpolatedTransform() const {
return Transform::interpolateTransforms(oldTransform, transform, interpolationFactor);
}
// Set the interpolation factor of the body
inline void Body::setInterpolationFactor(decimal factor) {
// Set the factor
interpolationFactor = factor;
}
// Return if the rigid body can move
inline bool Body::getIsMotionEnabled() const {
return isMotionEnabled;
}
// Set the value to true if the body can move
inline void Body::setIsMotionEnabled(bool isMotionEnabled) {
this->isMotionEnabled = isMotionEnabled;
}
// Return the current position and orientation
inline const Transform& Body::getTransform() const {
return transform;
}
// Set the current position and orientation
inline void Body::setTransform(const Transform& transform) {
// Check if the body has moved
if (this->transform != transform) {
hasMoved = true;
}
this->transform = transform;
}
// Return the AAABB of the body
inline const AABB* Body::getAABB() const {
return aabb;
}
// Return true if the body can collide with others bodies
inline bool Body::getIsCollisionEnabled() const {
return isCollisionEnabled;
}
// Set the isCollisionEnabled value
inline void Body::setIsCollisionEnabled(bool isCollisionEnabled) {
this->isCollisionEnabled = isCollisionEnabled;
}
// Update the old transform with the current one
// This is used to compute the interpolated position and orientation of the body
inline void Body::updateOldTransform() {
oldTransform = transform;
}
// Update the rigid body in order to reflect a change in the body state
inline void Body::updateAABB() {
// TODO : An AABB should not be updated every frame but only if the body has moved
// Update the AABB
aabb->update(transform, collisionShape->getLocalExtents(OBJECT_MARGIN));
}
// Smaller than operator // Smaller than operator
inline bool Body::operator<(const Body& body2) const { inline bool Body::operator<(const Body& body2) const {
return (id < body2.id); return (id < body2.id);
@ -219,7 +79,7 @@ inline bool Body::operator==(const Body& body2) const {
return (id == body2.id); return (id == body2.id);
} }
// Equal operator // Not equal operator
inline bool Body::operator!=(const Body& body2) const { inline bool Body::operator!=(const Body& body2) const {
return (id != body2.id); return (id != body2.id);
} }

View File

@ -0,0 +1,55 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010-2012 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "CollisionBody.h"
// We want to use the ReactPhysics3D namespace
using namespace reactphysics3d;
// Constructor
CollisionBody::CollisionBody(const Transform& transform, CollisionShape *collisionShape, bodyindex id)
: Body(id), collisionShape(collisionShape), transform(transform), isActive(true), hasMoved(false) {
assert(collisionShape);
isMotionEnabled = true;
isCollisionEnabled = true;
interpolationFactor = 0.0;
// Initialize the old transform
oldTransform = transform;
// Create the AABB for broad-phase collision detection
aabb = new AABB(transform, collisionShape->getLocalExtents(OBJECT_MARGIN));
}
// Destructor
CollisionBody::~CollisionBody() {
// Delete the AABB
delete aabb;
}

185
src/body/CollisionBody.h Normal file
View File

@ -0,0 +1,185 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010-2012 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef COLLISION_BODY_H
#define COLLISION_BODY_H
// Libraries
#include <stdexcept>
#include <cassert>
#include "Body.h"
#include "../mathematics/Transform.h"
#include "../collision/shapes/AABB.h"
#include "../collision/shapes/CollisionShape.h"
#include "../configuration.h"
// Namespace reactphysics3d
namespace reactphysics3d {
/* -------------------------------------------------------------------
Class CollisionBody :
This class represents a body that is able to collide with others
bodies. This class inherits from the Body class.
-------------------------------------------------------------------
*/
class CollisionBody : public Body {
protected :
CollisionShape* collisionShape; // Collision shape of the body
Transform transform; // Position and orientation of the body
Transform oldTransform; // Last position and orientation of the body
decimal interpolationFactor; // Interpolation factor used for the state interpolation
bool isActive; // True if the body is active (not sleeping because of deactivation)
bool isMotionEnabled; // True if the body is able to move
bool isCollisionEnabled; // True if the body can collide with others bodies
AABB* aabb; // Axis-Aligned Bounding Box for Broad-Phase collision detection
bool hasMoved; // True if the body has moved during the last frame
public :
CollisionBody(const Transform& transform, CollisionShape* collisionShape, bodyindex id); // Constructor
virtual ~CollisionBody(); // Destructor
bool getHasMoved() const; // Return true if the body has moved during the last frame
void setHasMoved(bool hasMoved); // Set the hasMoved variable (true if the body has moved during the last frame)
CollisionShape* getCollisionShape() const; // Return the collision shape
void setCollisionShape(CollisionShape* collisionShape); // Set the collision shape
bool getIsActive() const; // Return true if the body is active
void setIsActive(bool isActive); // Set the isActive variable
const Transform& getTransform() const; // Return the current position and orientation
void setTransform(const Transform& transform); // Set the current position and orientation
const AABB* getAABB() const; // Return the AAABB of the body
Transform getInterpolatedTransform() const; // Return the interpolated transform for rendering
void setInterpolationFactor(decimal factor); // Set the interpolation factor of the body
bool getIsMotionEnabled() const; // Return if the rigid body can move
void setIsMotionEnabled(bool isMotionEnabled); // Set the value to true if the body can move
bool getIsCollisionEnabled() const; // Return true if the body can collide with others bodies
void setIsCollisionEnabled(bool isCollisionEnabled); // Set the isCollisionEnabled value
void updateOldTransform(); // Update the old transform with the current one
void updateAABB(); // Update the Axis-Aligned Bounding Box coordinates
};
// Return true if the body has moved during the last frame
inline bool CollisionBody::getHasMoved() const {
return hasMoved;
}
// Set the hasMoved variable (true if the body has moved during the last frame)
inline void CollisionBody::setHasMoved(bool hasMoved) {
this->hasMoved = hasMoved;
}
// Return the collision shape
inline CollisionShape* CollisionBody::getCollisionShape() const {
assert(collisionShape);
return collisionShape;
}
// Set the collision shape
inline void CollisionBody::setCollisionShape(CollisionShape* collisionShape) {
assert(collisionShape);
this->collisionShape = collisionShape;
}
// Return true if the body is active
inline bool CollisionBody::getIsActive() const {
return isActive;
}
// Set the isActive variable
inline void CollisionBody::setIsActive(bool isActive) {
this->isActive = isActive;
}
// Return the interpolated transform for rendering
inline Transform CollisionBody::getInterpolatedTransform() const {
return Transform::interpolateTransforms(oldTransform, transform, interpolationFactor);
}
// Set the interpolation factor of the body
inline void CollisionBody::setInterpolationFactor(decimal factor) {
// Set the factor
interpolationFactor = factor;
}
// Return if the rigid body can move
inline bool CollisionBody::getIsMotionEnabled() const {
return isMotionEnabled;
}
// Set the value to true if the body can move
inline void CollisionBody::setIsMotionEnabled(bool isMotionEnabled) {
this->isMotionEnabled = isMotionEnabled;
}
// Return the current position and orientation
inline const Transform& CollisionBody::getTransform() const {
return transform;
}
// Set the current position and orientation
inline void CollisionBody::setTransform(const Transform& transform) {
// Check if the body has moved
if (this->transform != transform) {
hasMoved = true;
}
this->transform = transform;
}
// Return the AAABB of the body
inline const AABB* CollisionBody::getAABB() const {
return aabb;
}
// Return true if the body can collide with others bodies
inline bool CollisionBody::getIsCollisionEnabled() const {
return isCollisionEnabled;
}
// Set the isCollisionEnabled value
inline void CollisionBody::setIsCollisionEnabled(bool isCollisionEnabled) {
this->isCollisionEnabled = isCollisionEnabled;
}
// Update the old transform with the current one
// This is used to compute the interpolated position and orientation of the body
inline void CollisionBody::updateOldTransform() {
oldTransform = transform;
}
// Update the rigid body in order to reflect a change in the body state
inline void CollisionBody::updateAABB() {
// TODO : An AABB should not be updated every frame but only if the body has moved
// Update the AABB
aabb->update(transform, collisionShape->getLocalExtents(OBJECT_MARGIN));
}
}
#endif

View File

@ -32,8 +32,8 @@ using namespace reactphysics3d;
// Constructor // Constructor
RigidBody::RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal, CollisionShape *collisionShape, bodyindex id) RigidBody::RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal, CollisionShape *collisionShape, bodyindex id)
: Body(transform, collisionShape, mass, id), inertiaTensorLocal(inertiaTensorLocal), : CollisionBody(transform, collisionShape, id), inertiaTensorLocal(inertiaTensorLocal),
inertiaTensorLocalInverse(inertiaTensorLocal.getInverse()), massInverse(1.0/mass) { mass(mass), inertiaTensorLocalInverse(inertiaTensorLocal.getInverse()), massInverse(1.0/mass) {
restitution = 1.0; restitution = 1.0;

View File

@ -28,8 +28,7 @@
// Libraries // Libraries
#include <cassert> #include <cassert>
#include "Body.h" #include "CollisionBody.h"
#include "../collision/shapes/CollisionShape.h"
#include "../mathematics/mathematics.h" #include "../mathematics/mathematics.h"
// Namespace reactphysics3d // Namespace reactphysics3d
@ -39,11 +38,16 @@ namespace reactphysics3d {
Class RigidBody : Class RigidBody :
This class represents a rigid body of the physics This class represents a rigid body of the physics
engine. A rigid body is a non-deformable body that engine. A rigid body is a non-deformable body that
has a constant mass. has a constant mass. This class inherits from the
CollisionBody class.
------------------------------------------------------------------- -------------------------------------------------------------------
*/ */
class RigidBody : public Body { class RigidBody : public CollisionBody {
protected : protected :
// TODO : Remove the mass variable (duplicate with inverseMass)
decimal mass; // Mass of the body
Vector3 linearVelocity; // Linear velocity of the body Vector3 linearVelocity; // Linear velocity of the body
Vector3 angularVelocity; // Angular velocity of the body Vector3 angularVelocity; // Angular velocity of the body
Vector3 externalForce; // Current external force on the body Vector3 externalForce; // Current external force on the body
@ -58,6 +62,8 @@ class RigidBody : public Body {
CollisionShape* collisionShape, bodyindex id); // Constructor // Copy-constructor CollisionShape* collisionShape, bodyindex id); // Constructor // Copy-constructor
virtual ~RigidBody(); // Destructor virtual ~RigidBody(); // Destructor
decimal getMass() const; // Return the mass of the body
void setMass(decimal mass); // Set the mass of the body
Vector3 getLinearVelocity() const; // Return the linear velocity Vector3 getLinearVelocity() const; // Return the linear velocity
void setLinearVelocity(const Vector3& linearVelocity); // Set the linear velocity of the body void setLinearVelocity(const Vector3& linearVelocity); // Set the linear velocity of the body
Vector3 getAngularVelocity() const; // Return the angular velocity Vector3 getAngularVelocity() const; // Return the angular velocity
@ -78,6 +84,16 @@ class RigidBody : public Body {
void setRestitution(decimal restitution) throw(std::invalid_argument); // Set the restitution coefficient void setRestitution(decimal restitution) throw(std::invalid_argument); // Set the restitution coefficient
}; };
// Method that return the mass of the body
inline decimal RigidBody::getMass() const {
return mass;
};
// Method that set the mass of the body
inline void RigidBody::setMass(decimal mass) {
this->mass = mass;
}
// Return the linear velocity // Return the linear velocity
inline Vector3 RigidBody::getLinearVelocity() const { inline Vector3 RigidBody::getLinearVelocity() const {
return linearVelocity; return linearVelocity;

View File

@ -0,0 +1,40 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010-2012 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "BroadPhasePair.h"
using namespace reactphysics3d;
// Constructor
BroadPhasePair::BroadPhasePair(CollisionBody* body1, CollisionBody* body2)
: body1(body1), body2(body2), previousSeparatingAxis(Vector3(1,1,1)) {
}
// Destructor
BroadPhasePair::~BroadPhasePair() {
}

View File

@ -0,0 +1,89 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010-2012 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef BROAD_PHASE_PAIR_H
#define BROAD_PHASE_PAIR_H
// Libraries
#include "../body/CollisionBody.h"
// ReactPhysics3D namespace
namespace reactphysics3d {
// struct BroadPhasePair
// This structure represents a pair of bodies
// during the broad-phase collision detection
struct BroadPhasePair {
public:
CollisionBody* body1; // Pointer to the first body
CollisionBody* body2; // Pointer to the second body
Vector3 previousSeparatingAxis; // Previous cached separating axis
BroadPhasePair(CollisionBody* body1, CollisionBody* body2); // Constructor
~BroadPhasePair(); // Destructor
bodyindexpair getBodiesIndexPair() const; // Return the pair of bodies index
// Operators
bool operator<(const BroadPhasePair& broadPhasePair2) const; // Smaller than operator
bool operator>(const BroadPhasePair& broadPhasePair2) const; // Larger than operator
bool operator==(const BroadPhasePair& broadPhasePair2) const; // Equal operator
bool operator!=(const BroadPhasePair& broadPhasePair2) const; // Not equal operator
};
// Return the pair of bodies index
inline bodyindexpair BroadPhasePair::getBodiesIndexPair() const {
// Construct the pair of body index
bodyindexpair indexPair = body1->getID() < body2->getID() ? std::make_pair(body1->getID(), body2->getID()) :
std::make_pair(body2->getID(), body1->getID());
assert(indexPair.first != indexPair.second);
return indexPair;
}
// Smaller than operator
inline bool BroadPhasePair::operator<(const BroadPhasePair& broadPhasePair2) const {
return (body1 < broadPhasePair2.body1 ? true : (body2 < broadPhasePair2.body2));
}
// Larger than operator
inline bool BroadPhasePair::operator>(const BroadPhasePair& broadPhasePair2) const {
return (body1 > broadPhasePair2.body1 ? true : (body2 > broadPhasePair2.body2));
}
// Equal operator
inline bool BroadPhasePair::operator==(const BroadPhasePair& broadPhasePair2) const {
return (body1 == broadPhasePair2.body1 && body2 == broadPhasePair2.body2);
}
// Not equal operator
inline bool BroadPhasePair::operator!=(const BroadPhasePair& broadPhasePair2) const {
return (body1 != broadPhasePair2.body1 || body2 != broadPhasePair2.body2);
}
}
#endif

View File

@ -25,7 +25,7 @@
// Libraries // Libraries
#include "CollisionDetection.h" #include "CollisionDetection.h"
#include "../engine/PhysicsWorld.h" #include "../engine/CollisionWorld.h"
#include "broadphase/SweepAndPruneAlgorithm.h" #include "broadphase/SweepAndPruneAlgorithm.h"
#include "broadphase/NoBroadPhaseAlgorithm.h" #include "broadphase/NoBroadPhaseAlgorithm.h"
#include "../body/Body.h" #include "../body/Body.h"
@ -45,7 +45,7 @@ using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
CollisionDetection::CollisionDetection(PhysicsWorld* world) CollisionDetection::CollisionDetection(CollisionWorld* world)
: world(world), narrowPhaseGJKAlgorithm(memoryPoolContactInfos), : world(world), narrowPhaseGJKAlgorithm(memoryPoolContactInfos),
narrowPhaseSphereVsSphereAlgorithm(memoryPoolContactInfos) { narrowPhaseSphereVsSphereAlgorithm(memoryPoolContactInfos) {
@ -56,12 +56,6 @@ CollisionDetection::CollisionDetection(PhysicsWorld* world)
// Destructor // Destructor
CollisionDetection::~CollisionDetection() { CollisionDetection::~CollisionDetection() {
// Delete the remaining overlapping pairs
for (map<std::pair<bodyindex, bodyindex>, OverlappingPair*>::iterator it=overlappingPairs.begin(); it != overlappingPairs.end(); it++) {
// Delete the overlapping pair
(*it).second->OverlappingPair::~OverlappingPair();
memoryPoolOverlappingPairs.freeObject((*it).second);
}
// Delete the broad-phase algorithm // Delete the broad-phase algorithm
delete broadPhaseAlgorithm; delete broadPhaseAlgorithm;
@ -69,9 +63,7 @@ CollisionDetection::~CollisionDetection() {
// Compute the collision detection // Compute the collision detection
bool CollisionDetection::computeCollisionDetection() { bool CollisionDetection::computeCollisionDetection() {
world->removeAllContactConstraints();
// TODO : Remove this code // TODO : Remove this code
timeval timeValueStart; timeval timeValueStart;
timeval timeValueStop; timeval timeValueStop;
@ -98,7 +90,7 @@ bool CollisionDetection::computeCollisionDetection() {
void CollisionDetection::computeBroadPhase() { void CollisionDetection::computeBroadPhase() {
// Notify the broad-phase algorithm about the bodies that have moved since last frame // Notify the broad-phase algorithm about the bodies that have moved since last frame
for (set<Body*>::iterator it = world->getBodiesBeginIterator(); it != world->getBodiesEndIterator(); it++) { for (set<CollisionBody*>::iterator it = world->getBodiesBeginIterator(); it != world->getBodiesEndIterator(); it++) {
// If the body has moved // If the body has moved
if ((*it)->getHasMoved()) { if ((*it)->getHasMoved()) {
@ -107,32 +99,31 @@ void CollisionDetection::computeBroadPhase() {
broadPhaseAlgorithm->updateObject(*it, *((*it)->getAABB())); broadPhaseAlgorithm->updateObject(*it, *((*it)->getAABB()));
} }
} }
// TODO : DELETE THIS
//std::cout << "Nb overlapping pairs : " << overlappingPairs.size() << std::endl;
//std::cout << "Nb active pairs in pair manager : " << broadPhaseAlgorithm->getNbOverlappingPairs() << std::endl;
} }
// Compute the narrow-phase collision detection // Compute the narrow-phase collision detection
bool CollisionDetection::computeNarrowPhase() { bool CollisionDetection::computeNarrowPhase() {
bool collisionExists = false; bool collisionExists = false;
map<std::pair<bodyindex, bodyindex>, OverlappingPair*>::iterator it; map<bodyindexpair, BroadPhasePair*>::iterator it;
// For each possible collision pair of bodies // For each possible collision pair of bodies
for (it = overlappingPairs.begin(); it != overlappingPairs.end(); it++) { for (it = overlappingPairs.begin(); it != overlappingPairs.end(); it++) {
ContactInfo* contactInfo = NULL; ContactInfo* contactInfo = 0;
Body* const body1 = (*it).second->getBody1(); BroadPhasePair* pair = (*it).second;
Body* const body2 = (*it).second->getBody2(); assert(pair);
CollisionBody* const body1 = pair->body1;
CollisionBody* const body2 = pair->body2;
// Update the contact cache of the overlapping pair // Update the contact cache of the overlapping pair
(*it).second->update(); world->updateOverlappingPair(pair);
// Select the narrow phase algorithm to use according to the two collision shapes // Select the narrow phase algorithm to use according to the two collision shapes
NarrowPhaseAlgorithm& narrowPhaseAlgorithm = SelectNarrowPhaseAlgorithm(body1->getCollisionShape(), body2->getCollisionShape()); NarrowPhaseAlgorithm& narrowPhaseAlgorithm = SelectNarrowPhaseAlgorithm(body1->getCollisionShape(), body2->getCollisionShape());
// Notify the narrow-phase algorithm about the overlapping pair we are going to test // Notify the narrow-phase algorithm about the overlapping pair we are going to test
narrowPhaseAlgorithm.setCurrentOverlappingPair((*it).second); narrowPhaseAlgorithm.setCurrentOverlappingPair(pair);
// Use the narrow-phase collision detection algorithm to check if there really is a collision // Use the narrow-phase collision detection algorithm to check if there really is a collision
if (narrowPhaseAlgorithm.testCollision(body1->getCollisionShape(), body1->getTransform(), if (narrowPhaseAlgorithm.testCollision(body1->getCollisionShape(), body1->getTransform(),
@ -140,21 +131,12 @@ bool CollisionDetection::computeNarrowPhase() {
assert(contactInfo); assert(contactInfo);
collisionExists = true; collisionExists = true;
// Create a new contact // Notify the world about the new narrow-phase contact
Contact* contact = new (memoryPoolContacts.allocateObject()) Contact(body1, body2, contactInfo); world->notifyNewContact(pair, contactInfo);
// Delete and remove the contact info from the memory pool // Delete and remove the contact info from the memory pool
contactInfo->ContactInfo::~ContactInfo(); contactInfo->ContactInfo::~ContactInfo();
memoryPoolContactInfos.freeObject(contactInfo); memoryPoolContactInfos.freeObject(contactInfo);
// Add the contact to the contact cache of the corresponding overlapping pair
(*it).second->addContact(contact);
// Add all the contacts in the contact cache of the two bodies
// to the set of constraints in the physics world
for (uint i=0; i<(*it).second->getNbContacts(); i++) {
world->addConstraint((*it).second->getContact(i));
}
} }
} }
@ -163,34 +145,37 @@ bool CollisionDetection::computeNarrowPhase() {
// Allow the broadphase to notify the collision detection about an overlapping pair // Allow the broadphase to notify the collision detection about an overlapping pair
// This method is called by a broad-phase collision detection algorithm // This method is called by a broad-phase collision detection algorithm
void CollisionDetection::broadPhaseNotifyAddedOverlappingPair(const BroadPhasePair* addedPair) { void CollisionDetection::broadPhaseNotifyAddedOverlappingPair(BodyPair* addedPair) {
// Construct the pair of body index // Get the pair of body index
pair<bodyindex, bodyindex> indexPair = addedPair->body1->getID() < addedPair->body2->getID() ? make_pair(addedPair->body1->getID(), addedPair->body2->getID()) : bodyindexpair indexPair = addedPair->getBodiesIndexPair();
make_pair(addedPair->body2->getID(), addedPair->body1->getID());
assert(indexPair.first != indexPair.second); // Create the corresponding broad-phase pair object
BroadPhasePair* broadPhasePair = new (memoryPoolOverlappingPairs.allocateObject()) BroadPhasePair(addedPair->body1, addedPair->body2);
// Add the pair into the set of overlapping pairs (if not there yet) // Add the pair into the set of overlapping pairs (if not there yet)
OverlappingPair* newPair = new (memoryPoolOverlappingPairs.allocateObject()) OverlappingPair(addedPair->body1, addedPair->body2, memoryPoolContacts); pair<map<bodyindexpair, BroadPhasePair*>::iterator, bool> check = overlappingPairs.insert(make_pair(indexPair, broadPhasePair));
pair<map<pair<bodyindex, bodyindex>, OverlappingPair*>::iterator, bool> check = overlappingPairs.insert(make_pair(indexPair, newPair)); assert(check.second);
// If the overlapping pair was already in the set of overlapping pair // Notify the world about the new broad-phase overlapping pair
if (!check.second) { world->notifyAddedOverlappingPair(broadPhasePair);
// Delete the new pair
newPair->OverlappingPair::~OverlappingPair();
memoryPoolOverlappingPairs.freeObject(newPair);
}
} }
// Allow the broadphase to notify the collision detection about a removed overlapping pair // Allow the broadphase to notify the collision detection about a removed overlapping pair
void CollisionDetection::broadPhaseNotifyRemovedOverlappingPair(const BroadPhasePair* removedPair) { void CollisionDetection::broadPhaseNotifyRemovedOverlappingPair(BodyPair* removedPair) {
// Construct the pair of body index // Get the pair of body index
pair<bodyindex, bodyindex> indexPair = removedPair->body1->getID() < removedPair->body2->getID() ? make_pair(removedPair->body1->getID(), removedPair->body2->getID()) : bodyindexpair indexPair = removedPair->getBodiesIndexPair();
make_pair(removedPair->body2->getID(), removedPair->body1->getID());
// Get the broad-phase pair
BroadPhasePair* broadPhasePair = overlappingPairs[indexPair];
assert(broadPhasePair);
// Notify the world about the removed broad-phase pair
world->notifyRemovedOverlappingPair(broadPhasePair);
// Remove the overlapping pair from the memory pool // Remove the overlapping pair from the memory pool
overlappingPairs[indexPair]->OverlappingPair::~OverlappingPair(); broadPhasePair->BroadPhasePair::~BroadPhasePair();
memoryPoolOverlappingPairs.freeObject(overlappingPairs[indexPair]); memoryPoolOverlappingPairs.freeObject(broadPhasePair);
overlappingPairs.erase(indexPair); overlappingPairs.erase(indexPair);
} }

View File

@ -27,9 +27,9 @@
#define COLLISION_DETECTION_H #define COLLISION_DETECTION_H
// Libraries // Libraries
#include "../body/Body.h" #include "../body/CollisionBody.h"
#include "OverlappingPair.h"
#include "broadphase/BroadPhaseAlgorithm.h" #include "broadphase/BroadPhaseAlgorithm.h"
#include "BroadPhasePair.h"
#include "../memory/MemoryPool.h" #include "../memory/MemoryPool.h"
#include "narrowphase/GJK/GJKAlgorithm.h" #include "narrowphase/GJK/GJKAlgorithm.h"
#include "narrowphase/SphereVsSphereAlgorithm.h" #include "narrowphase/SphereVsSphereAlgorithm.h"
@ -46,7 +46,7 @@ namespace reactphysics3d {
// Declarations // Declarations
class BroadPhaseAlgorithm; class BroadPhaseAlgorithm;
class PhysicsWorld; class CollisionWorld;
/* ------------------------------------------------------------------- /* -------------------------------------------------------------------
Class CollisionDetection : Class CollisionDetection :
@ -57,45 +57,32 @@ class PhysicsWorld;
------------------------------------------------------------------- -------------------------------------------------------------------
*/ */
class CollisionDetection { class CollisionDetection {
private : private :
PhysicsWorld* world; // Pointer to the physics world CollisionWorld* world; // Pointer to the physics world
std::map<std::pair<bodyindex, bodyindex>, OverlappingPair*> overlappingPairs; // Broad-phase overlapping pairs of bodies std::map<bodyindexpair, BroadPhasePair*> overlappingPairs; // Broad-phase overlapping pairs of bodies
std::set<std::pair<bodyindex, bodyindex> > currentStepOverlappingPairs; // Overlapping pairs of bodies at the current collision detection step
std::set<std::pair<bodyindex, bodyindex> > lastStepOverlappingPairs; // Overlapping pairs of bodies at the last collision detection step
BroadPhaseAlgorithm* broadPhaseAlgorithm; // Broad-phase algorithm BroadPhaseAlgorithm* broadPhaseAlgorithm; // Broad-phase algorithm
GJKAlgorithm narrowPhaseGJKAlgorithm; // Narrow-phase GJK algorithm GJKAlgorithm narrowPhaseGJKAlgorithm; // Narrow-phase GJK algorithm
SphereVsSphereAlgorithm narrowPhaseSphereVsSphereAlgorithm; // Narrow-phase Sphere vs Sphere algorithm SphereVsSphereAlgorithm narrowPhaseSphereVsSphereAlgorithm; // Narrow-phase Sphere vs Sphere algorithm
MemoryPool<Contact> memoryPoolContacts; // Memory pool for the contacts
MemoryPool<OverlappingPair> memoryPoolOverlappingPairs; // Memory pool for the overlapping pairs
MemoryPool<ContactInfo> memoryPoolContactInfos; // Memory pool for the contact info MemoryPool<ContactInfo> memoryPoolContactInfos; // Memory pool for the contact info
MemoryPool<BroadPhasePair> memoryPoolOverlappingPairs; // Memory pool for the overlapping pairs
void computeBroadPhase(); // Compute the broad-phase collision detection void computeBroadPhase(); // Compute the broad-phase collision detection
bool computeNarrowPhase(); // Compute the narrow-phase collision detection bool computeNarrowPhase(); // Compute the narrow-phase collision detection
NarrowPhaseAlgorithm& SelectNarrowPhaseAlgorithm(CollisionShape* collisionShape1, NarrowPhaseAlgorithm& SelectNarrowPhaseAlgorithm(CollisionShape* collisionShape1,
CollisionShape* collisionShape2); // Select the narrow phase algorithm to use given two collision shapes CollisionShape* collisionShape2); // Select the narrow phase algorithm to use given two collision shapes
public : public :
CollisionDetection(PhysicsWorld* physicsWorld); // Constructor CollisionDetection(CollisionWorld* world); // Constructor
~CollisionDetection(); // Destructor ~CollisionDetection(); // Destructor
void addBody(Body* body); // Add a body to the collision detection void addBody(CollisionBody* body); // Add a body to the collision detection
void removeBody(Body* body); // Remove a body from the collision detection void removeBody(CollisionBody* body); // Remove a body from the collision detection
OverlappingPair* getOverlappingPair(bodyindex body1ID, bodyindex body2ID); // Return an overlapping pair or null
bool computeCollisionDetection(); // Compute the collision detection bool computeCollisionDetection(); // Compute the collision detection
void broadPhaseNotifyAddedOverlappingPair(const BroadPhasePair* pair); // Allow the broadphase to notify the collision detection about a new overlapping pair void broadPhaseNotifyAddedOverlappingPair(BodyPair* pair); // Allow the broadphase to notify the collision detection about a new overlapping pair
void broadPhaseNotifyRemovedOverlappingPair(const BroadPhasePair* pair); // Allow the broadphase to notify the collision detection about a removed overlapping pair void broadPhaseNotifyRemovedOverlappingPair(BodyPair* pair); // Allow the broadphase to notify the collision detection about a removed overlapping pair
}; };
// Return an overlapping pair of bodies according to the given bodies ID
// The method returns null if the pair of bodies is not overlapping
inline OverlappingPair* CollisionDetection::getOverlappingPair(bodyindex body1ID, bodyindex body2ID) {
std::pair<bodyindex, bodyindex> pair = (body1ID < body2ID) ? std::make_pair(body1ID, body2ID) : std::make_pair(body2ID, body1ID);
if (overlappingPairs.count(pair) == 1) {
return overlappingPairs[pair];
}
return 0;
}
// Select the narrow-phase collision algorithm to use given two collision shapes // Select the narrow-phase collision algorithm to use given two collision shapes
inline NarrowPhaseAlgorithm& CollisionDetection::SelectNarrowPhaseAlgorithm(CollisionShape* collisionShape1, CollisionShape* collisionShape2) { inline NarrowPhaseAlgorithm& CollisionDetection::SelectNarrowPhaseAlgorithm(CollisionShape* collisionShape1, CollisionShape* collisionShape2) {
@ -109,14 +96,14 @@ inline NarrowPhaseAlgorithm& CollisionDetection::SelectNarrowPhaseAlgorithm(Coll
} }
// Add a body to the collision detection // Add a body to the collision detection
inline void CollisionDetection::addBody(Body* body) { inline void CollisionDetection::addBody(CollisionBody* body) {
// Add the body to the broad-phase // Add the body to the broad-phase
broadPhaseAlgorithm->addObject(body, *(body->getAABB())); broadPhaseAlgorithm->addObject(body, *(body->getAABB()));
} }
// Remove a body from the collision detection // Remove a body from the collision detection
inline void CollisionDetection::removeBody(Body* body) { inline void CollisionDetection::removeBody(CollisionBody* body) {
// Remove the body from the broad-phase // Remove the body from the broad-phase
broadPhaseAlgorithm->removeObject(body); broadPhaseAlgorithm->removeObject(body);

View File

@ -28,7 +28,7 @@
// Libraries // Libraries
#include <vector> #include <vector>
#include "../../body/Body.h" #include "../../body/CollisionBody.h"
#include "PairManager.h" #include "PairManager.h"
// Namespace ReactPhysics3D // Namespace ReactPhysics3D
@ -62,12 +62,12 @@ class BroadPhaseAlgorithm {
// TODO : DELETE THIS METHOD // TODO : DELETE THIS METHOD
uint getNbOverlappingPairs() const; uint getNbOverlappingPairs() const;
virtual void addObject(Body* body, const AABB& aabb)=0; // Notify the broad-phase about a new object in the world virtual void addObject(CollisionBody* body, const AABB& aabb)=0; // Notify the broad-phase about a new object in the world
virtual void removeObject(Body* body)=0; // Notify the broad-phase about an object that has been removed from the world virtual void removeObject(CollisionBody* body)=0; // Notify the broad-phase about an object that has been removed from the world
virtual void updateObject(Body* body, const AABB& aabb)=0; // Notify the broad-phase that the AABB of an object has changed virtual void updateObject(CollisionBody* body, const AABB& aabb)=0; // Notify the broad-phase that the AABB of an object has changed
BroadPhasePair* beginOverlappingPairsPointer() const; // Return a pointer to the first active pair (used to iterate over the active pairs) BodyPair* beginOverlappingPairsPointer() const; // Return a pointer to the first active pair (used to iterate over the active pairs)
BroadPhasePair* endOverlappingPairsPointer() const; // Return a pointer to the last active pair (used to iterate over the active pairs) BodyPair* endOverlappingPairsPointer() const; // Return a pointer to the last active pair (used to iterate over the active pairs)
}; };
// TODO : DELETE THIS METHOD // TODO : DELETE THIS METHOD
@ -77,12 +77,12 @@ inline uint BroadPhaseAlgorithm::getNbOverlappingPairs() const {
// Return a pointer to the first active pair (used to iterate over the overlapping pairs) // Return a pointer to the first active pair (used to iterate over the overlapping pairs)
inline BroadPhasePair* BroadPhaseAlgorithm::beginOverlappingPairsPointer() const { inline BodyPair* BroadPhaseAlgorithm::beginOverlappingPairsPointer() const {
return pairManager.beginOverlappingPairsPointer(); return pairManager.beginOverlappingPairsPointer();
} }
// Return a pointer to the last active pair (used to iterate over the overlapping pairs) // Return a pointer to the last active pair (used to iterate over the overlapping pairs)
inline BroadPhasePair* BroadPhaseAlgorithm::endOverlappingPairsPointer() const { inline BodyPair* BroadPhaseAlgorithm::endOverlappingPairsPointer() const {
return pairManager.endOverlappingPairsPointer(); return pairManager.endOverlappingPairsPointer();
} }

View File

@ -44,25 +44,25 @@ namespace reactphysics3d {
*/ */
class NoBroadPhaseAlgorithm : public BroadPhaseAlgorithm { class NoBroadPhaseAlgorithm : public BroadPhaseAlgorithm {
protected : protected :
std::set<Body*> bodies; // All bodies of the world std::set<CollisionBody*> bodies; // All bodies of the world
public : public :
NoBroadPhaseAlgorithm(CollisionDetection& collisionDetection); // Constructor NoBroadPhaseAlgorithm(CollisionDetection& collisionDetection); // Constructor
virtual ~NoBroadPhaseAlgorithm(); // Destructor virtual ~NoBroadPhaseAlgorithm(); // Destructor
virtual void addObject(Body* body, const AABB& aabb); // Notify the broad-phase about a new object in the world virtual void addObject(CollisionBody* body, const AABB& aabb); // Notify the broad-phase about a new object in the world
virtual void removeObject(Body* body); // Notify the broad-phase about an object that has been removed from the world virtual void removeObject(CollisionBody* body); // Notify the broad-phase about an object that has been removed from the world
virtual void updateObject(Body* body, const AABB& aabb); // Notify the broad-phase that the AABB of an object has changed virtual void updateObject(CollisionBody* body, const AABB& aabb); // Notify the broad-phase that the AABB of an object has changed
}; };
// Notify the broad-phase about a new object in the world // Notify the broad-phase about a new object in the world
inline void NoBroadPhaseAlgorithm::addObject(Body* body, const AABB& aabb) { inline void NoBroadPhaseAlgorithm::addObject(CollisionBody* body, const AABB& aabb) {
std::cout << "New body in broadphase with id=" << body->getID() << std::endl; std::cout << "New body in broadphase with id=" << body->getID() << std::endl;
// For each body that is already in the world // For each body that is already in the world
for (std::set<Body*>::iterator it = bodies.begin(); it != bodies.end(); ++it) { for (std::set<CollisionBody*>::iterator it = bodies.begin(); it != bodies.end(); ++it) {
// Add an overlapping pair with the new body // Add an overlapping pair with the new body
pairManager.addPair(*it, body); pairManager.addPair(*it, body);
@ -73,10 +73,10 @@ inline void NoBroadPhaseAlgorithm::addObject(Body* body, const AABB& aabb) {
} }
// Notify the broad-phase about an object that has been removed from the world // Notify the broad-phase about an object that has been removed from the world
inline void NoBroadPhaseAlgorithm::removeObject(Body* body) { inline void NoBroadPhaseAlgorithm::removeObject(CollisionBody* body) {
// For each body that is in the world // For each body that is in the world
for (std::set<Body*>::iterator it = bodies.begin(); it != bodies.end(); ++it) { for (std::set<CollisionBody*>::iterator it = bodies.begin(); it != bodies.end(); ++it) {
if ((*it)->getID() != body->getID()) { if ((*it)->getID() != body->getID()) {
@ -90,7 +90,7 @@ inline void NoBroadPhaseAlgorithm::removeObject(Body* body) {
} }
// Notify the broad-phase that the AABB of an object has changed // Notify the broad-phase that the AABB of an object has changed
inline void NoBroadPhaseAlgorithm::updateObject(Body* body, const AABB& aabb) { inline void NoBroadPhaseAlgorithm::updateObject(CollisionBody* body, const AABB& aabb) {
// Do nothing // Do nothing
return; return;
} }

View File

@ -56,7 +56,7 @@ PairManager::~PairManager() {
// that pair. If the pair to add does not already exist in the set of // that pair. If the pair to add does not already exist in the set of
// overlapping pairs, it will be created and if it already exists, we only // overlapping pairs, it will be created and if it already exists, we only
// return a pointer to that pair. // return a pointer to that pair.
BroadPhasePair* PairManager::addPair(Body* body1, Body* body2) { BodyPair* PairManager::addPair(CollisionBody* body1, CollisionBody* body2) {
// Sort the bodies to have the body with smallest ID first // Sort the bodies to have the body with smallest ID first
sortBodiesUsingID(body1, body2); sortBodiesUsingID(body1, body2);
@ -69,7 +69,7 @@ BroadPhasePair* PairManager::addPair(Body* body1, Body* body2) {
uint hashValue = computeHashBodies(id1, id2) & hashMask; uint hashValue = computeHashBodies(id1, id2) & hashMask;
// Try to find the pair in the current overlapping pairs. // Try to find the pair in the current overlapping pairs.
BroadPhasePair* pair = findPairWithHashValue(id1, id2, hashValue); BodyPair* pair = findPairWithHashValue(id1, id2, hashValue);
// If the pair is already in the set of overlapping pairs // If the pair is already in the set of overlapping pairs
if (pair) { if (pair) {
@ -93,7 +93,7 @@ BroadPhasePair* PairManager::addPair(Body* body1, Body* body2) {
} }
// Create the new overlapping pair // Create the new overlapping pair
BroadPhasePair* newPair = &overlappingPairs[nbOverlappingPairs]; BodyPair* newPair = &overlappingPairs[nbOverlappingPairs];
newPair->body1 = body1; newPair->body1 = body1;
newPair->body2 = body2; newPair->body2 = body2;
@ -119,7 +119,7 @@ bool PairManager::removePair(bodyindex id1, bodyindex id2) {
const uint hashValue = computeHashBodies(id1, id2) & hashMask; const uint hashValue = computeHashBodies(id1, id2) & hashMask;
// Find the pair to remove // Find the pair to remove
const BroadPhasePair* pair = findPairWithHashValue(id1, id2, hashValue); BodyPair* pair = findPairWithHashValue(id1, id2, hashValue);
// If we have not found the pair // If we have not found the pair
if (!pair) { if (!pair) {
@ -184,7 +184,7 @@ void PairManager::removePairWithHashValue(bodyindex id1, bodyindex id2, luint ha
// now free because of the pair we want to remove // now free because of the pair we want to remove
// Get the last pair // Get the last pair
const BroadPhasePair* lastPair = &overlappingPairs[indexLastPair]; const BodyPair* lastPair = &overlappingPairs[indexLastPair];
const uint lastPairHashValue = computeHashBodies(lastPair->body1->getID(), lastPair->body2->getID()) & hashMask; const uint lastPairHashValue = computeHashBodies(lastPair->body1->getID(), lastPair->body2->getID()) & hashMask;
// Compute the initial offset of the last pair // Compute the initial offset of the last pair
@ -223,7 +223,7 @@ void PairManager::removePairWithHashValue(bodyindex id1, bodyindex id2, luint ha
} }
// Look for a pair in the set of overlapping pairs // Look for a pair in the set of overlapping pairs
BroadPhasePair* PairManager::lookForAPair(bodyindex id1, bodyindex id2, luint hashValue) const { BodyPair* PairManager::lookForAPair(bodyindex id1, bodyindex id2, luint hashValue) const {
// Look for the pair in the set of overlapping pairs // Look for the pair in the set of overlapping pairs
bodyindex offset = hashTable[hashValue]; bodyindex offset = hashTable[hashValue];
@ -256,7 +256,7 @@ void PairManager::reallocatePairs() {
} }
// Reallocate the overlapping pairs // Reallocate the overlapping pairs
BroadPhasePair* newOverlappingPairs = (BroadPhasePair*) malloc(nbElementsHashTable * sizeof(BroadPhasePair)); BodyPair* newOverlappingPairs = (BodyPair*) malloc(nbElementsHashTable * sizeof(BodyPair));
bodyindex* newOffsetNextPair = (bodyindex*) malloc(nbElementsHashTable * sizeof(bodyindex)); bodyindex* newOffsetNextPair = (bodyindex*) malloc(nbElementsHashTable * sizeof(bodyindex));
assert(newOverlappingPairs); assert(newOverlappingPairs);
@ -264,8 +264,8 @@ void PairManager::reallocatePairs() {
// If there is already some overlapping pairs // If there is already some overlapping pairs
if (nbOverlappingPairs) { if (nbOverlappingPairs) {
// Copy the pairs to the new place // Copy the pairs to the new location
memcpy(newOverlappingPairs, overlappingPairs, nbOverlappingPairs * sizeof(BroadPhasePair)); memcpy(newOverlappingPairs, overlappingPairs, nbOverlappingPairs * sizeof(BodyPair));
} }
// Recompute the hash table with the new hash values // Recompute the hash table with the new hash values

View File

@ -27,7 +27,8 @@
#define PAIR_MANAGER_H #define PAIR_MANAGER_H
// Libraries // Libraries
#include "../../body/Body.h" #include "../../body/CollisionBody.h"
#include <utility>
// Namespace ReactPhysics3D // Namespace ReactPhysics3D
@ -35,15 +36,26 @@ namespace reactphysics3d {
// Declaration // Declaration
class CollisionDetection; class CollisionDetection;
// Structure BroadPhasePair that represents a pair of bodies
// during the broad-phase collision detection
struct BroadPhasePair {
public:
Body* body1; // Pointer to the first body
Body* body2; // Pointer to the second body
};
// struct BodyPair
// This structure represents a pair of bodies
// during the broad-phase collision detection
struct BodyPair {
public:
CollisionBody* body1; // Pointer to the first body
CollisionBody* body2; // Pointer to the second body
// Return the pair of bodies index
bodyindexpair getBodiesIndexPair() const {
// Construct the pair of body index
bodyindexpair indexPair = body1->getID() < body2->getID() ? std::make_pair(body1->getID(), body2->getID()) :
std::make_pair(body2->getID(), body1->getID());
assert(indexPair.first != indexPair.second);
return indexPair;
}
};
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
Class PairManager : Class PairManager :
@ -63,23 +75,23 @@ class PairManager {
bodyindex* offsetNextPair; // Array that contains for each offset, the offset of the next pair with bodyindex* offsetNextPair; // Array that contains for each offset, the offset of the next pair with
// the same hash value // the same hash value
// for a given same hash value // for a given same hash value
BroadPhasePair* overlappingPairs; // Array that contains the currently active pairs BodyPair* overlappingPairs; // Array that contains the currently active pairs
static bodyindex INVALID_INDEX; // Invalid ID static bodyindex INVALID_INDEX; // Invalid ID
CollisionDetection& collisionDetection; // Reference to the collision detection CollisionDetection& collisionDetection; // Reference to the collision detection
void sortBodiesUsingID(Body*& body1, Body*& body2) const; // Sort the bodies according to their IDs (smallest ID first) void sortBodiesUsingID(CollisionBody*& body1, CollisionBody*& body2) const; // Sort the bodies according to their IDs (smallest ID first)
void sortIDs(bodyindex& id1, bodyindex& id2) const; // Sort the IDs (smallest ID first) void sortIDs(bodyindex& id1, bodyindex& id2) const; // Sort the IDs (smallest ID first)
bool isDifferentPair(const BroadPhasePair& pair1, bodyindex pair2ID1, bool isDifferentPair(const BodyPair& pair1, bodyindex pair2ID1,
bodyindex pair2ID2) const; // Return true if pair1 and pair2 are the same bodyindex pair2ID2) const; // Return true if pair1 and pair2 are the same
uint computeHashBodies(uint id1, uint id2) const; // Compute the hash value of two bodies using their IDs uint computeHashBodies(uint id1, uint id2) const; // Compute the hash value of two bodies using their IDs
int computeHash32Bits(int key) const; // This method returns an hash value for a 32 bits key int computeHash32Bits(int key) const; // This method returns an hash value for a 32 bits key
luint computeNextPowerOfTwo(luint number) const; // Return the next power of two luint computeNextPowerOfTwo(luint number) const; // Return the next power of two
void reallocatePairs(); // Reallocate memory for more pairs void reallocatePairs(); // Reallocate memory for more pairs
void shrinkMemory(); // Shrink the allocated memory void shrinkMemory(); // Shrink the allocated memory
bodyindex computePairOffset(const BroadPhasePair* pair) const; // Compute the offset of a given pair bodyindex computePairOffset(const BodyPair* pair) const; // Compute the offset of a given pair
BroadPhasePair* lookForAPair(bodyindex id1, bodyindex id2, BodyPair* lookForAPair(bodyindex id1, bodyindex id2,
luint hashValue) const; // Look for a pair in the set of overlapping pairs luint hashValue) const; // Look for a pair in the set of overlapping pairs
BroadPhasePair* findPairWithHashValue(bodyindex id1, bodyindex id2, BodyPair* findPairWithHashValue(bodyindex id1, bodyindex id2,
luint hashValue) const; // Find a pair given two body IDs and an hash value luint hashValue) const; // Find a pair given two body IDs and an hash value
void removePairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue, void removePairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue,
bodyindex indexPair); // Remove a pair from the set of active pair bodyindex indexPair); // Remove a pair from the set of active pair
@ -88,14 +100,14 @@ class PairManager {
~PairManager(); // Destructor ~PairManager(); // Destructor
bodyindex getNbOverlappingPairs() const; // Return the number of active pairs bodyindex getNbOverlappingPairs() const; // Return the number of active pairs
BroadPhasePair* addPair(Body* body1, Body* body2); // Add a pair of bodies in the pair manager BodyPair* addPair(CollisionBody* body1, CollisionBody* body2); // Add a pair of bodies in the pair manager
bool removePair(bodyindex id1, bodyindex id2); // Remove a pair of bodies from the pair manager bool removePair(bodyindex id1, bodyindex id2); // Remove a pair of bodies from the pair manager
BroadPhasePair* findPair(bodyindex id1, bodyindex id2) const; // Find a pair given two body IDs BodyPair* findPair(bodyindex id1, bodyindex id2) const; // Find a pair given two body IDs
BroadPhasePair* beginOverlappingPairsPointer() const; // Return a pointer to the first overlapping pair (used to iterate over the active pairs) BodyPair* beginOverlappingPairsPointer() const; // Return a pointer to the first overlapping pair (used to iterate over the active pairs)
BroadPhasePair* endOverlappingPairsPointer() const; // Return a pointer to the last overlapping pair (used to iterate over the active pairs) BodyPair* endOverlappingPairsPointer() const; // Return a pointer to the last overlapping pair (used to iterate over the active pairs)
void registerAddedOverlappingPairCallback(void (CollisionDetection::*callbackFunction) (const BroadPhasePair* addedActivePair)); // Register a callback function (using a function pointer) that will be called when a new overlapping pair is added in the pair manager void registerAddedOverlappingPairCallback(void (CollisionDetection::*callbackFunction) (const BodyPair* addedActivePair)); // Register a callback function (using a function pointer) that will be called when a new overlapping pair is added in the pair manager
void unregisterAddedOverlappingPairCallback(); // Unregister the callback function that will be called when a new active pair is added in the pair manager void unregisterAddedOverlappingPairCallback(); // Unregister the callback function that will be called when a new active pair is added in the pair manager
void registerRemovedOverlappingPairCallback(void (CollisionDetection::*callbackFunction) (const BroadPhasePair* removedActivePair)); // Register a callback function (using a function pointer) that will be called when an overlapping pair is removed from the pair manager void registerRemovedOverlappingPairCallback(void (CollisionDetection::*callbackFunction) (const BodyPair* removedActivePair)); // Register a callback function (using a function pointer) that will be called when an overlapping pair is removed from the pair manager
void unregisterRemovedOverlappingPairCallback(); // Unregister a callback function that will be called when a active pair is removed from the pair manager void unregisterRemovedOverlappingPairCallback(); // Unregister a callback function that will be called when a active pair is removed from the pair manager
}; };
@ -110,7 +122,7 @@ inline uint PairManager::computeHashBodies(uint id1, uint id2) const {
} }
// Return true if pair1 and pair2 are the same // Return true if pair1 and pair2 are the same
inline bool PairManager::isDifferentPair(const BroadPhasePair& pair1, bodyindex pair2ID1, bodyindex pair2ID2) const { inline bool PairManager::isDifferentPair(const BodyPair& pair1, bodyindex pair2ID1, bodyindex pair2ID2) const {
return (pair2ID1 != pair1.body1->getID() || pair2ID2 != pair1.body2->getID()); return (pair2ID1 != pair1.body1->getID() || pair2ID2 != pair1.body2->getID());
} }
@ -125,13 +137,13 @@ inline luint PairManager::computeNextPowerOfTwo(luint number) const {
} }
// Sort the bodies according to their IDs (smallest ID first) // Sort the bodies according to their IDs (smallest ID first)
inline void PairManager::sortBodiesUsingID(Body*& body1, Body*& body2) const { inline void PairManager::sortBodiesUsingID(CollisionBody*& body1, CollisionBody*& body2) const {
// If the ID of body1 is larger than the ID of body 2 // If the ID of body1 is larger than the ID of body 2
if (body1->getID() > body2->getID()) { if (body1->getID() > body2->getID()) {
// Swap the two bodies pointers // Swap the two bodies pointers
Body* temp = body2; CollisionBody* temp = body2;
body2 = body1; body2 = body1;
body1 = temp; body1 = temp;
} }
@ -161,7 +173,7 @@ inline int PairManager::computeHash32Bits(int key) const {
} }
// Find a pair given two body IDs // Find a pair given two body IDs
inline BroadPhasePair* PairManager::findPair(bodyindex id1, bodyindex id2) const { inline BodyPair* PairManager::findPair(bodyindex id1, bodyindex id2) const {
// Check if the hash table has been allocated yet // Check if the hash table has been allocated yet
if (!hashTable) return 0; if (!hashTable) return 0;
@ -179,7 +191,7 @@ inline BroadPhasePair* PairManager::findPair(bodyindex id1, bodyindex id2) const
// Find a pair given two body IDs and an hash value // Find a pair given two body IDs and an hash value
// This internal version is used to avoid computing multiple times in the // This internal version is used to avoid computing multiple times in the
// caller method // caller method
inline BroadPhasePair* PairManager::findPairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue) const { inline BodyPair* PairManager::findPairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue) const {
// Check if the hash table has been allocated yet // Check if the hash table has been allocated yet
if (!hashTable) return 0; if (!hashTable) return 0;
@ -202,19 +214,19 @@ inline void PairManager::shrinkMemory() {
} }
// Compute the offset of a given pair in the array of overlapping pairs // Compute the offset of a given pair in the array of overlapping pairs
inline bodyindex PairManager::computePairOffset(const BroadPhasePair* pair) const { inline bodyindex PairManager::computePairOffset(const BodyPair* pair) const {
return ((bodyindex)((size_t(pair) - size_t(overlappingPairs))) / sizeof(BroadPhasePair)); return ((bodyindex)((size_t(pair) - size_t(overlappingPairs))) / sizeof(BodyPair));
} }
// Return a pointer to the first overlapping pair (used to iterate over the overlapping pairs) or // Return a pointer to the first overlapping pair (used to iterate over the overlapping pairs) or
// returns 0 if there is no overlapping pairs. // returns 0 if there is no overlapping pairs.
inline BroadPhasePair* PairManager::beginOverlappingPairsPointer() const { inline BodyPair* PairManager::beginOverlappingPairsPointer() const {
return &overlappingPairs[0]; return &overlappingPairs[0];
} }
// Return a pointer to the last overlapping pair (used to iterate over the overlapping pairs) or // Return a pointer to the last overlapping pair (used to iterate over the overlapping pairs) or
// returns 0 if there is no overlapping pairs. // returns 0 if there is no overlapping pairs.
inline BroadPhasePair* PairManager::endOverlappingPairsPointer() const { inline BodyPair* PairManager::endOverlappingPairsPointer() const {
if (nbOverlappingPairs > 0) { if (nbOverlappingPairs > 0) {
return &overlappingPairs[nbOverlappingPairs-1]; return &overlappingPairs[nbOverlappingPairs-1];
} }

View File

@ -65,7 +65,7 @@ SweepAndPruneAlgorithm::~SweepAndPruneAlgorithm() {
// Notify the broad-phase about a new object in the world // Notify the broad-phase about a new object in the world
// This method adds the AABB of the object ion to broad-phase // This method adds the AABB of the object ion to broad-phase
void SweepAndPruneAlgorithm::addObject(Body* body, const AABB& aabb) { void SweepAndPruneAlgorithm::addObject(CollisionBody* body, const AABB& aabb) {
bodyindex boxIndex; bodyindex boxIndex;
// If the index of the first free box is valid (means that // If the index of the first free box is valid (means that
@ -112,7 +112,7 @@ void SweepAndPruneAlgorithm::addObject(Body* body, const AABB& aabb) {
} }
// Add the body pointer to box index mapping // Add the body pointer to box index mapping
mapBodyToBoxIndex.insert(pair<Body*, bodyindex>(body, boxIndex)); mapBodyToBoxIndex.insert(pair<CollisionBody*, bodyindex>(body, boxIndex));
nbBoxes++; nbBoxes++;
@ -124,7 +124,7 @@ void SweepAndPruneAlgorithm::addObject(Body* body, const AABB& aabb) {
} }
// Notify the broad-phase about a object that has been removed from the world // Notify the broad-phase about a object that has been removed from the world
void SweepAndPruneAlgorithm::removeObject(Body* body) { void SweepAndPruneAlgorithm::removeObject(CollisionBody* body) {
// Call the update method with an AABB that is very far away // Call the update method with an AABB that is very far away
// in order to remove all overlapping pairs from the pair manager // in order to remove all overlapping pairs from the pair manager
@ -145,7 +145,7 @@ void SweepAndPruneAlgorithm::removeObject(Body* body) {
} }
// Notify the broad-phase that the AABB of an object has changed // Notify the broad-phase that the AABB of an object has changed
void SweepAndPruneAlgorithm::updateObject(Body* body, const AABB& aabb) { void SweepAndPruneAlgorithm::updateObject(CollisionBody* body, const AABB& aabb) {
// Compute the AABB with integer coordinates // Compute the AABB with integer coordinates
AABBInt aabbInt(aabb); AABBInt aabbInt(aabb);

View File

@ -62,7 +62,7 @@ struct BoxAABB {
public: public:
bodyindex min[3]; // Index of the three minimum end-points of the AABB over the axis X, Y and Z bodyindex min[3]; // Index of the three minimum end-points of the AABB over the axis X, Y and Z
bodyindex max[3]; // Index of the three maximum end-points of the AABB over the axis X, Y and Z bodyindex max[3]; // Index of the three maximum end-points of the AABB over the axis X, Y and Z
Body* body; // Body that corresponds to the owner of the AABB CollisionBody* body; // Body that corresponds to the owner of the AABB
}; };
// Structure AABBInt // Structure AABBInt
@ -94,10 +94,10 @@ class SweepAndPruneAlgorithm : public BroadPhaseAlgorithm {
bodyindex nbBoxes; // Number of AABB boxes in the broad-phase bodyindex nbBoxes; // Number of AABB boxes in the broad-phase
bodyindex nbMaxBoxes; // Maximum number of boxes in the boxes array bodyindex nbMaxBoxes; // Maximum number of boxes in the boxes array
std::vector<bodyindex> freeBoxIndices; // Indices that are not used by any boxes std::vector<bodyindex> freeBoxIndices; // Indices that are not used by any boxes
std::map<Body*, bodyindex> mapBodyToBoxIndex; // Map a body pointer to its box index std::map<CollisionBody*, bodyindex> mapBodyToBoxIndex; // Map a body pointer to its box index
void resizeArrays(); // Resize the boxes and end-points arrays when it's full void resizeArrays(); // Resize the boxes and end-points arrays when it's full
void addPair(Body* body1, Body* body2); // Add an overlapping pair of AABBS void addPair(CollisionBody* body1, CollisionBody* body2); // Add an overlapping pair of AABBS
bool testIntersect1DSortedAABBs(const BoxAABB& box1, const AABBInt& box2, bool testIntersect1DSortedAABBs(const BoxAABB& box1, const AABBInt& box2,
const EndPoint* const baseEndPoint, uint axis) const; // Check for 1D box intersection const EndPoint* const baseEndPoint, uint axis) const; // Check for 1D box intersection
bool testIntersect2D(const BoxAABB& box1, const BoxAABB& box2, bool testIntersect2D(const BoxAABB& box1, const BoxAABB& box2,
@ -107,9 +107,9 @@ class SweepAndPruneAlgorithm : public BroadPhaseAlgorithm {
SweepAndPruneAlgorithm(CollisionDetection& collisionDetection); // Constructor SweepAndPruneAlgorithm(CollisionDetection& collisionDetection); // Constructor
virtual ~SweepAndPruneAlgorithm(); // Destructor virtual ~SweepAndPruneAlgorithm(); // Destructor
virtual void addObject(Body* body, const AABB& aabb); // Notify the broad-phase about a new object in the world virtual void addObject(CollisionBody* body, const AABB& aabb); // Notify the broad-phase about a new object in the world
virtual void removeObject(Body* body); // Notify the broad-phase about a object that has been removed from the world virtual void removeObject(CollisionBody* body); // Notify the broad-phase about a object that has been removed from the world
virtual void updateObject(Body* body, const AABB& aabb); // Notify the broad-phase that the AABB of an object has changed virtual void updateObject(CollisionBody* body, const AABB& aabb); // Notify the broad-phase that the AABB of an object has changed
}; };
// Encode a floating value into a integer value in order to // Encode a floating value into a integer value in order to

View File

@ -28,7 +28,6 @@
#include "Simplex.h" #include "Simplex.h"
#include "../../../constraint/Contact.h" #include "../../../constraint/Contact.h"
#include "../../../configuration.h" #include "../../../configuration.h"
#include "../../OverlappingPair.h"
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <cfloat> #include <cfloat>
@ -87,7 +86,7 @@ bool GJKAlgorithm::testCollision(const CollisionShape* collisionShape1, const Tr
Simplex simplex; Simplex simplex;
// Get the previous point V (last cached separating axis) // Get the previous point V (last cached separating axis)
Vector3 v = currentOverlappingPair->getCachedSeparatingAxis(); Vector3 v = currentOverlappingPair->previousSeparatingAxis;
// Initialize the upper bound for the square distance // Initialize the upper bound for the square distance
decimal distSquare = DECIMAL_LARGEST; decimal distSquare = DECIMAL_LARGEST;
@ -107,7 +106,7 @@ bool GJKAlgorithm::testCollision(const CollisionShape* collisionShape1, const Tr
if (vDotw > 0.0 && vDotw * vDotw > distSquare * marginSquare) { if (vDotw > 0.0 && vDotw * vDotw > distSquare * marginSquare) {
// Cache the current separating axis for frame coherence // Cache the current separating axis for frame coherence
currentOverlappingPair->setCachedSeparatingAxis(v); currentOverlappingPair->previousSeparatingAxis = v;
// No intersection, we return false // No intersection, we return false
return false; return false;

View File

@ -29,7 +29,10 @@
// Libraries // Libraries
#include "../../body/Body.h" #include "../../body/Body.h"
#include "../ContactInfo.h" #include "../ContactInfo.h"
#include "../OverlappingPair.h" #include "../broadphase/PairManager.h"
#include "../../memory/MemoryPool.h"
#include "../BroadPhasePair.h"
// Namespace ReactPhysics3D // Namespace ReactPhysics3D
namespace reactphysics3d { namespace reactphysics3d {
@ -46,20 +49,20 @@ namespace reactphysics3d {
class NarrowPhaseAlgorithm { class NarrowPhaseAlgorithm {
protected : protected :
MemoryPool<ContactInfo>& memoryPoolContactInfos; // Reference to the memory pool for contact infos MemoryPool<ContactInfo>& memoryPoolContactInfos; // Reference to the memory pool for contact infos
OverlappingPair* currentOverlappingPair; // Overlapping pair of the bodies currently tested for collision BroadPhasePair* currentOverlappingPair; // Overlapping pair of the bodies currently tested for collision
public : public :
NarrowPhaseAlgorithm(MemoryPool<ContactInfo>& memoryPool); // Constructor NarrowPhaseAlgorithm(MemoryPool<ContactInfo>& memoryPool); // Constructor
virtual ~NarrowPhaseAlgorithm(); // Destructor virtual ~NarrowPhaseAlgorithm(); // Destructor
void setCurrentOverlappingPair(OverlappingPair* overlappingPair); // Set the current overlapping pair of bodies void setCurrentOverlappingPair(BroadPhasePair* overlappingPair); // Set the current overlapping pair of bodies
virtual bool testCollision(const CollisionShape* collisionShape1, const Transform& transform1, virtual bool testCollision(const CollisionShape* collisionShape1, const Transform& transform1,
const CollisionShape* collisionShape2, const Transform& transform2, const CollisionShape* collisionShape2, const Transform& transform2,
ContactInfo*& contactInfo)=0; // Return true and compute a contact info if the two bounding volume collide ContactInfo*& contactInfo)=0; // Return true and compute a contact info if the two bounding volume collide
}; };
// Set the current overlapping pair of bodies // Set the current overlapping pair of bodies
inline void NarrowPhaseAlgorithm::setCurrentOverlappingPair(OverlappingPair* overlappingPair) { inline void NarrowPhaseAlgorithm::setCurrentOverlappingPair(BroadPhasePair *overlappingPair) {
currentOverlappingPair = overlappingPair; currentOverlappingPair = overlappingPair;
} }

View File

@ -29,6 +29,7 @@
// Libraries // Libraries
#include <limits> #include <limits>
#include <cfloat> #include <cfloat>
#include <utility>
#include "decimal.h" #include "decimal.h"
// Windows platform // Windows platform
@ -47,6 +48,7 @@ namespace reactphysics3d {
typedef unsigned int uint; typedef unsigned int uint;
typedef long unsigned int luint; typedef long unsigned int luint;
typedef short unsigned int bodyindex; // TODO : Replace whenever possible using the bodyindex type typedef short unsigned int bodyindex; // TODO : Replace whenever possible using the bodyindex type
typedef std::pair<bodyindex, bodyindex> bodyindexpair;
// Mathematical constants // Mathematical constants
const reactphysics3d::decimal DECIMAL_SMALLEST = - std::numeric_limits<reactphysics3d::decimal>::max(); // Minimun decimal value const reactphysics3d::decimal DECIMAL_SMALLEST = - std::numeric_limits<reactphysics3d::decimal>::max(); // Minimun decimal value

View File

@ -30,7 +30,7 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
Constraint::Constraint(Body* const body1, Body* const body2, uint nbConstraints, bool active, ConstraintType type) Constraint::Constraint(RigidBody* const body1, RigidBody* const body2, uint nbConstraints, bool active, ConstraintType type)
:body1(body1), body2(body2), active(active), nbConstraints(nbConstraints), type(type) { :body1(body1), body2(body2), active(active), nbConstraints(nbConstraints), type(type) {
// Initialize the cached lambda values // Initialize the cached lambda values

View File

@ -27,7 +27,7 @@
#define CONSTRAINT_H #define CONSTRAINT_H
// Libraries // Libraries
#include "../body/Body.h" #include "../body/RigidBody.h"
#include "../mathematics/mathematics.h" #include "../mathematics/mathematics.h"
// ReactPhysics3D namespace // ReactPhysics3D namespace
@ -46,19 +46,19 @@ enum ConstraintType {CONTACT};
*/ */
class Constraint { class Constraint {
protected : protected :
Body* const body1; // Pointer to the first body of the constraint RigidBody* const body1; // Pointer to the first body of the constraint
Body* const body2; // Pointer to the second body of the constraint RigidBody* const body2; // Pointer to the second body of the constraint
bool active; // True if the constraint is active bool active; // True if the constraint is active
uint nbConstraints; // Number mathematical constraints associated with this Constraint uint nbConstraints; // Number mathematical constraints associated with this Constraint
const ConstraintType type; // Type of the constraint const ConstraintType type; // Type of the constraint
std::vector<decimal> cachedLambdas; // Cached lambda values of each mathematical constraint for more precise initializaton of LCP solver std::vector<decimal> cachedLambdas; // Cached lambda values of each mathematical constraint for more precise initializaton of LCP solver
public : public :
Constraint(Body* const body1, Body* const body2, uint nbConstraints, Constraint(RigidBody* const body1, RigidBody* const body2, uint nbConstraints,
bool active, ConstraintType type); // Constructor // Constructor bool active, ConstraintType type); // Constructor // Constructor
virtual ~Constraint(); // Destructor virtual ~Constraint(); // Destructor
Body* const getBody1() const; // Return the reference to the body 1 RigidBody* const getBody1() const; // Return the reference to the body 1
Body* const getBody2() const; // Return the reference to the body 2 // Evaluate the constraint RigidBody* const getBody2() const; // Return the reference to the body 2 // Evaluate the constraint
bool isActive() const; // Return true if the constraint is active // Return the jacobian matrix of body 2 bool isActive() const; // Return true if the constraint is active // Return the jacobian matrix of body 2
ConstraintType getType() const; // Return the type of the constraint ConstraintType getType() const; // Return the type of the constraint
virtual void computeJacobian(int noConstraint, decimal J_sp[NB_MAX_CONSTRAINTS][2*6]) const=0; // Compute the jacobian matrix for all mathematical constraints virtual void computeJacobian(int noConstraint, decimal J_sp[NB_MAX_CONSTRAINTS][2*6]) const=0; // Compute the jacobian matrix for all mathematical constraints
@ -71,12 +71,12 @@ class Constraint {
}; };
// Return the reference to the body 1 // Return the reference to the body 1
inline Body* const Constraint::getBody1() const { inline RigidBody* const Constraint::getBody1() const {
return body1; return body1;
} }
// Return the reference to the body 2 // Return the reference to the body 2
inline Body* const Constraint::getBody2() const { inline RigidBody* const Constraint::getBody2() const {
return body2; return body2;
} }

View File

@ -30,7 +30,7 @@ using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
Contact::Contact(Body* const body1, Body* const body2, const ContactInfo* contactInfo) Contact::Contact(RigidBody* const body1, RigidBody* const body2, const ContactInfo* contactInfo)
: Constraint(body1, body2, 3, true, CONTACT), normal(contactInfo->normal), penetrationDepth(contactInfo->penetrationDepth), : Constraint(body1, body2, 3, true, CONTACT), normal(contactInfo->normal), penetrationDepth(contactInfo->penetrationDepth),
localPointOnBody1(contactInfo->localPoint1), localPointOnBody2(contactInfo->localPoint2), localPointOnBody1(contactInfo->localPoint1), localPointOnBody2(contactInfo->localPoint2),
worldPointOnBody1(body1->getTransform() * contactInfo->localPoint1), worldPointOnBody2(body2->getTransform() * contactInfo->localPoint2) { worldPointOnBody1(body1->getTransform() * contactInfo->localPoint1), worldPointOnBody2(body2->getTransform() * contactInfo->localPoint2) {
@ -170,4 +170,4 @@ void Contact::computeErrorValue(int noConstraint, decimal errorValues[]) const {
errorValues[noConstraint] = errorValue; // Error value for contact constraint errorValues[noConstraint] = errorValue; // Error value for contact constraint
errorValues[noConstraint + 1] = 0.0; // Error value for friction constraint errorValues[noConstraint + 1] = 0.0; // Error value for friction constraint
errorValues[noConstraint + 2] = 0.0; // Error value for friction constraint errorValues[noConstraint + 2] = 0.0; // Error value for friction constraint
} }

View File

@ -62,6 +62,7 @@ namespace reactphysics3d {
------------------------------------------------------------------- -------------------------------------------------------------------
*/ */
class Contact : public Constraint { class Contact : public Constraint {
protected : protected :
const Vector3 normal; // Normal vector of the contact (From body1 toward body2) in world space const Vector3 normal; // Normal vector of the contact (From body1 toward body2) in world space
decimal penetrationDepth; // Penetration depth decimal penetrationDepth; // Penetration depth
@ -75,7 +76,7 @@ class Contact : public Constraint {
void computeFrictionVectors(); // Compute the two friction vectors that span the tangential friction plane void computeFrictionVectors(); // Compute the two friction vectors that span the tangential friction plane
public : public :
Contact(Body* const body1, Body* const body2, const ContactInfo* contactInfo); // Constructor Contact(RigidBody* const body1, RigidBody* const body2, const ContactInfo* contactInfo); // Constructor
virtual ~Contact(); // Destructor virtual ~Contact(); // Destructor
Vector3 getNormal() const; // Return the normal vector of the contact Vector3 getNormal() const; // Return the normal vector of the contact

View File

@ -24,8 +24,7 @@
********************************************************************************/ ********************************************************************************/
// Libraries // Libraries
#include "PhysicsWorld.h" #include "CollisionWorld.h"
#include "PhysicsEngine.h"
#include <algorithm> #include <algorithm>
// Namespaces // Namespaces
@ -33,88 +32,93 @@ using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
PhysicsWorld::PhysicsWorld(const Vector3& gravity) CollisionWorld::CollisionWorld() : collisionDetection(this), currentBodyID(0) {
: gravity(gravity), isGravityOn(true), currentBodyID(0) {
} }
// Destructor // Destructor
PhysicsWorld::~PhysicsWorld() { CollisionWorld::~CollisionWorld() {
} }
// Create a rigid body into the physics world // Notify the world about a new broad-phase overlapping pair
RigidBody* PhysicsWorld::createRigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal, CollisionShape* collisionShape) { void CollisionWorld::notifyAddedOverlappingPair(const BroadPhasePair* addedPair) {
// TODO : Implement this method
}
// Notify the world about a removed broad-phase overlapping pair
void CollisionWorld::notifyRemovedOverlappingPair(const BroadPhasePair* removedPair) {
// TODO : Implement this method
}
// Notify the world about a new narrow-phase contact
void CollisionWorld::notifyNewContact(const BroadPhasePair* broadPhasePair, const ContactInfo* contactInfo) {
// TODO : Implement this method
}
// Update the overlapping pair
inline void CollisionWorld::updateOverlappingPair(const BroadPhasePair* pair) {
}
// Create a collision body and add it to the world
CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform, CollisionShape* collisionShape) {
// Get the next available body ID
bodyindex bodyID = computeNextAvailableBodyID();
// Largest index cannot be used (it is used for invalid index)
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
// Create the collision body
CollisionBody* collisionBody = new (memoryPoolCollisionBodies.allocateObject()) CollisionBody(transform, collisionShape, bodyID);
// Add the collision body to the world
bodies.insert(collisionBody);
// Add the collision body to the collision detection
collisionDetection.addBody(collisionBody);
// Return the pointer to the rigid body
return collisionBody;
}
// Destroy a collision body
void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) {
// Remove the body from the collision detection
collisionDetection.removeBody(collisionBody);
// Add the body ID to the list of free IDs
freeBodiesIDs.push_back(collisionBody->getID());
// Call the constructor of the collision body
collisionBody->CollisionBody::~CollisionBody();
// Remove the collision body from the list of bodies
bodies.erase(collisionBody); // TOOD : Maybe use a set to make this faster
// Free the object from the memory pool
memoryPoolCollisionBodies.freeObject(collisionBody);
}
// Return the next available body ID
bodyindex CollisionWorld::computeNextAvailableBodyID() {
// Compute the body ID // Compute the body ID
bodyindex bodyID; bodyindex bodyID;
if (!freeRigidBodyIDs.empty()) { if (!freeBodiesIDs.empty()) {
bodyID = freeRigidBodyIDs.back(); bodyID = freeBodiesIDs.back();
freeRigidBodyIDs.pop_back(); freeBodiesIDs.pop_back();
} }
else { else {
bodyID = currentBodyID; bodyID = currentBodyID;
currentBodyID++; currentBodyID++;
} }
// Largest index cannot be used (it is used for invalid index) return bodyID;
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
// Create the rigid body
RigidBody* rigidBody = new (memoryPoolRigidBodies.allocateObject()) RigidBody(transform, mass, inertiaTensorLocal, collisionShape, bodyID);
// Add the rigid body to the physics world
bodies.insert(rigidBody);
rigidBodies.insert(rigidBody);
// Add the rigid body to the collision detection
collisionDetection->addBody(rigidBody);
// Return the pointer to the rigid body
return rigidBody;
}
// Destroy a rigid body
void PhysicsWorld::destroyRigidBody(RigidBody* rigidBody) {
// Remove the body from the collision detection
collisionDetection->removeBody(rigidBody);
// Add the body ID to the list of free IDs
freeRigidBodyIDs.push_back(rigidBody->getID());
// Call the constructor of the rigid body
rigidBody->RigidBody::~RigidBody();
// Remove the rigid body from the list of rigid bodies
bodies.erase(rigidBody); // TOOD : Maybe use a set to make this faster
rigidBodies.erase(rigidBody); // TOOD : Maybe use a set to make this faster
// Free the object from the memory pool
memoryPoolRigidBodies.freeObject(rigidBody);
}
// Remove all collision contacts constraints
// TODO : This method should be in the collision detection class
void PhysicsWorld::removeAllContactConstraints() {
// For all constraints
for (vector<Constraint*>::iterator it = constraints.begin(); it != constraints.end(); ) {
// Try a downcasting
Contact* contact = dynamic_cast<Contact*>(*it);
// If the constraint is a contact
if (contact) {
// Remove it from the constraints of the physics world
it = constraints.erase(it);
}
else {
++it;
}
}
} }
// Remove all constraints in the physics world
void PhysicsWorld::removeAllConstraints() {
constraints.clear();
}

View File

@ -0,0 +1,93 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010-2012 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef COLLISION_WORLD_H
#define COLLISION_WORLD_H
// Libraries
#include <vector>
#include <set>
#include <algorithm>
#include "../mathematics/mathematics.h"
#include "../body/CollisionBody.h"
#include "OverlappingPair.h"
#include "../collision/CollisionDetection.h"
#include "../constraint/Constraint.h"
#include "../constraint/Contact.h"
#include "../memory/MemoryPool.h"
// Namespace reactphysics3d
namespace reactphysics3d {
/* -------------------------------------------------------------------
Class CollisionWorld :
This class represent a world where it is possible to move bodies
by hand and to test collision between each other. In this kind of
world, the bodies movement is not computed using the laws of physics.
-------------------------------------------------------------------
*/
class CollisionWorld {
protected :
CollisionDetection collisionDetection; // Reference to the collision detection
std::set<CollisionBody*> bodies; // All the bodies (rigid and soft) of the physics world
std::map<std::pair<bodyindex, bodyindex>, OverlappingPair*> overlappingPairs; // Broad-phase overlapping pairs of bodies
bodyindex currentBodyID; // Current body ID
MemoryPool<CollisionBody> memoryPoolCollisionBodies; // Memory pool for rigid bodies memory allocation
std::vector<luint> freeBodiesIDs; // List of free ID for rigid bodies
virtual void notifyAddedOverlappingPair(const BroadPhasePair* addedPair); // Notify the world about a new broad-phase overlapping pair
virtual void notifyRemovedOverlappingPair(const BroadPhasePair* removedPair); // Notify the world about a removed broad-phase overlapping pair
virtual void notifyNewContact(const BroadPhasePair* pair, const ContactInfo* contactInfo); // Notify the world about a new narrow-phase contact
virtual void updateOverlappingPair(const BroadPhasePair* pair); // Update the overlapping pair
bodyindex computeNextAvailableBodyID(); // Return the next available body ID
public :
CollisionWorld(); // Constructor
virtual ~CollisionWorld(); // Destructor
std::set<CollisionBody*>::iterator getBodiesBeginIterator(); // Return an iterator to the beginning of the bodies of the physics world
std::set<CollisionBody*>::iterator getBodiesEndIterator(); // Return an iterator to the end of the bodies of the physics world
CollisionBody* createCollisionBody(const Transform& transform,
CollisionShape* collisionShape); // Create a collision body
void destroyCollisionBody(CollisionBody* collisionBody); // Destroy a collision body
// Friends
friend class CollisionDetection;
};
// Return an iterator to the beginning of the bodies of the physics world
inline std::set<CollisionBody*>::iterator CollisionWorld::getBodiesBeginIterator() {
return bodies.begin();
}
// Return an iterator to the end of the bodies of the physics world
inline std::set<CollisionBody*>::iterator CollisionWorld::getBodiesEndIterator() {
return bodies.end();
}
} // End of the ReactPhysics3D namespace
#endif

View File

@ -25,6 +25,7 @@
// Libraries // Libraries
#include "ConstraintSolver.h" #include "ConstraintSolver.h"
#include "DynamicsWorld.h"
#include "../body/RigidBody.h" #include "../body/RigidBody.h"
using namespace reactphysics3d; using namespace reactphysics3d;
@ -32,8 +33,8 @@ using namespace std;
// Constructor // Constructor
ConstraintSolver::ConstraintSolver(PhysicsWorld* world) ConstraintSolver::ConstraintSolver(DynamicsWorld* world)
:physicsWorld(world), nbConstraints(0), nbIterationsLCP(DEFAULT_LCP_ITERATIONS), :world(world), nbConstraints(0), nbIterationsLCP(DEFAULT_LCP_ITERATIONS),
nbIterationsLCPErrorCorrection(DEFAULT_LCP_ITERATIONS_ERROR_CORRECTION), nbIterationsLCPErrorCorrection(DEFAULT_LCP_ITERATIONS_ERROR_CORRECTION),
isErrorCorrectionActive(false) { isErrorCorrectionActive(false) {
@ -53,7 +54,7 @@ void ConstraintSolver::initialize() {
// For each constraint // For each constraint
vector<Constraint*>::iterator it; vector<Constraint*>::iterator it;
for (it = physicsWorld->getConstraintsBeginIterator(); it != physicsWorld->getConstraintsEndIterator(); ++it) { for (it = world->getConstraintsBeginIterator(); it != world->getConstraintsEndIterator(); ++it) {
constraint = *it; constraint = *it;
// If the constraint is active // If the constraint is active

View File

@ -29,12 +29,14 @@
// Libraries // Libraries
#include "../configuration.h" #include "../configuration.h"
#include "../constraint/Constraint.h" #include "../constraint/Constraint.h"
#include "PhysicsWorld.h"
#include <map> #include <map>
#include <set> #include <set>
// ReactPhysics3D namespace // ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
// Declarations
class DynamicsWorld;
/* ------------------------------------------------------------------- /* -------------------------------------------------------------------
@ -64,7 +66,7 @@ namespace reactphysics3d {
*/ */
class ConstraintSolver { class ConstraintSolver {
private: private:
PhysicsWorld* physicsWorld; // Reference to the physics world DynamicsWorld* world; // Reference to the world
std::vector<Constraint*> activeConstraints; // Current active constraints in the physics world std::vector<Constraint*> activeConstraints; // Current active constraints in the physics world
bool isErrorCorrectionActive; // True if error correction (with world order) is active bool isErrorCorrectionActive; // True if error correction (with world order) is active
uint nbIterationsLCP; // Number of iterations of the LCP solver uint nbIterationsLCP; // Number of iterations of the LCP solver
@ -125,7 +127,7 @@ class ConstraintSolver {
void solveLCPErrorCorrection(); // Solve the LCP problem for error correction projection void solveLCPErrorCorrection(); // Solve the LCP problem for error correction projection
public: public:
ConstraintSolver(PhysicsWorld* world); // Constructor ConstraintSolver(DynamicsWorld* world); // Constructor
virtual ~ConstraintSolver(); // Destructor virtual ~ConstraintSolver(); // Destructor
void solve(decimal dt); // Solve the current LCP problem void solve(decimal dt); // Solve the current LCP problem
bool isConstrainedBody(Body* body) const; // Return true if the body is in at least one constraint bool isConstrainedBody(Body* body) const; // Return true if the body is in at least one constraint
@ -232,4 +234,4 @@ inline void ConstraintSolver::solve(decimal dt) {
} // End of ReactPhysics3D namespace } // End of ReactPhysics3D namespace
#endif #endif

View File

@ -24,28 +24,32 @@
********************************************************************************/ ********************************************************************************/
// Libraries // Libraries
#include "PhysicsEngine.h" #include "DynamicsWorld.h"
// We want to use the ReactPhysics3D namespace // We want to use the ReactPhysics3D namespace
using namespace reactphysics3d; using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
PhysicsEngine::PhysicsEngine(PhysicsWorld* world, decimal timeStep = DEFAULT_TIMESTEP) DynamicsWorld::DynamicsWorld(const Vector3 &gravity, decimal timeStep = DEFAULT_TIMESTEP)
: world(world), collisionDetection(world), timer(timeStep), constraintSolver(world), : CollisionWorld(), timer(timeStep), gravity(gravity), isGravityOn(true), constraintSolver(this),
isDeactivationActive(DEACTIVATION_ENABLED) { isDeactivationActive(DEACTIVATION_ENABLED) {
assert(world);
assert(timeStep > 0.0);
world->setCollisionDetection(&collisionDetection);
} }
// Destructor // Destructor
PhysicsEngine::~PhysicsEngine() { DynamicsWorld::~DynamicsWorld() {
// Delete the remaining overlapping pairs
for (map<std::pair<bodyindex, bodyindex>, OverlappingPair*>::iterator it=overlappingPairs.begin(); it != overlappingPairs.end(); it++) {
// Delete the overlapping pair
(*it).second->OverlappingPair::~OverlappingPair();
memoryPoolOverlappingPairs.freeObject((*it).second);
}
} }
// Update the physics simulation // Update the physics simulation
void PhysicsEngine::update() { void DynamicsWorld::update() {
bool existCollision = false; bool existCollision = false;
assert(timer.getIsRunning()); assert(timer.getIsRunning());
@ -58,7 +62,10 @@ void PhysicsEngine::update() {
// While the time accumulator is not empty // While the time accumulator is not empty
while(timer.isPossibleToTakeStep()) { while(timer.isPossibleToTakeStep()) {
existCollision = false; existCollision = false;
removeAllContactConstraints();
// Compute the collision detection // Compute the collision detection
if (collisionDetection.computeCollisionDetection()) { if (collisionDetection.computeCollisionDetection()) {
@ -96,7 +103,7 @@ void PhysicsEngine::update() {
// and orientation of each body. // and orientation of each body.
// This method uses the semi-implicit Euler method to update the position and // This method uses the semi-implicit Euler method to update the position and
// orientation of the body // orientation of the body
void PhysicsEngine::updateAllBodiesMotion() { void DynamicsWorld::updateAllBodiesMotion() {
decimal dt = timer.getTimeStep(); decimal dt = timer.getTimeStep();
Vector3 newLinearVelocity; Vector3 newLinearVelocity;
Vector3 newAngularVelocity; Vector3 newAngularVelocity;
@ -104,7 +111,7 @@ void PhysicsEngine::updateAllBodiesMotion() {
Vector3 angularVelocityErrorCorrection; Vector3 angularVelocityErrorCorrection;
// For each body of thephysics world // For each body of thephysics world
for (set<RigidBody*>::iterator it=world->getRigidBodiesBeginIterator(); it != world->getRigidBodiesEndIterator(); ++it) { for (set<RigidBody*>::iterator it=getRigidBodiesBeginIterator(); it != getRigidBodiesEndIterator(); ++it) {
RigidBody* rigidBody = *it; RigidBody* rigidBody = *it;
assert(rigidBody); assert(rigidBody);
@ -148,7 +155,7 @@ void PhysicsEngine::updateAllBodiesMotion() {
// Update the position and orientation of a body // Update the position and orientation of a body
// Use the Semi-Implicit Euler (Sympletic Euler) method to compute the new position and the new // Use the Semi-Implicit Euler (Sympletic Euler) method to compute the new position and the new
// orientation of the body // orientation of the body
void PhysicsEngine::updatePositionAndOrientationOfBody(RigidBody* rigidBody, const Vector3& newLinVelocity, const Vector3& newAngVelocity, void DynamicsWorld::updatePositionAndOrientationOfBody(RigidBody* rigidBody, const Vector3& newLinVelocity, const Vector3& newAngVelocity,
const Vector3& linearVelocityErrorCorrection, const Vector3& angularVelocityErrorCorrection) { const Vector3& linearVelocityErrorCorrection, const Vector3& angularVelocityErrorCorrection) {
decimal dt = timer.getTimeStep(); decimal dt = timer.getTimeStep();
@ -177,14 +184,14 @@ void PhysicsEngine::updatePositionAndOrientationOfBody(RigidBody* rigidBody, con
} }
// Compute and set the interpolation factor to all bodies // Compute and set the interpolation factor to all bodies
void PhysicsEngine::setInterpolationFactorToAllBodies() { void DynamicsWorld::setInterpolationFactorToAllBodies() {
// Compute the interpolation factor // Compute the interpolation factor
decimal factor = timer.computeInterpolationFactor(); decimal factor = timer.computeInterpolationFactor();
assert(factor >= 0.0 && factor <= 1.0); assert(factor >= 0.0 && factor <= 1.0);
// Set the factor to all bodies // Set the factor to all bodies
for (set<RigidBody*>::iterator it=world->getRigidBodiesBeginIterator(); it != world->getRigidBodiesEndIterator(); ++it) { for (set<RigidBody*>::iterator it=getRigidBodiesBeginIterator(); it != getRigidBodiesEndIterator(); ++it) {
RigidBody* rigidBody = dynamic_cast<RigidBody*>(*it); RigidBody* rigidBody = dynamic_cast<RigidBody*>(*it);
assert(rigidBody); assert(rigidBody);
@ -194,18 +201,140 @@ void PhysicsEngine::setInterpolationFactorToAllBodies() {
} }
// Apply the gravity force to all bodies of the physics world // Apply the gravity force to all bodies of the physics world
void PhysicsEngine::applyGravity() { void DynamicsWorld::applyGravity() {
// For each body of the physics world // For each body of the physics world
for (set<RigidBody*>::iterator it=world->getRigidBodiesBeginIterator(); it != world->getRigidBodiesEndIterator(); ++it) { for (set<RigidBody*>::iterator it=getRigidBodiesBeginIterator(); it != getRigidBodiesEndIterator(); ++it) {
RigidBody* rigidBody = dynamic_cast<RigidBody*>(*it); RigidBody* rigidBody = dynamic_cast<RigidBody*>(*it);
assert(rigidBody); assert(rigidBody);
// If the gravity force is on // If the gravity force is on
if(world->getIsGravityOn()) { if(isGravityOn) {
// Apply the current gravity force to the body // Apply the current gravity force to the body
rigidBody->setExternalForce(rigidBody->getMass() * world->getGravity()); rigidBody->setExternalForce(rigidBody->getMass() * gravity);
} }
} }
} }
// Create a rigid body into the physics world
RigidBody* DynamicsWorld::createRigidBody(const Transform& transform, decimal mass,
const Matrix3x3& inertiaTensorLocal,
CollisionShape* collisionShape) {
// Compute the body ID
bodyindex bodyID = computeNextAvailableBodyID();
// Largest index cannot be used (it is used for invalid index)
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
// Create the rigid body
RigidBody* rigidBody = new (memoryPoolRigidBodies.allocateObject()) RigidBody(transform, mass, inertiaTensorLocal, collisionShape, bodyID);
// Add the rigid body to the physics world
bodies.insert(rigidBody);
rigidBodies.insert(rigidBody);
// Add the rigid body to the collision detection
collisionDetection.addBody(rigidBody);
// Return the pointer to the rigid body
return rigidBody;
}
// Destroy a rigid body
void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) {
// Remove the body from the collision detection
collisionDetection.removeBody(rigidBody);
// Add the body ID to the list of free IDs
freeBodiesIDs.push_back(rigidBody->getID());
// Call the constructor of the rigid body
rigidBody->RigidBody::~RigidBody();
// Remove the rigid body from the list of rigid bodies
bodies.erase(rigidBody); // TOOD : Maybe use a set to make this faster
rigidBodies.erase(rigidBody); // TOOD : Maybe use a set to make this faster
// Free the object from the memory pool
memoryPoolRigidBodies.freeObject(rigidBody);
}
// Remove all collision contacts constraints
// TODO : This method should be in the collision detection class
void DynamicsWorld::removeAllContactConstraints() {
// For all constraints
for (vector<Constraint*>::iterator it = constraints.begin(); it != constraints.end(); ) {
// Try a downcasting
Contact* contact = dynamic_cast<Contact*>(*it);
// If the constraint is a contact
if (contact) {
// Remove it from the constraints of the physics world
it = constraints.erase(it);
}
else {
++it;
}
}
}
// Remove all constraints in the physics world
void DynamicsWorld::removeAllConstraints() {
constraints.clear();
}
// Notify the world about a new broad-phase overlapping pair
void DynamicsWorld::notifyAddedOverlappingPair(const BroadPhasePair* addedPair) {
// Get the pair of body index
std::pair<bodyindex, bodyindex> indexPair = addedPair->getBodiesIndexPair();
// Add the pair into the set of overlapping pairs (if not there yet)
OverlappingPair* newPair = new (memoryPoolOverlappingPairs.allocateObject()) OverlappingPair(addedPair->body1, addedPair->body2, memoryPoolContacts);
std::pair<map<std::pair<bodyindex, bodyindex>, OverlappingPair*>::iterator, bool> check = overlappingPairs.insert(make_pair(indexPair, newPair));
assert(check.second);
}
// Notify the world about a removed broad-phase overlapping pair
void DynamicsWorld::notifyRemovedOverlappingPair(const BroadPhasePair* removedPair) {
// Get the pair of body index
std::pair<bodyindex, bodyindex> indexPair = removedPair->getBodiesIndexPair();
// Remove the overlapping pair from the memory pool
overlappingPairs[indexPair]->OverlappingPair::~OverlappingPair();
memoryPoolOverlappingPairs.freeObject(overlappingPairs[indexPair]);
overlappingPairs.erase(indexPair);
}
// Notify the world about a new narrow-phase contact
void DynamicsWorld::notifyNewContact(const BroadPhasePair* broadPhasePair, const ContactInfo* contactInfo) {
RigidBody* const rigidBody1 = dynamic_cast<RigidBody* const>(broadPhasePair->body1);
RigidBody* const rigidBody2 = dynamic_cast<RigidBody* const>(broadPhasePair->body2);
assert(rigidBody1);
assert(rigidBody2);
// Create a new contact
Contact* contact = new (memoryPoolContacts.allocateObject()) Contact(rigidBody1, rigidBody2, contactInfo);
assert(contact);
// Get the corresponding overlapping pair
pair<bodyindex, bodyindex> indexPair = broadPhasePair->getBodiesIndexPair();
OverlappingPair* overlappingPair = overlappingPairs[indexPair];
assert(overlappingPair);
// Add the contact to the contact cache of the corresponding overlapping pair
overlappingPair->addContact(contact);
// Add all the contacts in the contact cache of the two bodies
// to the set of constraints in the physics world
for (uint i=0; i<overlappingPair->getNbContacts(); i++) {
addConstraint(overlappingPair->getContact(i));
}
}

200
src/engine/DynamicsWorld.h Normal file
View File

@ -0,0 +1,200 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010-2012 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef DYNAMICS_WORLD_H
#define DYNAMICS_WORLD_H
// Libraries
#include "CollisionWorld.h"
#include "../collision/CollisionDetection.h"
#include "ConstraintSolver.h"
#include "../body/RigidBody.h"
#include "Timer.h"
#include "../configuration.h"
// Namespace ReactPhysics3D
namespace reactphysics3d {
/* -------------------------------------------------------------------
Class DynamicsWorld :
This class represents a dynamics world. This class inherits from
the CollisionWorld class. In a dynamics world, bodies can collide
and their movements are simulated using the laws of physics.
-------------------------------------------------------------------
*/
class DynamicsWorld : public CollisionWorld {
protected :
Timer timer; // Timer of the physics engine
ConstraintSolver constraintSolver; // Constraint solver
bool isDeactivationActive; // True if the deactivation (sleeping) of inactive bodies is enabled
std::set<RigidBody*> rigidBodies; // All the rigid bodies of the physics world
std::vector<Constraint*> constraints; // List that contains all the current constraints
Vector3 gravity; // Gravity vector of the world
bool isGravityOn; // True if the gravity force is on
MemoryPool<OverlappingPair> memoryPoolOverlappingPairs; // Memory pool for the overlapping pairs
MemoryPool<RigidBody> memoryPoolRigidBodies; // Memory pool for rigid bodies memory allocation
MemoryPool<Contact> memoryPoolContacts; // Memory pool for the contacts
void updateAllBodiesMotion(); // Compute the motion of all bodies and update their positions and orientations
void updatePositionAndOrientationOfBody(RigidBody* body, const Vector3& newLinVelocity, const Vector3& newAngVelocity,
const Vector3& linearVelocityErrorCorrection, const Vector3& angularVelocityErrorCorrection); // Update the position and orientation of a body
void setInterpolationFactorToAllBodies(); // Compute and set the interpolation factor to all bodies
void applyGravity(); // Apply the gravity force to all bodies
void resetBodiesMovementVariable(); // Reset the boolean movement variable of each body
virtual void updateOverlappingPair(const BroadPhasePair* pair); // Update the overlapping pair
virtual void notifyAddedOverlappingPair(const BroadPhasePair* addedPair); // Notify the world about a new broad-phase overlapping pair
virtual void notifyRemovedOverlappingPair(const BroadPhasePair* removedPair); // Notify the world about a removed broad-phase overlapping pair
virtual void notifyNewContact(const BroadPhasePair* pair,
const ContactInfo* contactInfo); // Notify the world about a new narrow-phase contact
public :
DynamicsWorld(const Vector3& gravity, decimal timeStep); // Constructor
virtual ~DynamicsWorld(); // Destructor
Timer& getTimer() {return timer;}
void start(); // Start the physics simulation
void stop(); // Stop the physics simulation
void update(); // Update the physics simulation
void setNbLCPIterations(uint nbIterations); // Set the number of iterations of the LCP solver
void setIsErrorCorrectionActive(bool isErrorCorrectionActive); // Set the isErrorCorrectionActive value
RigidBody* createRigidBody(const Transform& transform, decimal mass,
const Matrix3x3& inertiaTensorLocal, CollisionShape* collisionShape); // Create a rigid body into the physics world
void destroyRigidBody(RigidBody* rigidBody); // Destroy a rigid body
Vector3 getGravity() const; // Return the gravity vector of the world
bool getIsGravityOn() const; // Return if the gravity is on
void setIsGratityOn(bool isGravityOn); // Set the isGravityOn attribute
void addConstraint(Constraint* constraint); // Add a constraint
void removeConstraint(Constraint* constraint); // Remove a constraint
void removeAllContactConstraints(); // Remove all collision contacts constraints
void removeAllConstraints(); // Remove all constraints and delete them (free their memory)
std::vector<Constraint*>::iterator getConstraintsBeginIterator(); // Return a start iterator on the constraint list
std::vector<Constraint*>::iterator getConstraintsEndIterator(); // Return a end iterator on the constraint list
std::set<RigidBody*>::iterator getRigidBodiesBeginIterator(); // Return an iterator to the beginning of the rigid bodies of the physics world
std::set<RigidBody*>::iterator getRigidBodiesEndIterator(); // Return an iterator to the end of the rigid bodies of the physics world
};
// --- Inline functions --- //
// Start the physics simulation
inline void DynamicsWorld::start() {
timer.start();
}
inline void DynamicsWorld::stop() {
std::cout << "Stop Simulation" << std::endl;
timer.stop();
}
// Set the number of iterations of the LCP solver
inline void DynamicsWorld::setNbLCPIterations(uint nbIterations) {
constraintSolver.setNbLCPIterations(nbIterations);
}
// Set the isErrorCorrectionActive value
inline void DynamicsWorld::setIsErrorCorrectionActive(bool isErrorCorrectionActive) {
constraintSolver.setIsErrorCorrectionActive(isErrorCorrectionActive);
}
// Reset the boolean movement variable of each body
inline void DynamicsWorld::resetBodiesMovementVariable() {
// For each rigid body
for (std::set<RigidBody*>::iterator it = getRigidBodiesBeginIterator(); it != getRigidBodiesEndIterator(); it++) {
// Set the hasMoved variable to false
(*it)->setHasMoved(false);
}
}
// Update the overlapping pair
inline void DynamicsWorld::updateOverlappingPair(const BroadPhasePair* pair) {
// Get the pair of body index
std::pair<bodyindex, bodyindex> indexPair = pair->getBodiesIndexPair();
// Get the corresponding overlapping pair
OverlappingPair* overlappingPair = overlappingPairs[indexPair];
// Update the contact cache of the overlapping pair
overlappingPair->update();
}
// Add a constraint into the physics world
inline void DynamicsWorld::addConstraint(Constraint* constraint) {
assert(constraint != 0);
constraints.push_back(constraint);
}
// Remove a constraint and free its memory
inline void DynamicsWorld::removeConstraint(Constraint* constraint) {
std::vector<Constraint*>::iterator it;
assert(constraint);
it = std::find(constraints.begin(), constraints.end(), constraint);
assert(*it == constraint);
delete *it;
constraints.erase(it);
}
// Return the gravity vector of the world
inline Vector3 DynamicsWorld::getGravity() const {
return gravity;
}
// Return if the gravity is on
inline bool DynamicsWorld::getIsGravityOn() const {
return isGravityOn;
}
// Set the isGravityOn attribute
inline void DynamicsWorld::setIsGratityOn(bool isGravityOn) {
this->isGravityOn = isGravityOn;
}
// Return an iterator to the beginning of the bodies of the physics world
inline std::set<RigidBody*>::iterator DynamicsWorld::getRigidBodiesBeginIterator() {
return rigidBodies.begin();
}
// Return an iterator to the end of the bodies of the physics world
inline std::set<RigidBody*>::iterator DynamicsWorld::getRigidBodiesEndIterator() {
return rigidBodies.end();
}
// Return a start iterator on the constraint list
inline std::vector<Constraint*>::iterator DynamicsWorld::getConstraintsBeginIterator() {
return constraints.begin();
}
// Return a end iterator on the constraint list
inline std::vector<Constraint*>::iterator DynamicsWorld::getConstraintsEndIterator() {
return constraints.end();
}
}
#endif

View File

@ -30,7 +30,7 @@ using namespace reactphysics3d;
// Constructor // Constructor
OverlappingPair::OverlappingPair(Body* body1, Body* body2, MemoryPool<Contact>& memoryPoolContacts) OverlappingPair::OverlappingPair(CollisionBody* body1, CollisionBody* body2, MemoryPool<Contact>& memoryPoolContacts)
: body1(body1), body2(body2), contactsCache(body1, body2, memoryPoolContacts), cachedSeparatingAxis(1.0, 1.0, 1.0) { : body1(body1), body2(body2), contactsCache(body1, body2, memoryPoolContacts), cachedSeparatingAxis(1.0, 1.0, 1.0) {
} }

View File

@ -43,17 +43,17 @@ namespace reactphysics3d {
*/ */
class OverlappingPair { class OverlappingPair {
private: private:
Body* const body1; // Pointer to the first body of the contact CollisionBody* const body1; // Pointer to the first body of the contact
Body* const body2; // Pointer to the second body of the contact CollisionBody* const body2; // Pointer to the second body of the contact
PersistentContactCache contactsCache; // Persistent contact cache PersistentContactCache contactsCache; // Persistent contact cache
Vector3 cachedSeparatingAxis; // Cached previous separating axis Vector3 cachedSeparatingAxis; // Cached previous separating axis
public: public:
OverlappingPair(Body* body1, Body* body2, MemoryPool<Contact>& memoryPoolContacts); // Constructor OverlappingPair(CollisionBody* body1, CollisionBody* body2, MemoryPool<Contact>& memoryPoolContacts); // Constructor
~OverlappingPair(); // Destructor ~OverlappingPair(); // Destructor
Body* const getBody1() const; // Return the pointer to first body CollisionBody* const getBody1() const; // Return the pointer to first body
Body* const getBody2() const; // Return the pointer to second body CollisionBody* const getBody2() const; // Return the pointer to second body
void addContact(Contact* contact); // Add a contact to the contact cache void addContact(Contact* contact); // Add a contact to the contact cache
void update(); // Update the contact cache void update(); // Update the contact cache
Vector3 getCachedSeparatingAxis() const; // Return the cached separating axis Vector3 getCachedSeparatingAxis() const; // Return the cached separating axis
@ -63,12 +63,12 @@ class OverlappingPair {
}; };
// Return the pointer to first body // Return the pointer to first body
inline Body* const OverlappingPair::getBody1() const { inline CollisionBody* const OverlappingPair::getBody1() const {
return body1; return body1;
} }
// Return the pointer to second body // Return the pointer to second body
inline Body* const OverlappingPair::getBody2() const { inline CollisionBody* const OverlappingPair::getBody2() const {
return body2; return body2;
} }

View File

@ -1,107 +0,0 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010-2012 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef PHYSICS_ENGINE_H
#define PHYSICS_ENGINE_H
// Libraries
#include "PhysicsWorld.h"
#include "../collision/CollisionDetection.h"
#include "ConstraintSolver.h"
#include "../body/RigidBody.h"
#include "Timer.h"
#include "../configuration.h"
// Namespace ReactPhysics3D
namespace reactphysics3d {
/* -------------------------------------------------------------------
Class PhysicsEngine :
This class represents the physics engine
of the library.
-------------------------------------------------------------------
*/
class PhysicsEngine {
private :
PhysicsWorld* world; // Pointer to the physics world of the physics engine
Timer timer; // Timer of the physics engine
CollisionDetection collisionDetection; // Collision detection
ConstraintSolver constraintSolver; // Constraint solver
bool isDeactivationActive; // True if the deactivation (sleeping) of inactive bodies is enabled
void updateAllBodiesMotion(); // Compute the motion of all bodies and update their positions and orientations
void updatePositionAndOrientationOfBody(RigidBody* body, const Vector3& newLinVelocity, const Vector3& newAngVelocity,
const Vector3& linearVelocityErrorCorrection, const Vector3& angularVelocityErrorCorrection); // Update the position and orientation of a body
void setInterpolationFactorToAllBodies(); // Compute and set the interpolation factor to all bodies
void applyGravity(); // Apply the gravity force to all bodies
void resetBodiesMovementVariable(); // Reset the boolean movement variable of each body
public :
PhysicsEngine(PhysicsWorld* world, decimal timeStep); // Constructor
~PhysicsEngine(); // Destructor
void start(); // Start the physics simulation
void stop(); // Stop the physics simulation
void update(); // Update the physics simulation
void setNbLCPIterations(uint nbIterations); // Set the number of iterations of the LCP solver
void setIsErrorCorrectionActive(bool isErrorCorrectionActive); // Set the isErrorCorrectionActive value
};
// --- Inline functions --- //
// Start the physics simulation
inline void PhysicsEngine::start() {
timer.start();
}
inline void PhysicsEngine::stop() {
timer.stop();
}
// Set the number of iterations of the LCP solver
inline void PhysicsEngine::setNbLCPIterations(uint nbIterations) {
constraintSolver.setNbLCPIterations(nbIterations);
}
// Set the isErrorCorrectionActive value
inline void PhysicsEngine::setIsErrorCorrectionActive(bool isErrorCorrectionActive) {
constraintSolver.setIsErrorCorrectionActive(isErrorCorrectionActive);
}
// Reset the boolean movement variable of each body
inline void PhysicsEngine::resetBodiesMovementVariable() {
// For each rigid body
for (std::set<RigidBody*>::iterator it = world->getRigidBodiesBeginIterator(); it != world->getRigidBodiesEndIterator(); it++) {
// Set the hasMoved variable to false
(*it)->setHasMoved(false);
}
}
}
#endif

View File

@ -1,155 +0,0 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010-2012 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef PHYSICS_WORLD_H
#define PHYSICS_WORLD_H
// Libraries
#include <vector>
#include <set>
#include <algorithm>
#include "../mathematics/mathematics.h"
#include "../body/Body.h"
#include "../collision/CollisionDetection.h"
#include "../constraint/Constraint.h"
#include "../constraint/Contact.h"
#include "../memory/MemoryPool.h"
// Namespace reactphysics3d
namespace reactphysics3d {
/* -------------------------------------------------------------------
Class PhysicsWorld :
This class represents the world of the
physics engine. The physics world contains all the bodies of the physics
engine.
-------------------------------------------------------------------
*/
class PhysicsWorld {
protected :
CollisionDetection* collisionDetection; // Reference to the collision detection
std::set<Body*> bodies; // All the bodies (rigid and soft) of the physics world
std::set<RigidBody*> rigidBodies; // All the rigid bodies of the physics world
std::vector<luint> freeRigidBodyIDs; // List of free ID for rigid bodies
std::vector<Constraint*> constraints; // List that contains all the current constraints
Vector3 gravity; // Gravity vector of the world
bool isGravityOn; // True if the gravity force is on
bodyindex currentBodyID; // Current body ID
MemoryPool<RigidBody> memoryPoolRigidBodies; // Memory pool for rigid bodies memory allocation
public :
PhysicsWorld(const Vector3& gravity); // Constructor
virtual ~PhysicsWorld(); // Destructor
RigidBody* createRigidBody(const Transform& transform, decimal mass,
const Matrix3x3& inertiaTensorLocal, CollisionShape* collisionShape); // Create a rigid body into the physics world
void destroyRigidBody(RigidBody* rigidBody); // Destroy a rigid body
Vector3 getGravity() const; // Return the gravity vector of the world
bool getIsGravityOn() const; // Return if the gravity is on
void setIsGratityOn(bool isGravityOn); // Set the isGravityOn attribute
void setCollisionDetection(CollisionDetection* collisionDetection); // Set the collision detection reference
void addConstraint(Constraint* constraint); // Add a constraint
void removeConstraint(Constraint* constraint); // Remove a constraint
void removeAllContactConstraints(); // Remove all collision contacts constraints
void removeAllConstraints(); // Remove all constraints and delete them (free their memory)
std::vector<Constraint*>::iterator getConstraintsBeginIterator(); // Return a start iterator on the constraint list
std::vector<Constraint*>::iterator getConstraintsEndIterator(); // Return a end iterator on the constraint list
std::set<Body*>::iterator getBodiesBeginIterator(); // Return an iterator to the beginning of the bodies of the physics world
std::set<Body*>::iterator getBodiesEndIterator(); // Return an iterator to the end of the bodies of the physics world
std::set<RigidBody*>::iterator getRigidBodiesBeginIterator(); // Return an iterator to the beginning of the rigid bodies of the physics world
std::set<RigidBody*>::iterator getRigidBodiesEndIterator(); // Return an iterator to the end of the rigid bodies of the physics world
};
// Add a constraint into the physics world
inline void PhysicsWorld::addConstraint(Constraint* constraint) {
assert(constraint != 0);
constraints.push_back(constraint);
}
// Remove a constraint and free its memory
inline void PhysicsWorld::removeConstraint(Constraint* constraint) {
std::vector<Constraint*>::iterator it;
assert(constraint);
it = std::find(constraints.begin(), constraints.end(), constraint);
assert(*it == constraint);
delete *it;
constraints.erase(it);
}
// Return the gravity vector of the world
inline Vector3 PhysicsWorld::getGravity() const {
return gravity;
}
// Return if the gravity is on
inline bool PhysicsWorld::getIsGravityOn() const {
return isGravityOn;
}
// Set the isGravityOn attribute
inline void PhysicsWorld::setIsGratityOn(bool isGravityOn) {
this->isGravityOn = isGravityOn;
}
// Set the collision detection reference
inline void PhysicsWorld::setCollisionDetection(CollisionDetection* collisionDetection) {
this->collisionDetection = collisionDetection;
}
// Return a start iterator on the constraint list
inline std::vector<Constraint*>::iterator PhysicsWorld::getConstraintsBeginIterator() {
return constraints.begin();
}
// Return a end iterator on the constraint list
inline std::vector<Constraint*>::iterator PhysicsWorld::getConstraintsEndIterator() {
return constraints.end();
}
// Return an iterator to the beginning of the bodies of the physics world
inline std::set<Body*>::iterator PhysicsWorld::getBodiesBeginIterator() {
return bodies.begin();
}
// Return an iterator to the end of the bodies of the physics world
inline std::set<Body*>::iterator PhysicsWorld::getBodiesEndIterator() {
return bodies.end();
}
// Return an iterator to the beginning of the bodies of the physics world
inline std::set<RigidBody*>::iterator PhysicsWorld::getRigidBodiesBeginIterator() {
return rigidBodies.begin();
}
// Return an iterator to the end of the bodies of the physics world
inline std::set<RigidBody*>::iterator PhysicsWorld::getRigidBodiesEndIterator() {
return rigidBodies.end();
}
} // End of the ReactPhysics3D namespace
#endif

View File

@ -126,6 +126,7 @@ inline void Timer::start() {
// Stop the timer // Stop the timer
inline void Timer::stop() { inline void Timer::stop() {
std::cout << "Timer stop" << std::endl;
isRunning = false; isRunning = false;
} }

View File

@ -65,8 +65,8 @@ class MemoryPool {
static const uint NB_OBJECTS_FIRST_BLOCK; // Number of objects allocated in the first block static const uint NB_OBJECTS_FIRST_BLOCK; // Number of objects allocated in the first block
void* pBlocks; // Pointer to the first allocated memory block void* pBlocks; // Pointer to the first allocated memory block
struct MemoryUnit* pAllocatedUnits; // Pointer to the first allocated memory unit MemoryUnit* pAllocatedUnits; // Pointer to the first allocated memory unit
struct MemoryUnit* pFreeUnits; // Pointer to the first free memory unit MemoryUnit* pFreeUnits; // Pointer to the first free memory unit
uint currentNbObjects; // Current number of objects in the pool uint currentNbObjects; // Current number of objects in the pool
uint capacity; // Current maximum number of objects that can be allocated in the pool uint capacity; // Current maximum number of objects that can be allocated in the pool
uint nbObjectsNextBlock; // Number of objects to allocate in the next block uint nbObjectsNextBlock; // Number of objects to allocate in the next block
@ -110,8 +110,8 @@ MemoryPool<T>::~MemoryPool() {
assert(currentNbObjects == 0); assert(currentNbObjects == 0);
// Release all the allocated memory blocks // Release all the allocated memory blocks
struct MemoryBlock* currentBlock = (struct MemoryBlock*) pBlocks; MemoryBlock* currentBlock = (MemoryBlock*) pBlocks;
while(currentBlock != 0) { while(currentBlock) {
MemoryBlock* tempBlock = currentBlock->pNext; MemoryBlock* tempBlock = currentBlock->pNext;
free(currentBlock); free(currentBlock);
currentBlock = tempBlock; currentBlock = tempBlock;
@ -134,7 +134,7 @@ void* MemoryPool<T>::allocateObject() {
assert(currentNbObjects < capacity); assert(currentNbObjects < capacity);
assert(pFreeUnits); assert(pFreeUnits);
struct MemoryUnit* currentUnit = pFreeUnits; MemoryUnit* currentUnit = pFreeUnits;
pFreeUnits = currentUnit->pNext; pFreeUnits = currentUnit->pNext;
if (pFreeUnits) { if (pFreeUnits) {
pFreeUnits->pPrevious = 0; pFreeUnits->pPrevious = 0;
@ -149,7 +149,7 @@ void* MemoryPool<T>::allocateObject() {
currentNbObjects++; currentNbObjects++;
// Return a pointer to the allocated memory unit // Return a pointer to the allocated memory unit
return (void*)((char*)currentUnit + sizeof(struct MemoryUnit)); return (void*)((char*)currentUnit + sizeof(MemoryUnit));
} }
// Tell the pool that an object does not need to be stored in the pool anymore // Tell the pool that an object does not need to be stored in the pool anymore
@ -163,7 +163,7 @@ void MemoryPool<T>::freeObject(void* pObjectToFree) {
// The pointer location must be inside the memory block // The pointer location must be inside the memory block
//assert(pBlocks<pObjectToFree && pObjectToFree<(void*)((char*)pBlocks + memorySize)); //assert(pBlocks<pObjectToFree && pObjectToFree<(void*)((char*)pBlocks + memorySize));
struct MemoryUnit* currentUnit = (struct MemoryUnit*)((char*)pObjectToFree - sizeof(struct MemoryUnit)); MemoryUnit* currentUnit = (MemoryUnit*)((char*)pObjectToFree - sizeof(MemoryUnit));
pAllocatedUnits = currentUnit->pNext; pAllocatedUnits = currentUnit->pNext;
if (pAllocatedUnits) { if (pAllocatedUnits) {
pAllocatedUnits->pPrevious = 0; pAllocatedUnits->pPrevious = 0;
@ -185,9 +185,9 @@ template<class T>
void MemoryPool<T>::allocateMemory() { void MemoryPool<T>::allocateMemory() {
// Compute the size of the new // Compute the size of the new
size_t sizeBlock = nbObjectsNextBlock * (sizeof(struct MemoryUnit) + sizeof(T)); size_t sizeBlock = nbObjectsNextBlock * (sizeof(MemoryUnit) + sizeof(T));
struct MemoryBlock* tempBlocks = (struct MemoryBlock*) pBlocks; MemoryBlock* tempBlocks = (MemoryBlock*) pBlocks;
// Allocate a new memory block // Allocate a new memory block
pBlocks = malloc(sizeBlock); pBlocks = malloc(sizeBlock);
@ -195,14 +195,14 @@ void MemoryPool<T>::allocateMemory() {
// Check that the allocation didn't fail // Check that the allocation didn't fail
if (!pBlocks) throw std::bad_alloc(); if (!pBlocks) throw std::bad_alloc();
struct MemoryBlock* block = (struct MemoryBlock*) pBlocks; MemoryBlock* block = (MemoryBlock*) pBlocks;
block->pNext = tempBlocks; block->pNext = tempBlocks;
// For each allocated memory unit in the new block // For each allocated memory unit in the new block
for (uint i=0; i<nbObjectsNextBlock; i++) { for (uint i=0; i<nbObjectsNextBlock; i++) {
// Get the adress of a memory unit // Get the adress of a memory unit
struct MemoryUnit* currentUnit = (struct MemoryUnit*)( (char*)pBlocks + i * (sizeof(T) + sizeof(struct MemoryUnit)) ); MemoryUnit* currentUnit = (MemoryUnit*)( (char*)pBlocks + i * (sizeof(T) + sizeof(MemoryUnit)) );
currentUnit->pPrevious = 0; currentUnit->pPrevious = 0;
currentUnit->pNext = pFreeUnits; currentUnit->pNext = pFreeUnits;

View File

@ -37,9 +37,10 @@
// Libraries // Libraries
#include "configuration.h" #include "configuration.h"
#include "mathematics/mathematics.h" #include "mathematics/mathematics.h"
#include "body/CollisionBody.h"
#include "body/RigidBody.h" #include "body/RigidBody.h"
#include "engine/PhysicsWorld.h" #include "engine/DynamicsWorld.h"
#include "engine/PhysicsEngine.h" #include "engine/CollisionWorld.h"
#include "collision/shapes/CollisionShape.h" #include "collision/shapes/CollisionShape.h"
#include "collision/shapes/BoxShape.h" #include "collision/shapes/BoxShape.h"
#include "collision/shapes/SphereShape.h" #include "collision/shapes/SphereShape.h"