Add the CollisionBody class

This commit is contained in:
Daniel Chappuis 2012-09-18 22:09:49 +02:00
parent 19f7925d47
commit 2ed2b2a54f
23 changed files with 350 additions and 242 deletions

View File

@ -31,25 +31,11 @@
using namespace reactphysics3d;
// Constructor
Body::Body(const Transform& transform, CollisionShape *collisionShape, decimal mass, bodyindex id)
: collisionShape(collisionShape), mass(mass), transform(transform), isActive(true), id(id), hasMoved(false) {
assert(mass > 0.0);
assert(collisionShape);
Body::Body(bodyindex id) : id(id) {
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
Body::~Body() {
// Delete the AABB
delete aabb;
}

View File

@ -29,9 +29,6 @@
// Libraries
#include <stdexcept>
#include <cassert>
#include "../mathematics/Transform.h"
#include "../collision/shapes/AABB.h"
#include "../collision/shapes/CollisionShape.h"
#include "../configuration.h"
// Namespace reactphysics3d
@ -45,43 +42,15 @@ namespace reactphysics3d {
-------------------------------------------------------------------
*/
class Body {
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
bool hasMoved; // True if the body has moved during the last frame
public :
Body(const Transform& transform, CollisionShape* collisionShape, decimal mass, bodyindex id); // Constructor
Body(bodyindex id); // Constructor
virtual ~Body(); // Destructor
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
bool operator<(const Body& body2) const; // Smaller than operator
@ -95,115 +64,6 @@ inline bodyindex Body::getID() const {
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
inline bool Body::operator<(const Body& body2) const {
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
RigidBody::RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal, CollisionShape *collisionShape, bodyindex id)
: Body(transform, collisionShape, mass, id), inertiaTensorLocal(inertiaTensorLocal),
inertiaTensorLocalInverse(inertiaTensorLocal.getInverse()), massInverse(1.0/mass) {
: CollisionBody(transform, collisionShape, id), inertiaTensorLocal(inertiaTensorLocal),
mass(mass), inertiaTensorLocalInverse(inertiaTensorLocal.getInverse()), massInverse(1.0/mass) {
restitution = 1.0;

View File

@ -28,8 +28,7 @@
// Libraries
#include <cassert>
#include "Body.h"
#include "../collision/shapes/CollisionShape.h"
#include "CollisionBody.h"
#include "../mathematics/mathematics.h"
// Namespace reactphysics3d
@ -39,11 +38,16 @@ namespace reactphysics3d {
Class RigidBody :
This class represents a rigid body of the physics
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 :
// TODO : Remove the mass variable (duplicate with inverseMass)
decimal mass; // Mass of the body
Vector3 linearVelocity; // Linear velocity of the body
Vector3 angularVelocity; // Angular velocity of 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
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
void setLinearVelocity(const Vector3& linearVelocity); // Set the linear velocity of the body
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
};
// 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
inline Vector3 RigidBody::getLinearVelocity() const {
return linearVelocity;

View File

@ -98,7 +98,7 @@ bool CollisionDetection::computeCollisionDetection() {
void CollisionDetection::computeBroadPhase() {
// 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 ((*it)->getHasMoved()) {
@ -122,8 +122,8 @@ bool CollisionDetection::computeNarrowPhase() {
for (it = overlappingPairs.begin(); it != overlappingPairs.end(); it++) {
ContactInfo* contactInfo = NULL;
Body* const body1 = (*it).second->getBody1();
Body* const body2 = (*it).second->getBody2();
CollisionBody* const body1 = (*it).second->getBody1();
CollisionBody* const body2 = (*it).second->getBody2();
// Update the contact cache of the overlapping pair
(*it).second->update();
@ -140,8 +140,11 @@ bool CollisionDetection::computeNarrowPhase() {
assert(contactInfo);
collisionExists = true;
RigidBody* const rigidBody1 = dynamic_cast<RigidBody* const>(body1);
RigidBody* const rigidBody2 = dynamic_cast<RigidBody* const>(body2);
// Create a new contact
Contact* contact = new (memoryPoolContacts.allocateObject()) Contact(body1, body2, contactInfo);
Contact* contact = new (memoryPoolContacts.allocateObject()) Contact(rigidBody1, rigidBody2, contactInfo);
// Delete and remove the contact info from the memory pool
contactInfo->ContactInfo::~ContactInfo();

View File

@ -27,7 +27,7 @@
#define COLLISION_DETECTION_H
// Libraries
#include "../body/Body.h"
#include "../body/CollisionBody.h"
#include "OverlappingPair.h"
#include "broadphase/BroadPhaseAlgorithm.h"
#include "../memory/MemoryPool.h"
@ -57,6 +57,7 @@ class PhysicsWorld;
-------------------------------------------------------------------
*/
class CollisionDetection {
private :
PhysicsWorld* world; // Pointer to the physics world
std::map<std::pair<bodyindex, bodyindex>, OverlappingPair*> overlappingPairs; // Broad-phase overlapping pairs of bodies
@ -78,8 +79,8 @@ class CollisionDetection {
CollisionDetection(PhysicsWorld* physicsWorld); // Constructor
~CollisionDetection(); // Destructor
void addBody(Body* body); // Add a body to the collision detection
void removeBody(Body* body); // Remove a body from the collision detection
void addBody(CollisionBody* body); // Add a body to 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
void broadPhaseNotifyAddedOverlappingPair(const BroadPhasePair* pair); // Allow the broadphase to notify the collision detection about a new overlapping pair
@ -109,14 +110,14 @@ inline NarrowPhaseAlgorithm& CollisionDetection::SelectNarrowPhaseAlgorithm(Coll
}
// 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
broadPhaseAlgorithm->addObject(body, *(body->getAABB()));
}
// 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
broadPhaseAlgorithm->removeObject(body);

View File

@ -30,7 +30,7 @@ using namespace reactphysics3d;
// 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) {
}

View File

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

View File

@ -28,7 +28,7 @@
// Libraries
#include <vector>
#include "../../body/Body.h"
#include "../../body/CollisionBody.h"
#include "PairManager.h"
// Namespace ReactPhysics3D
@ -62,9 +62,9 @@ class BroadPhaseAlgorithm {
// TODO : DELETE THIS METHOD
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 removeObject(Body* 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 addObject(CollisionBody* body, const AABB& aabb)=0; // Notify the broad-phase about a new object in 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(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)
BroadPhasePair* endOverlappingPairsPointer() const; // Return a pointer to the last active pair (used to iterate over the active pairs)

View File

@ -44,25 +44,25 @@ namespace reactphysics3d {
*/
class NoBroadPhaseAlgorithm : public BroadPhaseAlgorithm {
protected :
std::set<Body*> bodies; // All bodies of the world
std::set<CollisionBody*> bodies; // All bodies of the world
public :
NoBroadPhaseAlgorithm(CollisionDetection& collisionDetection); // Constructor
virtual ~NoBroadPhaseAlgorithm(); // Destructor
virtual void addObject(Body* 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 updateObject(Body* body, const AABB& aabb); // Notify the broad-phase that the AABB of an object has changed
virtual void addObject(CollisionBody* body, const AABB& aabb); // Notify the broad-phase about a new object in the world
virtual void removeObject(CollisionBody* body); // Notify the broad-phase about an object that has been removed from the world
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
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;
// 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
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
inline void NoBroadPhaseAlgorithm::removeObject(Body* body) {
inline void NoBroadPhaseAlgorithm::removeObject(CollisionBody* body) {
// 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()) {
@ -90,7 +90,7 @@ inline void NoBroadPhaseAlgorithm::removeObject(Body* body) {
}
// 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
return;
}

View File

@ -56,7 +56,7 @@ PairManager::~PairManager() {
// 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
// return a pointer to that pair.
BroadPhasePair* PairManager::addPair(Body* body1, Body* body2) {
BroadPhasePair* PairManager::addPair(CollisionBody* body1, CollisionBody* body2) {
// Sort the bodies to have the body with smallest ID first
sortBodiesUsingID(body1, body2);

View File

@ -27,7 +27,7 @@
#define PAIR_MANAGER_H
// Libraries
#include "../../body/Body.h"
#include "../../body/CollisionBody.h"
// Namespace ReactPhysics3D
@ -40,8 +40,8 @@ class CollisionDetection;
// during the broad-phase collision detection
struct BroadPhasePair {
public:
Body* body1; // Pointer to the first body
Body* body2; // Pointer to the second body
CollisionBody* body1; // Pointer to the first body
CollisionBody* body2; // Pointer to the second body
};
@ -67,8 +67,8 @@ class PairManager {
static bodyindex INVALID_INDEX; // Invalid ID
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 sortIDs(bodyindex& id1, bodyindex& id2) const; // Sort the 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)
bool isDifferentPair(const BroadPhasePair& pair1, bodyindex pair2ID1,
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
@ -88,7 +88,7 @@ class PairManager {
~PairManager(); // Destructor
bodyindex getNbOverlappingPairs() const; // Return the number of active pairs
BroadPhasePair* addPair(Body* body1, Body* body2); // Add a pair of bodies in the pair manager
BroadPhasePair* 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
BroadPhasePair* 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)
@ -125,13 +125,13 @@ inline luint PairManager::computeNextPowerOfTwo(luint number) const {
}
// 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 (body1->getID() > body2->getID()) {
// Swap the two bodies pointers
Body* temp = body2;
CollisionBody* temp = body2;
body2 = body1;
body1 = temp;
}

View File

@ -65,7 +65,7 @@ SweepAndPruneAlgorithm::~SweepAndPruneAlgorithm() {
// Notify the broad-phase about a new object in the world
// 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;
// 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
mapBodyToBoxIndex.insert(pair<Body*, bodyindex>(body, boxIndex));
mapBodyToBoxIndex.insert(pair<CollisionBody*, bodyindex>(body, boxIndex));
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
void SweepAndPruneAlgorithm::removeObject(Body* body) {
void SweepAndPruneAlgorithm::removeObject(CollisionBody* body) {
// Call the update method with an AABB that is very far away
// 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
void SweepAndPruneAlgorithm::updateObject(Body* body, const AABB& aabb) {
void SweepAndPruneAlgorithm::updateObject(CollisionBody* body, const AABB& aabb) {
// Compute the AABB with integer coordinates
AABBInt aabbInt(aabb);

View File

@ -62,7 +62,7 @@ struct BoxAABB {
public:
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
Body* body; // Body that corresponds to the owner of the AABB
CollisionBody* body; // Body that corresponds to the owner of the AABB
};
// Structure AABBInt
@ -94,10 +94,10 @@ class SweepAndPruneAlgorithm : public BroadPhaseAlgorithm {
bodyindex nbBoxes; // Number of AABB boxes in the broad-phase
bodyindex nbMaxBoxes; // Maximum number of boxes in the boxes array
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 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,
const EndPoint* const baseEndPoint, uint axis) const; // Check for 1D box intersection
bool testIntersect2D(const BoxAABB& box1, const BoxAABB& box2,
@ -107,9 +107,9 @@ class SweepAndPruneAlgorithm : public BroadPhaseAlgorithm {
SweepAndPruneAlgorithm(CollisionDetection& collisionDetection); // Constructor
virtual ~SweepAndPruneAlgorithm(); // Destructor
virtual void addObject(Body* 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 updateObject(Body* body, const AABB& aabb); // Notify the broad-phase that the AABB of an object has changed
virtual void addObject(CollisionBody* body, const AABB& aabb); // Notify the broad-phase about a new object in the world
virtual void removeObject(CollisionBody* body); // Notify the broad-phase about a object that has been removed from the world
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

View File

@ -30,7 +30,7 @@
using namespace reactphysics3d;
// 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) {
// Initialize the cached lambda values

View File

@ -27,7 +27,7 @@
#define CONSTRAINT_H
// Libraries
#include "../body/Body.h"
#include "../body/RigidBody.h"
#include "../mathematics/mathematics.h"
// ReactPhysics3D namespace
@ -46,19 +46,19 @@ enum ConstraintType {CONTACT};
*/
class Constraint {
protected :
Body* const body1; // Pointer to the first body of the constraint
Body* const body2; // Pointer to the second body of the constraint
RigidBody* const body1; // Pointer to the first body of the constraint
RigidBody* const body2; // Pointer to the second body of the constraint
bool active; // True if the constraint is active
uint nbConstraints; // Number mathematical constraints associated with this 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
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
virtual ~Constraint(); // Destructor
Body* 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 getBody1() const; // Return the reference to the body 1
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
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
@ -71,12 +71,12 @@ class Constraint {
};
// Return the reference to the body 1
inline Body* const Constraint::getBody1() const {
inline RigidBody* const Constraint::getBody1() const {
return body1;
}
// Return the reference to the body 2
inline Body* const Constraint::getBody2() const {
inline RigidBody* const Constraint::getBody2() const {
return body2;
}

View File

@ -30,7 +30,7 @@ using namespace reactphysics3d;
using namespace std;
// 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),
localPointOnBody1(contactInfo->localPoint1), localPointOnBody2(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 + 1] = 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 {
protected :
const Vector3 normal; // Normal vector of the contact (From body1 toward body2) in world space
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
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
Vector3 getNormal() const; // Return the normal vector of the contact

View File

@ -58,6 +58,8 @@ void PhysicsEngine::update() {
// While the time accumulator is not empty
while(timer.isPossibleToTakeStep()) {
std::cout << "Update ..." << std::endl;
existCollision = false;
// Compute the collision detection

View File

@ -31,7 +31,7 @@
#include <set>
#include <algorithm>
#include "../mathematics/mathematics.h"
#include "../body/Body.h"
#include "../body/CollisionBody.h"
#include "../collision/CollisionDetection.h"
#include "../constraint/Constraint.h"
#include "../constraint/Contact.h"
@ -40,7 +40,6 @@
// Namespace reactphysics3d
namespace reactphysics3d {
/* -------------------------------------------------------------------
Class PhysicsWorld :
This class represents the world of the
@ -51,7 +50,7 @@ namespace reactphysics3d {
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<CollisionBody*> 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
@ -77,8 +76,8 @@ class PhysicsWorld {
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<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
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
};
@ -131,12 +130,12 @@ inline std::vector<Constraint*>::iterator PhysicsWorld::getConstraintsEndIterato
}
// Return an iterator to the beginning of the bodies of the physics world
inline std::set<Body*>::iterator PhysicsWorld::getBodiesBeginIterator() {
inline std::set<CollisionBody*>::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() {
inline std::set<CollisionBody*>::iterator PhysicsWorld::getBodiesEndIterator() {
return bodies.end();
}

View File

@ -65,8 +65,8 @@ class MemoryPool {
static const uint NB_OBJECTS_FIRST_BLOCK; // Number of objects allocated in the first block
void* pBlocks; // Pointer to the first allocated memory block
struct MemoryUnit* pAllocatedUnits; // Pointer to the first allocated memory unit
struct MemoryUnit* pFreeUnits; // Pointer to the first free memory unit
MemoryUnit* pAllocatedUnits; // Pointer to the first allocated memory unit
MemoryUnit* pFreeUnits; // Pointer to the first free memory unit
uint currentNbObjects; // Current number of objects 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
@ -110,8 +110,8 @@ MemoryPool<T>::~MemoryPool() {
assert(currentNbObjects == 0);
// Release all the allocated memory blocks
struct MemoryBlock* currentBlock = (struct MemoryBlock*) pBlocks;
while(currentBlock != 0) {
MemoryBlock* currentBlock = (MemoryBlock*) pBlocks;
while(currentBlock) {
MemoryBlock* tempBlock = currentBlock->pNext;
free(currentBlock);
currentBlock = tempBlock;
@ -134,7 +134,7 @@ void* MemoryPool<T>::allocateObject() {
assert(currentNbObjects < capacity);
assert(pFreeUnits);
struct MemoryUnit* currentUnit = pFreeUnits;
MemoryUnit* currentUnit = pFreeUnits;
pFreeUnits = currentUnit->pNext;
if (pFreeUnits) {
pFreeUnits->pPrevious = 0;
@ -149,7 +149,7 @@ void* MemoryPool<T>::allocateObject() {
currentNbObjects++;
// 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
@ -163,7 +163,7 @@ void MemoryPool<T>::freeObject(void* pObjectToFree) {
// The pointer location must be inside the memory block
//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;
if (pAllocatedUnits) {
pAllocatedUnits->pPrevious = 0;
@ -185,9 +185,9 @@ template<class T>
void MemoryPool<T>::allocateMemory() {
// 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
pBlocks = malloc(sizeBlock);
@ -195,14 +195,14 @@ void MemoryPool<T>::allocateMemory() {
// Check that the allocation didn't fail
if (!pBlocks) throw std::bad_alloc();
struct MemoryBlock* block = (struct MemoryBlock*) pBlocks;
MemoryBlock* block = (MemoryBlock*) pBlocks;
block->pNext = tempBlocks;
// For each allocated memory unit in the new block
for (uint i=0; i<nbObjectsNextBlock; i++) {
// 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->pNext = pFreeUnits;