Merge branch 'dynamicscollision' into develop
This commit is contained in:
commit
f47298d7eb
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
148
src/body/Body.h
148
src/body/Body.h
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
55
src/body/CollisionBody.cpp
Normal file
55
src/body/CollisionBody.cpp
Normal 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
185
src/body/CollisionBody.h
Normal 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
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
40
src/collision/BroadPhasePair.cpp
Normal file
40
src/collision/BroadPhasePair.cpp
Normal 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() {
|
||||||
|
|
||||||
|
}
|
89
src/collision/BroadPhasePair.h
Normal file
89
src/collision/BroadPhasePair.h
Normal 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
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
93
src/engine/CollisionWorld.h
Normal file
93
src/engine/CollisionWorld.h
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
200
src/engine/DynamicsWorld.h
Normal 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
|
|
@ -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) {
|
||||||
|
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user