Add Doxygen documentation into the code
This commit is contained in:
parent
03cddcf568
commit
04a31c696c
src
body
collision
BroadPhasePair.hCollisionDetection.cppCollisionDetection.hContactInfo.h
configuration.hbroadphase
BroadPhaseAlgorithm.hNoBroadPhaseAlgorithm.hPairManager.cppPairManager.hSweepAndPruneAlgorithm.cppSweepAndPruneAlgorithm.h
narrowphase
shapes
constraint
decimal.hengine
CollisionWorld.hContactManifold.cppContactManifold.hContactSolver.cppContactSolver.hDynamicsWorld.hOverlappingPair.hTimer.h
mathematics
memory
reactphysics3d.h
|
@ -31,56 +31,53 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "../configuration.h"
|
#include "../configuration.h"
|
||||||
|
|
||||||
// Namespace reactphysics3d
|
/// Namespace reactphysics3d
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
|
// Class Body
|
||||||
/* -------------------------------------------------------------------
|
/**
|
||||||
Class Body :
|
* This class is an abstract class to represent a body of the physics engine.
|
||||||
This class is an abstract class to represent a body of the physics
|
*/
|
||||||
engine.
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
class Body {
|
class Body {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// ID of the body
|
/// ID of the body
|
||||||
bodyindex mID;
|
bodyindex mID;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
Body(const Body& body);
|
Body(const Body& body);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
Body& operator=(const Body& body);
|
Body& operator=(const Body& body);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Body(bodyindex id);
|
Body(bodyindex id);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~Body();
|
virtual ~Body();
|
||||||
|
|
||||||
// Return the id of the body
|
/// Return the id of the body
|
||||||
bodyindex getID() const;
|
bodyindex getID() const;
|
||||||
|
|
||||||
// Smaller than operator
|
/// Smaller than operator
|
||||||
bool operator<(const Body& body2) const;
|
bool operator<(const Body& body2) const;
|
||||||
|
|
||||||
// Larger than operator
|
/// Larger than operator
|
||||||
bool operator>(const Body& body2) const;
|
bool operator>(const Body& body2) const;
|
||||||
|
|
||||||
// Equal operator
|
/// Equal operator
|
||||||
bool operator==(const Body& body2) const;
|
bool operator==(const Body& body2) const;
|
||||||
|
|
||||||
// Not equal operator
|
/// Not equal operator
|
||||||
bool operator!=(const Body& body2) const;
|
bool operator!=(const Body& body2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,116 +35,114 @@
|
||||||
#include "../collision/shapes/CollisionShape.h"
|
#include "../collision/shapes/CollisionShape.h"
|
||||||
#include "../configuration.h"
|
#include "../configuration.h"
|
||||||
|
|
||||||
// Namespace reactphysics3d
|
/// Namespace reactphysics3d
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
|
// Class CollisionBody
|
||||||
/* -------------------------------------------------------------------
|
/**
|
||||||
Class CollisionBody :
|
* This class represents a body that is able to collide with others
|
||||||
This class represents a body that is able to collide with others
|
* bodies. This class inherits from the Body class.
|
||||||
bodies. This class inherits from the Body class.
|
*/
|
||||||
-------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
class CollisionBody : public Body {
|
class CollisionBody : public Body {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Collision shape of the body
|
/// Collision shape of the body
|
||||||
CollisionShape* mCollisionShape;
|
CollisionShape* mCollisionShape;
|
||||||
|
|
||||||
// Position and orientation of the body
|
/// Position and orientation of the body
|
||||||
Transform mTransform;
|
Transform mTransform;
|
||||||
|
|
||||||
// Last position and orientation of the body
|
/// Last position and orientation of the body
|
||||||
Transform mOldTransform;
|
Transform mOldTransform;
|
||||||
|
|
||||||
// Interpolation factor used for the state interpolation
|
/// Interpolation factor used for the state interpolation
|
||||||
decimal mInterpolationFactor;
|
decimal mInterpolationFactor;
|
||||||
|
|
||||||
// True if the body is active (not sleeping)
|
/// True if the body is active (not sleeping)
|
||||||
bool mIsActive;
|
bool mIsActive;
|
||||||
|
|
||||||
// True if the body is able to move
|
/// True if the body is able to move
|
||||||
bool mIsMotionEnabled;
|
bool mIsMotionEnabled;
|
||||||
|
|
||||||
// True if the body can collide with others bodies
|
/// True if the body can collide with others bodies
|
||||||
bool mIsCollisionEnabled;
|
bool mIsCollisionEnabled;
|
||||||
|
|
||||||
// AABB for Broad-Phase collision detection
|
/// AABB for Broad-Phase collision detection
|
||||||
AABB* mAabb;
|
AABB* mAabb;
|
||||||
|
|
||||||
// True if the body has moved during the last frame
|
/// True if the body has moved during the last frame
|
||||||
bool mHasMoved;
|
bool mHasMoved;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
CollisionBody(const CollisionBody& body);
|
CollisionBody(const CollisionBody& body);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
CollisionBody& operator=(const CollisionBody& body);
|
CollisionBody& operator=(const CollisionBody& body);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
CollisionBody(const Transform& transform, CollisionShape* collisionShape, bodyindex id);
|
CollisionBody(const Transform& transform, CollisionShape* collisionShape, bodyindex id);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~CollisionBody();
|
virtual ~CollisionBody();
|
||||||
|
|
||||||
// Return true if the body has moved during the last frame
|
/// Return true if the body has moved during the last frame
|
||||||
bool getHasMoved() const;
|
bool getHasMoved() const;
|
||||||
|
|
||||||
// Set the hasMoved variable (true if the body has moved during the last frame)
|
/// Set the hasMoved variable (true if the body has moved during the last frame)
|
||||||
void setHasMoved(bool hasMoved);
|
void setHasMoved(bool hasMoved);
|
||||||
|
|
||||||
// Return the collision shape
|
/// Return the collision shape
|
||||||
CollisionShape* getCollisionShape() const;
|
CollisionShape* getCollisionShape() const;
|
||||||
|
|
||||||
// Set the collision shape
|
/// Set the collision shape
|
||||||
void setCollisionShape(CollisionShape* collisionShape);
|
void setCollisionShape(CollisionShape* collisionShape);
|
||||||
|
|
||||||
// Return true for an active body
|
/// Return true for an active body
|
||||||
bool getIsActive() const;
|
bool getIsActive() const;
|
||||||
|
|
||||||
// Set the isActive variable
|
/// Set the isActive variable
|
||||||
void setIsActive(bool isActive);
|
void setIsActive(bool isActive);
|
||||||
|
|
||||||
// Return the current position and orientation
|
/// Return the current position and orientation
|
||||||
const Transform& getTransform() const;
|
const Transform& getTransform() const;
|
||||||
|
|
||||||
// Set the current position and orientation
|
/// Set the current position and orientation
|
||||||
void setTransform(const Transform& transform);
|
void setTransform(const Transform& transform);
|
||||||
|
|
||||||
// Return the AAABB of the body
|
/// Return the AAABB of the body
|
||||||
const AABB* getAABB() const;
|
const AABB* getAABB() const;
|
||||||
|
|
||||||
// Return the interpolated transform for rendering
|
/// Return the interpolated transform for rendering
|
||||||
Transform getInterpolatedTransform() const;
|
Transform getInterpolatedTransform() const;
|
||||||
|
|
||||||
// Set the interpolation factor of the body
|
/// Set the interpolation factor of the body
|
||||||
void setInterpolationFactor(decimal factor);
|
void setInterpolationFactor(decimal factor);
|
||||||
|
|
||||||
// Return if the rigid body can move
|
/// Return if the rigid body can move
|
||||||
bool getIsMotionEnabled() const;
|
bool getIsMotionEnabled() const;
|
||||||
|
|
||||||
// Set the value to true if the body can move
|
/// Set the value to true if the body can move
|
||||||
void setIsMotionEnabled(bool isMotionEnabled);
|
void setIsMotionEnabled(bool isMotionEnabled);
|
||||||
|
|
||||||
// Return true if the body can collide with others bodies
|
/// Return true if the body can collide with others bodies
|
||||||
bool getIsCollisionEnabled() const;
|
bool getIsCollisionEnabled() const;
|
||||||
|
|
||||||
// Set the isCollisionEnabled value
|
/// Set the isCollisionEnabled value
|
||||||
void setIsCollisionEnabled(bool isCollisionEnabled);
|
void setIsCollisionEnabled(bool isCollisionEnabled);
|
||||||
|
|
||||||
// Update the old transform with the current one
|
/// Update the old transform with the current one.
|
||||||
void updateOldTransform();
|
void updateOldTransform();
|
||||||
|
|
||||||
// Update the Axis-Aligned Bounding Box coordinates
|
/// Update the Axis-Aligned Bounding Box coordinates
|
||||||
void updateAABB();
|
void updateAABB();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -232,8 +230,8 @@ inline void CollisionBody::setIsCollisionEnabled(bool isCollisionEnabled) {
|
||||||
mIsCollisionEnabled = isCollisionEnabled;
|
mIsCollisionEnabled = isCollisionEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the old transform with the current one
|
// Update the old transform with the current one.
|
||||||
// This is used to compute the interpolated position and orientation of the body
|
/// This is used to compute the interpolated position and orientation of the body
|
||||||
inline void CollisionBody::updateOldTransform() {
|
inline void CollisionBody::updateOldTransform() {
|
||||||
mOldTransform = mTransform;
|
mOldTransform = mTransform;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,17 +31,16 @@
|
||||||
#include "CollisionBody.h"
|
#include "CollisionBody.h"
|
||||||
#include "../mathematics/mathematics.h"
|
#include "../mathematics/mathematics.h"
|
||||||
|
|
||||||
// Namespace reactphysics3d
|
/// Namespace reactphysics3d
|
||||||
namespace reactphysics3d {
|
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. This class inherits from the
|
* has a constant mass. This class inherits from the
|
||||||
CollisionBody class.
|
* CollisionBody class.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class RigidBody : public CollisionBody {
|
class RigidBody : public CollisionBody {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
@ -50,123 +49,123 @@ class RigidBody : public CollisionBody {
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Mass of the body
|
/// Mass of the body
|
||||||
decimal mMass;
|
decimal mMass;
|
||||||
|
|
||||||
// Linear velocity of the body
|
/// Linear velocity of the body
|
||||||
Vector3 mLinearVelocity;
|
Vector3 mLinearVelocity;
|
||||||
|
|
||||||
// Angular velocity of the body
|
/// Angular velocity of the body
|
||||||
Vector3 mAngularVelocity;
|
Vector3 mAngularVelocity;
|
||||||
|
|
||||||
// Current external force on the body
|
/// Current external force on the body
|
||||||
Vector3 mExternalForce;
|
Vector3 mExternalForce;
|
||||||
|
|
||||||
// Current external torque on the body
|
/// Current external torque on the body
|
||||||
Vector3 mExternalTorque;
|
Vector3 mExternalTorque;
|
||||||
|
|
||||||
// Local inertia tensor of the body (in local-space)
|
/// Local inertia tensor of the body (in local-space)
|
||||||
Matrix3x3 mInertiaTensorLocal;
|
Matrix3x3 mInertiaTensorLocal;
|
||||||
|
|
||||||
// Inverse of the inertia tensor of the body
|
/// Inverse of the inertia tensor of the body
|
||||||
Matrix3x3 mInertiaTensorLocalInverse;
|
Matrix3x3 mInertiaTensorLocalInverse;
|
||||||
|
|
||||||
// Inverse of the mass of the body
|
/// Inverse of the mass of the body
|
||||||
decimal mMassInverse;
|
decimal mMassInverse;
|
||||||
|
|
||||||
// Coefficient of restitution (between 0 and 1) where 1 is for a very bouncy body
|
/// Coefficient of restitution (between 0 and 1) where 1 is for a very bouncy body
|
||||||
decimal mRestitution;
|
decimal mRestitution;
|
||||||
|
|
||||||
// Friction coefficient
|
/// Friction coefficient
|
||||||
decimal mFrictionCoefficient;
|
decimal mFrictionCoefficient;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
RigidBody(const RigidBody& body);
|
RigidBody(const RigidBody& body);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
RigidBody& operator=(const RigidBody& body);
|
RigidBody& operator=(const RigidBody& body);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal,
|
RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal,
|
||||||
CollisionShape* collisionShape, bodyindex id);
|
CollisionShape* collisionShape, bodyindex id);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~RigidBody();
|
virtual ~RigidBody();
|
||||||
|
|
||||||
// Return the mass of the body
|
/// Return the mass of the body
|
||||||
decimal getMass() const;
|
decimal getMass() const;
|
||||||
|
|
||||||
// Set the mass of the body
|
/// Set the mass of the body
|
||||||
void setMass(decimal mass);
|
void setMass(decimal mass);
|
||||||
|
|
||||||
// Return the linear velocity
|
/// Return the linear velocity
|
||||||
Vector3 getLinearVelocity() const;
|
Vector3 getLinearVelocity() const;
|
||||||
|
|
||||||
// Set the linear velocity of the body
|
/// Set the linear velocity of the body
|
||||||
void setLinearVelocity(const Vector3& linearVelocity);
|
void setLinearVelocity(const Vector3& linearVelocity);
|
||||||
|
|
||||||
// Return the angular velocity
|
/// Return the angular velocity
|
||||||
Vector3 getAngularVelocity() const;
|
Vector3 getAngularVelocity() const;
|
||||||
|
|
||||||
// Set the angular velocity
|
/// Set the angular velocity
|
||||||
void setAngularVelocity(const Vector3& angularVelocity);
|
void setAngularVelocity(const Vector3& angularVelocity);
|
||||||
|
|
||||||
// Set the inverse of the mass
|
/// Set the inverse of the mass
|
||||||
void setMassInverse(decimal massInverse);
|
void setMassInverse(decimal massInverse);
|
||||||
|
|
||||||
// Return the current external force of the body
|
/// Return the current external force of the body
|
||||||
Vector3 getExternalForce() const;
|
Vector3 getExternalForce() const;
|
||||||
|
|
||||||
// Set the current external force on the body
|
/// Set the current external force on the body
|
||||||
void setExternalForce(const Vector3& force);
|
void setExternalForce(const Vector3& force);
|
||||||
|
|
||||||
// Return the current external torque of the body
|
/// Return the current external torque of the body
|
||||||
Vector3 getExternalTorque() const;
|
Vector3 getExternalTorque() const;
|
||||||
|
|
||||||
// Set the current external torque of the body
|
/// Set the current external torque of the body
|
||||||
void setExternalTorque(const Vector3& torque);
|
void setExternalTorque(const Vector3& torque);
|
||||||
|
|
||||||
// Return the inverse of the mass of the body
|
/// Return the inverse of the mass of the body
|
||||||
decimal getMassInverse() const;
|
decimal getMassInverse() const;
|
||||||
|
|
||||||
// Return the local inertia tensor of the body (in body coordinates)
|
/// Return the local inertia tensor of the body (in body coordinates)
|
||||||
Matrix3x3 getInertiaTensorLocal() const;
|
Matrix3x3 getInertiaTensorLocal() const;
|
||||||
|
|
||||||
// Set the local inertia tensor of the body (in body coordinates)
|
/// Set the local inertia tensor of the body (in body coordinates)
|
||||||
void setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal);
|
void setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal);
|
||||||
|
|
||||||
// Get the inverse of the inertia tensor
|
/// Get the inverse of the inertia tensor
|
||||||
Matrix3x3 getInertiaTensorLocalInverse() const;
|
Matrix3x3 getInertiaTensorLocalInverse() const;
|
||||||
|
|
||||||
// Return the inertia tensor in world coordinates
|
/// Return the inertia tensor in world coordinates.
|
||||||
Matrix3x3 getInertiaTensorWorld() const;
|
Matrix3x3 getInertiaTensorWorld() const;
|
||||||
|
|
||||||
// Return the inverse of the inertia tensor in world coordinates
|
/// Return the inverse of the inertia tensor in world coordinates.
|
||||||
Matrix3x3 getInertiaTensorInverseWorld() const;
|
Matrix3x3 getInertiaTensorInverseWorld() const;
|
||||||
|
|
||||||
// Get the restitution coefficient
|
/// Get the restitution coefficient
|
||||||
decimal getRestitution() const;
|
decimal getRestitution() const;
|
||||||
|
|
||||||
// Set the restitution coefficient
|
/// Set the restitution coefficient
|
||||||
void setRestitution(decimal restitution) throw(std::invalid_argument);
|
void setRestitution(decimal restitution) throw(std::invalid_argument);
|
||||||
|
|
||||||
// Get the friction coefficient
|
/// Get the friction coefficient
|
||||||
decimal getFrictionCoefficient() const;
|
decimal getFrictionCoefficient() const;
|
||||||
|
|
||||||
// Set the friction coefficient
|
/// Set the friction coefficient
|
||||||
void setFrictionCoefficient(decimal frictionCoefficient);
|
void setFrictionCoefficient(decimal frictionCoefficient);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Method that return the mass of the body
|
// Method that return the mass of the body
|
||||||
inline decimal RigidBody::getMass() const {
|
inline decimal RigidBody::getMass() const {
|
||||||
return mMass;
|
return mMass;
|
||||||
};
|
}
|
||||||
|
|
||||||
// Method that set the mass of the body
|
// Method that set the mass of the body
|
||||||
inline void RigidBody::setMass(decimal mass) {
|
inline void RigidBody::setMass(decimal mass) {
|
||||||
|
@ -232,12 +231,12 @@ inline void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal
|
||||||
mInertiaTensorLocal = inertiaTensorLocal;
|
mInertiaTensorLocal = inertiaTensorLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the inertia tensor in world coordinates
|
// Return the inertia tensor in world coordinates.
|
||||||
// The inertia tensor I_w in world coordinates is computed
|
/// The inertia tensor I_w in world coordinates is computed
|
||||||
// with the local inertia tensor I_b in body coordinates
|
/// with the local inertia tensor I_b in body coordinates
|
||||||
// by I_w = R * I_b * R^T
|
/// by I_w = R * I_b * R^T
|
||||||
// where R is the rotation matrix (and R^T its transpose) of
|
/// where R is the rotation matrix (and R^T its transpose) of
|
||||||
// the current orientation quaternion of the body
|
/// the current orientation quaternion of the body
|
||||||
inline Matrix3x3 RigidBody::getInertiaTensorWorld() const {
|
inline Matrix3x3 RigidBody::getInertiaTensorWorld() const {
|
||||||
|
|
||||||
// Compute and return the inertia tensor in world coordinates
|
// Compute and return the inertia tensor in world coordinates
|
||||||
|
@ -245,12 +244,12 @@ inline Matrix3x3 RigidBody::getInertiaTensorWorld() const {
|
||||||
mTransform.getOrientation().getMatrix().getTranspose();
|
mTransform.getOrientation().getMatrix().getTranspose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the inverse of the inertia tensor in world coordinates
|
// Return the inverse of the inertia tensor in world coordinates.
|
||||||
// The inertia tensor I_w in world coordinates is computed with the
|
/// The inertia tensor I_w in world coordinates is computed with the
|
||||||
// local inverse inertia tensor I_b^-1 in body coordinates
|
/// local inverse inertia tensor I_b^-1 in body coordinates
|
||||||
// by I_w = R * I_b^-1 * R^T
|
/// by I_w = R * I_b^-1 * R^T
|
||||||
// where R is the rotation matrix (and R^T its transpose) of the
|
/// where R is the rotation matrix (and R^T its transpose) of the
|
||||||
// current orientation quaternion of the body
|
/// current orientation quaternion of the body
|
||||||
inline Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const {
|
inline Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const {
|
||||||
|
|
||||||
// Compute and return the inertia tensor in world coordinates
|
// Compute and return the inertia tensor in world coordinates
|
||||||
|
|
|
@ -29,48 +29,50 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "../body/CollisionBody.h"
|
#include "../body/CollisionBody.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// struct BroadPhasePair
|
// Structure BroadPhasePair
|
||||||
// This structure represents a pair of bodies
|
/**
|
||||||
// during the broad-phase collision detection
|
* This structure represents a pair of bodies
|
||||||
|
* during the broad-phase collision detection.
|
||||||
|
*/
|
||||||
struct BroadPhasePair {
|
struct BroadPhasePair {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Pointer to the first body
|
/// Pointer to the first body
|
||||||
CollisionBody* body1;
|
CollisionBody* body1;
|
||||||
|
|
||||||
// Pointer to the second body
|
/// Pointer to the second body
|
||||||
CollisionBody* body2;
|
CollisionBody* body2;
|
||||||
|
|
||||||
// Previous cached separating axis
|
/// Previous cached separating axis
|
||||||
Vector3 previousSeparatingAxis;
|
Vector3 previousSeparatingAxis;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
BroadPhasePair(CollisionBody* body1, CollisionBody* body2);
|
BroadPhasePair(CollisionBody* body1, CollisionBody* body2);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~BroadPhasePair();
|
~BroadPhasePair();
|
||||||
|
|
||||||
// Return the pair of bodies index
|
/// Return the pair of bodies index
|
||||||
bodyindexpair getBodiesIndexPair() const;
|
bodyindexpair getBodiesIndexPair() const;
|
||||||
|
|
||||||
// Smaller than operator
|
/// Smaller than operator
|
||||||
bool operator<(const BroadPhasePair& broadPhasePair2) const;
|
bool operator<(const BroadPhasePair& broadPhasePair2) const;
|
||||||
|
|
||||||
// Larger than operator
|
/// Larger than operator
|
||||||
bool operator>(const BroadPhasePair& broadPhasePair2) const;
|
bool operator>(const BroadPhasePair& broadPhasePair2) const;
|
||||||
|
|
||||||
// Equal operator
|
/// Equal operator
|
||||||
bool operator==(const BroadPhasePair& broadPhasePair2) const;
|
bool operator==(const BroadPhasePair& broadPhasePair2) const;
|
||||||
|
|
||||||
// Not equal operator
|
/// Not equal operator
|
||||||
bool operator!=(const BroadPhasePair& broadPhasePair2) const;
|
bool operator!=(const BroadPhasePair& broadPhasePair2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -143,8 +143,8 @@ bool CollisionDetection::computeNarrowPhase() {
|
||||||
return collisionExists;
|
return collisionExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(BodyPair* addedPair) {
|
void CollisionDetection::broadPhaseNotifyAddedOverlappingPair(BodyPair* addedPair) {
|
||||||
|
|
||||||
// Get the pair of body index
|
// Get the pair of body index
|
||||||
|
|
|
@ -41,63 +41,62 @@
|
||||||
#include <iostream> // TODO : Delete this
|
#include <iostream> // TODO : Delete this
|
||||||
|
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
class BroadPhaseAlgorithm;
|
class BroadPhaseAlgorithm;
|
||||||
class CollisionWorld;
|
class CollisionWorld;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class CollisionDetection
|
||||||
Class CollisionDetection :
|
/**
|
||||||
This class computes the collision detection algorithms. We first
|
* This class computes the collision detection algorithms. We first
|
||||||
perform a broad-phase algorithm to know which pairs of bodies can
|
* perform a broad-phase algorithm to know which pairs of bodies can
|
||||||
collide and then we run a narrow-phase algorithm to compute the
|
* collide and then we run a narrow-phase algorithm to compute the
|
||||||
collision contacts between bodies.
|
* collision contacts between bodies.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class CollisionDetection {
|
class CollisionDetection {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Pointer to the physics world
|
/// Pointer to the physics world
|
||||||
CollisionWorld* mWorld;
|
CollisionWorld* mWorld;
|
||||||
|
|
||||||
// Broad-phase overlapping pairs
|
/// Broad-phase overlapping pairs
|
||||||
std::map<bodyindexpair, BroadPhasePair*> mOverlappingPairs;
|
std::map<bodyindexpair, BroadPhasePair*> mOverlappingPairs;
|
||||||
|
|
||||||
// Broad-phase algorithm
|
/// Broad-phase algorithm
|
||||||
BroadPhaseAlgorithm* mBroadPhaseAlgorithm;
|
BroadPhaseAlgorithm* mBroadPhaseAlgorithm;
|
||||||
|
|
||||||
// Narrow-phase GJK algorithm
|
/// Narrow-phase GJK algorithm
|
||||||
GJKAlgorithm mNarrowPhaseGJKAlgorithm;
|
GJKAlgorithm mNarrowPhaseGJKAlgorithm;
|
||||||
|
|
||||||
// Narrow-phase Sphere vs Sphere algorithm
|
/// Narrow-phase Sphere vs Sphere algorithm
|
||||||
SphereVsSphereAlgorithm mNarrowPhaseSphereVsSphereAlgorithm;
|
SphereVsSphereAlgorithm mNarrowPhaseSphereVsSphereAlgorithm;
|
||||||
|
|
||||||
// Memory pool for contactinfo
|
/// Memory pool for contactinfo
|
||||||
MemoryPool<ContactInfo> mMemoryPoolContactInfos;
|
MemoryPool<ContactInfo> mMemoryPoolContactInfos;
|
||||||
|
|
||||||
// Memory pool for broad-phase pairs
|
/// Memory pool for broad-phase pairs
|
||||||
MemoryPool<BroadPhasePair> mMemoryPoolBroadPhasePairs;
|
MemoryPool<BroadPhasePair> mMemoryPoolBroadPhasePairs;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
CollisionDetection(const CollisionDetection& collisionDetection);
|
CollisionDetection(const CollisionDetection& collisionDetection);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
CollisionDetection& operator=(const CollisionDetection& collisionDetection);
|
CollisionDetection& operator=(const CollisionDetection& collisionDetection);
|
||||||
|
|
||||||
// Compute the broad-phase collision detection
|
/// Compute the broad-phase collision detection
|
||||||
void computeBroadPhase();
|
void computeBroadPhase();
|
||||||
|
|
||||||
// Compute the narrow-phase collision detection
|
/// Compute the narrow-phase collision detection
|
||||||
bool computeNarrowPhase();
|
bool computeNarrowPhase();
|
||||||
|
|
||||||
// Select the narrow phase algorithm to use given two collision shapes
|
/// Select the narrow phase algorithm to use given two collision shapes
|
||||||
NarrowPhaseAlgorithm& SelectNarrowPhaseAlgorithm(CollisionShape* collisionShape1,
|
NarrowPhaseAlgorithm& SelectNarrowPhaseAlgorithm(CollisionShape* collisionShape1,
|
||||||
CollisionShape* collisionShape2);
|
CollisionShape* collisionShape2);
|
||||||
|
|
||||||
|
@ -105,25 +104,25 @@ class CollisionDetection {
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
CollisionDetection(CollisionWorld* world);
|
CollisionDetection(CollisionWorld* world);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~CollisionDetection();
|
~CollisionDetection();
|
||||||
|
|
||||||
// Add a body to the collision detection
|
/// Add a body to the collision detection
|
||||||
void addBody(CollisionBody* body);
|
void addBody(CollisionBody* body);
|
||||||
|
|
||||||
// Remove a body from the collision detection
|
/// Remove a body from the collision detection
|
||||||
void removeBody(CollisionBody* body);
|
void removeBody(CollisionBody* body);
|
||||||
|
|
||||||
// Compute the collision detection
|
/// Compute the collision detection
|
||||||
bool computeCollisionDetection();
|
bool computeCollisionDetection();
|
||||||
|
|
||||||
// Allow the broadphase to notify the collision detection about a new overlapping pair
|
/// Allow the broadphase to notify the collision detection about a new overlapping pair.
|
||||||
void broadPhaseNotifyAddedOverlappingPair(BodyPair* pair);
|
void broadPhaseNotifyAddedOverlappingPair(BodyPair* pair);
|
||||||
|
|
||||||
// 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 broadPhaseNotifyRemovedOverlappingPair(BodyPair* pair);
|
void broadPhaseNotifyRemovedOverlappingPair(BodyPair* pair);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,45 +33,44 @@
|
||||||
// ReactPhysics3D namespace
|
// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Structure ContactInfo
|
||||||
Structure ContactInfo :
|
/**
|
||||||
This structure contains informations about a collision contact
|
* This structure contains informations about a collision contact
|
||||||
computed during the narrow-phase collision detection. Those
|
* computed during the narrow-phase collision detection. Those
|
||||||
informations are use to compute the contact set for a contact
|
* informations are used to compute the contact set for a contact
|
||||||
between two bodies.
|
* between two bodies.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
struct ContactInfo {
|
struct ContactInfo {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
ContactInfo(const ContactInfo& contactInfo);
|
ContactInfo(const ContactInfo& contactInfo);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
ContactInfo& operator=(const ContactInfo& contactInfo);
|
ContactInfo& operator=(const ContactInfo& contactInfo);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Normal vector the the collision contact in world space
|
/// Normal vector the the collision contact in world space
|
||||||
const Vector3 normal;
|
const Vector3 normal;
|
||||||
|
|
||||||
// Penetration depth of the contact
|
/// Penetration depth of the contact
|
||||||
const decimal penetrationDepth;
|
const decimal penetrationDepth;
|
||||||
|
|
||||||
// Contact point of body 1 in local space of body 1
|
/// Contact point of body 1 in local space of body 1
|
||||||
const Vector3 localPoint1;
|
const Vector3 localPoint1;
|
||||||
|
|
||||||
// Contact point of body 2 in local space of body 2
|
/// Contact point of body 2 in local space of body 2
|
||||||
const Vector3 localPoint2;
|
const Vector3 localPoint2;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
ContactInfo(const Vector3& normal, decimal penetrationDepth,
|
ContactInfo(const Vector3& normal, decimal penetrationDepth,
|
||||||
const Vector3& localPoint1, const Vector3& localPoint2);
|
const Vector3& localPoint1, const Vector3& localPoint2);
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,68 +31,67 @@
|
||||||
#include "../../body/CollisionBody.h"
|
#include "../../body/CollisionBody.h"
|
||||||
#include "PairManager.h"
|
#include "PairManager.h"
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
/// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
class CollisionDetection;
|
class CollisionDetection;
|
||||||
|
|
||||||
/* --------------------------------------------------------------------
|
// Class BroadPhaseAlgorithm
|
||||||
Class BroadPhaseAlgorithm :
|
/**
|
||||||
This class is an abstract class that represents an algorithm
|
* This class is an abstract class that represents an algorithm
|
||||||
used to perform the broad-phase of a collision detection. The
|
* used to perform the broad-phase of a collision detection. The
|
||||||
goal of the broad-phase algorithm is to compute the pair of bodies
|
* goal of the broad-phase algorithm is to compute the pair of bodies
|
||||||
that can collide. But it's important to understand that the
|
* that can collide. But it's important to understand that the
|
||||||
broad-phase doesn't compute only body pairs that can collide but
|
* broad-phase doesn't compute only body pairs that can collide but
|
||||||
could also pairs of body that doesn't collide but are very close.
|
* could also pairs of body that doesn't collide but are very close.
|
||||||
The goal of the broad-phase is to remove pairs of body that cannot
|
* The goal of the broad-phase is to remove pairs of body that cannot
|
||||||
collide in order to avoid to much bodies to be tested in the
|
* collide in order to avoid to much bodies to be tested in the
|
||||||
narrow-phase.
|
* narrow-phase.
|
||||||
--------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class BroadPhaseAlgorithm {
|
class BroadPhaseAlgorithm {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Pair manager containing the overlapping pairs
|
/// Pair manager containing the overlapping pairs
|
||||||
PairManager mPairManager;
|
PairManager mPairManager;
|
||||||
|
|
||||||
// Reference to the collision detection object
|
/// Reference to the collision detection object
|
||||||
CollisionDetection& mCollisionDetection;
|
CollisionDetection& mCollisionDetection;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
BroadPhaseAlgorithm(const BroadPhaseAlgorithm& algorithm);
|
BroadPhaseAlgorithm(const BroadPhaseAlgorithm& algorithm);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
BroadPhaseAlgorithm& operator=(const BroadPhaseAlgorithm& algorithm);
|
BroadPhaseAlgorithm& operator=(const BroadPhaseAlgorithm& algorithm);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
BroadPhaseAlgorithm(CollisionDetection& collisionDetection);
|
BroadPhaseAlgorithm(CollisionDetection& collisionDetection);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~BroadPhaseAlgorithm();
|
virtual ~BroadPhaseAlgorithm();
|
||||||
|
|
||||||
// Notify the broad-phase about a new object in the world
|
/// Notify the broad-phase about a new object in the world
|
||||||
virtual void addObject(CollisionBody* body, const AABB& aabb)=0;
|
virtual void addObject(CollisionBody* body, const AABB& aabb)=0;
|
||||||
|
|
||||||
// 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
|
||||||
virtual void removeObject(CollisionBody* body)=0;
|
virtual void removeObject(CollisionBody* body)=0;
|
||||||
|
|
||||||
// Notify the broad-phase that the AABB of an object has changed
|
/// Notify the broad-phase that the AABB of an object has changed
|
||||||
virtual void updateObject(CollisionBody* body, const AABB& aabb)=0;
|
virtual void updateObject(CollisionBody* body, const AABB& aabb)=0;
|
||||||
|
|
||||||
// Return a pointer to the first active pair (used to iterate over the active pairs)
|
/// Return a pointer to the first active pair (used to iterate over the active pairs)
|
||||||
BodyPair* beginOverlappingPairsPointer() const;
|
BodyPair* beginOverlappingPairsPointer() const;
|
||||||
|
|
||||||
// Return a pointer to the last active pair (used to iterate over the active pairs)
|
/// Return a pointer to the last active pair (used to iterate over the active pairs)
|
||||||
BodyPair* endOverlappingPairsPointer() const;
|
BodyPair* endOverlappingPairsPointer() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,50 +32,49 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
/// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* --------------------------------------------------------------------
|
// Class NoBroadPhaseAlgorithm
|
||||||
Class NoBroadPhaseAlgorithm :
|
/**
|
||||||
This class implements a broad-phase algorithm that does nothing.
|
* This class implements a broad-phase algorithm that does nothing.
|
||||||
It should be use if we don't want to perform a broad-phase for
|
* It should be use if we don't want to perform a broad-phase for
|
||||||
the collision detection.
|
* the collision detection.
|
||||||
--------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class NoBroadPhaseAlgorithm : public BroadPhaseAlgorithm {
|
class NoBroadPhaseAlgorithm : public BroadPhaseAlgorithm {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// All bodies of the world
|
/// All bodies of the world
|
||||||
std::set<CollisionBody*> mBodies;
|
std::set<CollisionBody*> mBodies;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
NoBroadPhaseAlgorithm(const NoBroadPhaseAlgorithm& algorithm);
|
NoBroadPhaseAlgorithm(const NoBroadPhaseAlgorithm& algorithm);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
NoBroadPhaseAlgorithm& operator=(const NoBroadPhaseAlgorithm& algorithm);
|
NoBroadPhaseAlgorithm& operator=(const NoBroadPhaseAlgorithm& algorithm);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
NoBroadPhaseAlgorithm(CollisionDetection& collisionDetection);
|
NoBroadPhaseAlgorithm(CollisionDetection& collisionDetection);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~NoBroadPhaseAlgorithm();
|
virtual ~NoBroadPhaseAlgorithm();
|
||||||
|
|
||||||
// Notify the broad-phase about a new object in the world
|
/// Notify the broad-phase about a new object in the world
|
||||||
virtual void addObject(CollisionBody* body, const AABB& aabb);
|
virtual void addObject(CollisionBody* 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
|
||||||
virtual void removeObject(CollisionBody* body);
|
virtual void removeObject(CollisionBody* 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
|
||||||
virtual void updateObject(CollisionBody* body, const AABB& aabb);
|
virtual void updateObject(CollisionBody* body, const AABB& aabb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,10 @@ PairManager::~PairManager() {
|
||||||
free(mHashTable);
|
free(mHashTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a pair of bodies in the pair manager and returns a pointer to
|
// Add a pair of bodies in the pair manager and returns a pointer to that pair.
|
||||||
// that pair. If the pair to add does not already exist in the set of
|
/// 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.
|
||||||
BodyPair* PairManager::addPair(CollisionBody* body1, CollisionBody* 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
|
||||||
|
@ -109,8 +109,8 @@ BodyPair* PairManager::addPair(CollisionBody* body1, CollisionBody* body2) {
|
||||||
return newPair;
|
return newPair;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a pair of bodies from the pair manager. This method returns
|
// Remove a pair of bodies from the pair manager.
|
||||||
// true if the pair has been found and removed.
|
/// This method returns true if the pair has been found and removed.
|
||||||
bool PairManager::removePair(bodyindex id1, bodyindex id2) {
|
bool PairManager::removePair(bodyindex id1, bodyindex id2) {
|
||||||
|
|
||||||
// Sort the bodies IDs
|
// Sort the bodies IDs
|
||||||
|
|
|
@ -31,23 +31,28 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
/// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Declaration
|
// Declaration
|
||||||
class CollisionDetection;
|
class CollisionDetection;
|
||||||
|
|
||||||
// struct BodyPair
|
// Structure BodyPair
|
||||||
// This structure represents a pair of bodies
|
/**
|
||||||
// during the broad-phase collision detection
|
* This structure represents a pair of bodies
|
||||||
|
* during the broad-phase collision detection.
|
||||||
|
*/
|
||||||
struct BodyPair {
|
struct BodyPair {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CollisionBody* body1; // Pointer to the first body
|
/// Pointer to the first body
|
||||||
CollisionBody* body2; // Pointer to the second body
|
CollisionBody* body1;
|
||||||
|
|
||||||
// Return the pair of bodies index
|
/// Pointer to the second body
|
||||||
|
CollisionBody* body2;
|
||||||
|
|
||||||
|
/// Return the pair of bodies index
|
||||||
bodyindexpair getBodiesIndexPair() const {
|
bodyindexpair getBodiesIndexPair() const {
|
||||||
|
|
||||||
// Construct the pair of body index
|
// Construct the pair of body index
|
||||||
|
@ -60,88 +65,87 @@ struct BodyPair {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* --------------------------------------------------------------------
|
// Class PairManager
|
||||||
Class PairManager :
|
/**
|
||||||
This class is a data-structure contains the pairs of bodies that
|
* This class is a data-structure contains the pairs of bodies that
|
||||||
are overlapping during the broad-phase collision detection.
|
* are overlapping during the broad-phase collision detection.
|
||||||
This class implements the pair manager described by Pierre Terdiman
|
* This class implements the pair manager described by Pierre Terdiman
|
||||||
in www.codercorner.com/SAP.pdf.
|
* in www.codercorner.com/SAP.pdf.
|
||||||
--------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class PairManager {
|
class PairManager {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Number of elements in the hash table
|
/// Number of elements in the hash table
|
||||||
bodyindex mNbElementsHashTable;
|
bodyindex mNbElementsHashTable;
|
||||||
|
|
||||||
// Hash mask for the hash function
|
/// Hash mask for the hash function
|
||||||
uint mHashMask;
|
uint mHashMask;
|
||||||
|
|
||||||
// Number of overlapping pairs
|
/// Number of overlapping pairs
|
||||||
bodyindex mNbOverlappingPairs;
|
bodyindex mNbOverlappingPairs;
|
||||||
|
|
||||||
// Hash table that contains the offset of the first pair of the list of
|
/// Hash table that contains the offset of the first pair of the list of
|
||||||
// pairs with the same hash value in the "overlappingPairs" array
|
/// pairs with the same hash value in the "overlappingPairs" array
|
||||||
bodyindex* mHashTable;
|
bodyindex* mHashTable;
|
||||||
|
|
||||||
// Array that contains for each offset, the offset of the next pair with
|
/// Array that contains for each offset, the offset of the next pair with
|
||||||
// the same hash value for a given same hash value
|
/// the same hash value for a given same hash value
|
||||||
bodyindex* mOffsetNextPair;
|
bodyindex* mOffsetNextPair;
|
||||||
|
|
||||||
// Array that contains the overlapping pairs
|
/// Array that contains the overlapping pairs
|
||||||
BodyPair* mOverlappingPairs;
|
BodyPair* mOverlappingPairs;
|
||||||
|
|
||||||
// Invalid ID
|
/// Invalid ID
|
||||||
static bodyindex INVALID_INDEX;
|
static bodyindex INVALID_INDEX;
|
||||||
|
|
||||||
// Reference to the collision detection
|
/// Reference to the collision detection
|
||||||
CollisionDetection& mCollisionDetection;
|
CollisionDetection& mCollisionDetection;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
PairManager(const PairManager& pairManager);
|
PairManager(const PairManager& pairManager);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
PairManager& operator=(const PairManager& pairManager);
|
PairManager& operator=(const PairManager& pairManager);
|
||||||
|
|
||||||
// Sort the bodies according to their IDs (smallest ID first)
|
/// Sort the bodies according to their IDs (smallest ID first)
|
||||||
void sortBodiesUsingID(CollisionBody*& body1, CollisionBody*& body2) const;
|
void sortBodiesUsingID(CollisionBody*& body1, CollisionBody*& body2) const;
|
||||||
|
|
||||||
// Sort the IDs (smallest ID first)
|
/// Sort the IDs (smallest ID first)
|
||||||
void sortIDs(bodyindex& id1, bodyindex& id2) const;
|
void sortIDs(bodyindex& id1, bodyindex& id2) const;
|
||||||
|
|
||||||
// Return true if pair1 and pair2 are the same
|
/// Return true if pair1 and pair2 are the same
|
||||||
bool isDifferentPair(const BodyPair& pair1, bodyindex pair2ID1, bodyindex pair2ID2) const;
|
bool isDifferentPair(const BodyPair& pair1, bodyindex pair2ID1, bodyindex pair2ID2) const;
|
||||||
|
|
||||||
// Compute the hash value of two bodies using their IDs
|
/// Compute the hash value of two bodies using their IDs
|
||||||
uint computeHashBodies(uint id1, uint id2) const;
|
uint computeHashBodies(uint id1, uint id2) const;
|
||||||
|
|
||||||
// This method returns an hash value for a 32 bits key
|
/// This method returns an hash value for a 32 bits key.
|
||||||
int computeHash32Bits(int key) const;
|
int computeHash32Bits(int key) const;
|
||||||
|
|
||||||
// Return the next power of two
|
/// Return the next power of two
|
||||||
luint computeNextPowerOfTwo(luint number) const;
|
luint computeNextPowerOfTwo(luint number) const;
|
||||||
|
|
||||||
// Reallocate memory for more pairs
|
/// Reallocate memory for more pairs
|
||||||
void reallocatePairs();
|
void reallocatePairs();
|
||||||
|
|
||||||
// Shrink the allocated memory
|
/// Shrink the allocated memory
|
||||||
void shrinkMemory();
|
void shrinkMemory();
|
||||||
|
|
||||||
// Compute the offset of a given pair
|
/// Compute the offset of a given pair
|
||||||
bodyindex computePairOffset(const BodyPair* pair) const;
|
bodyindex computePairOffset(const BodyPair* pair) const;
|
||||||
|
|
||||||
// Look for a pair in the set of overlapping pairs
|
/// Look for a pair in the set of overlapping pairs
|
||||||
BodyPair* lookForAPair(bodyindex id1, bodyindex id2, luint hashValue) const;
|
BodyPair* lookForAPair(bodyindex id1, bodyindex id2, luint hashValue) const;
|
||||||
|
|
||||||
// Find a pair given two body IDs and an hash value
|
/// Find a pair given two body IDs and an hash value.
|
||||||
BodyPair* findPairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue) const;
|
BodyPair* findPairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue) const;
|
||||||
|
|
||||||
// Remove a pair from the set of active pair
|
/// Remove a pair from the set of active pair
|
||||||
void removePairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue,
|
void removePairWithHashValue(bodyindex id1, bodyindex id2, luint hashValue,
|
||||||
bodyindex indexPair);
|
bodyindex indexPair);
|
||||||
|
|
||||||
|
@ -149,48 +153,48 @@ class PairManager {
|
||||||
|
|
||||||
// ----- Methods ----- //
|
// ----- Methods ----- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
PairManager(CollisionDetection& collisionDetection);
|
PairManager(CollisionDetection& collisionDetection);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~PairManager();
|
~PairManager();
|
||||||
|
|
||||||
// Return the number of active pairs
|
/// Return the number of active pairs
|
||||||
bodyindex getNbOverlappingPairs() const;
|
bodyindex getNbOverlappingPairs() const;
|
||||||
|
|
||||||
// Add a pair of bodies in the pair manager
|
/// Add a pair of bodies in the pair manager and returns a pointer to that pair.
|
||||||
BodyPair* addPair(CollisionBody* body1, CollisionBody* body2);
|
BodyPair* addPair(CollisionBody* body1, CollisionBody* body2);
|
||||||
|
|
||||||
// Remove a pair of bodies from the pair manager
|
/// Remove a pair of bodies from the pair manager.
|
||||||
bool removePair(bodyindex id1, bodyindex id2);
|
bool removePair(bodyindex id1, bodyindex id2);
|
||||||
|
|
||||||
// Find a pair given two body IDs
|
/// Find a pair given two body IDs
|
||||||
BodyPair* findPair(bodyindex id1, bodyindex id2) const;
|
BodyPair* findPair(bodyindex id1, bodyindex id2) const;
|
||||||
|
|
||||||
// Return a pointer to the first overlapping pair (used to
|
/// Return a pointer to the first overlapping pair (used to
|
||||||
// iterate over the active pairs)
|
/// iterate over the active pairs).
|
||||||
BodyPair* beginOverlappingPairsPointer() const;
|
BodyPair* beginOverlappingPairsPointer() const;
|
||||||
|
|
||||||
// Return a pointer to the last overlapping pair (used to
|
/// Return a pointer to the last overlapping pair (used to
|
||||||
// iterate over the active pairs)
|
/// iterate over the active pairs).
|
||||||
BodyPair* endOverlappingPairsPointer() const;
|
BodyPair* endOverlappingPairsPointer() const;
|
||||||
|
|
||||||
// Register a callback function (using a function pointer) that will be
|
/// Register a callback function (using a function pointer) that will be
|
||||||
// called when a new overlapping pair is added in the pair manager
|
/// called when a new overlapping pair is added in the pair manager.
|
||||||
void registerAddedOverlappingPairCallback(void (CollisionDetection::*callbackFunction)
|
void registerAddedOverlappingPairCallback(void (CollisionDetection::*callbackFunction)
|
||||||
(const BodyPair* addedActivePair));
|
(const BodyPair* addedActivePair));
|
||||||
|
|
||||||
// Unregister the callback function that will be called
|
/// Unregister the callback function that will be called
|
||||||
// when a new active pair is added in the pair manager
|
/// when a new active pair is added in the pair manager
|
||||||
void unregisterAddedOverlappingPairCallback();
|
void unregisterAddedOverlappingPairCallback();
|
||||||
|
|
||||||
// Register a callback function (using a function pointer)
|
/// Register a callback function (using a function pointer)
|
||||||
// that will be called when an overlapping pair is removed from the pair manager
|
/// that will be called when an overlapping pair is removed from the pair manager
|
||||||
void registerRemovedOverlappingPairCallback(void (CollisionDetection::*callbackFunction)
|
void registerRemovedOverlappingPairCallback(void (CollisionDetection::*callbackFunction)
|
||||||
(const BodyPair* removedActivePair));
|
(const BodyPair* removedActivePair));
|
||||||
|
|
||||||
// Unregister a callback function that will be called
|
/// Unregister a callback function that will be called
|
||||||
// when a active pair is removed from the pair manager
|
/// when a active pair is removed from the pair manager
|
||||||
void unregisterRemovedOverlappingPairCallback();
|
void unregisterRemovedOverlappingPairCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -242,10 +246,10 @@ inline void PairManager::sortIDs(bodyindex &id1, bodyindex &id2) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method returns an hash value for a 32 bits key
|
// This method returns an hash value for a 32 bits key.
|
||||||
// using Thomas Wang's hash technique.
|
/// using Thomas Wang's hash technique.
|
||||||
// This hash function can be found at :
|
/// This hash function can be found at :
|
||||||
// http://www.concentric.net/~ttwang/tech/inthash.htm
|
/// http://www.concentric.net/~ttwang/tech/inthash.htm
|
||||||
inline int PairManager::computeHash32Bits(int key) const {
|
inline int PairManager::computeHash32Bits(int key) const {
|
||||||
key += ~(key << 15);
|
key += ~(key << 15);
|
||||||
key ^= (key >> 10);
|
key ^= (key >> 10);
|
||||||
|
@ -272,9 +276,9 @@ inline BodyPair* PairManager::findPair(bodyindex id1, bodyindex id2) const {
|
||||||
lookForAPair(id1, id2, hashValue);
|
lookForAPair(id1, id2, hashValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 BodyPair* PairManager::findPairWithHashValue(bodyindex id1, bodyindex id2,
|
inline BodyPair* PairManager::findPairWithHashValue(bodyindex id1, bodyindex id2,
|
||||||
luint hashValue) const {
|
luint hashValue) const {
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,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(CollisionBody* body, const AABB& aabb) {
|
void SweepAndPruneAlgorithm::addObject(CollisionBody* body, const AABB& aabb) {
|
||||||
bodyindex boxIndex;
|
bodyindex boxIndex;
|
||||||
|
|
||||||
|
|
|
@ -33,20 +33,28 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
/// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// EndPoint structure that represent an end-point of an AABB
|
// Structure EndPoint
|
||||||
// on one of the three x,y or z axis
|
/**
|
||||||
|
* EndPoint structure that represent an end-point of an AABB
|
||||||
|
* on one of the three x,y or z axis.
|
||||||
|
*/
|
||||||
struct EndPoint {
|
struct EndPoint {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bodyindex boxID; // ID of the AABB box corresponding to this end-point
|
/// ID of the AABB box corresponding to this end-point
|
||||||
bool isMin; // True if the end-point is a minimum end-point of a box
|
bodyindex boxID;
|
||||||
uint value; // Value (one dimension coordinate) of the end-point
|
|
||||||
|
|
||||||
// Set the values of the endpoint
|
/// True if the end-point is a minimum end-point of a box
|
||||||
|
bool isMin;
|
||||||
|
|
||||||
|
/// Value (one dimension coordinate) of the end-point
|
||||||
|
uint value;
|
||||||
|
|
||||||
|
/// Set the values of the endpoint
|
||||||
void setValues(bodyindex boxID, bool isMin, uint value) {
|
void setValues(bodyindex boxID, bool isMin, uint value) {
|
||||||
this->boxID = boxID;
|
this->boxID = boxID;
|
||||||
this->isMin = isMin;
|
this->isMin = isMin;
|
||||||
|
@ -54,85 +62,95 @@ struct EndPoint {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Structure BoxAABB that represents an AABB in the
|
// Structure BoxAABB
|
||||||
// Sweep-And-Prune algorithm
|
/**
|
||||||
|
* This structure represents an AABB in the Sweep-And-Prune algorithm
|
||||||
|
*/
|
||||||
struct BoxAABB {
|
struct BoxAABB {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bodyindex min[3]; // Index of the 3 minimum end-points of the AABB over the x,y,z axis
|
/// Index of the 3 minimum end-points of the AABB over the x,y,z axis
|
||||||
bodyindex max[3]; // Index of the 3 maximum end-points of the AABB over the x,y,z axis
|
bodyindex min[3];
|
||||||
CollisionBody* body; // Body that corresponds to the owner of the AABB
|
|
||||||
|
/// Index of the 3 maximum end-points of the AABB over the x,y,z axis
|
||||||
|
bodyindex max[3];
|
||||||
|
|
||||||
|
/// Body that corresponds to the owner of the AABB
|
||||||
|
CollisionBody* body;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Structure AABBInt
|
// Structure AABBInt
|
||||||
// Axis-Aligned Bounding box with integer coordinates
|
/**
|
||||||
|
* Axis-Aligned Bounding box with integer coordinates.
|
||||||
|
*/
|
||||||
struct AABBInt {
|
struct AABBInt {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint min[3]; // Minimum values on the three axis
|
/// Minimum values on the three axis
|
||||||
uint max[3]; // Maximum values on the three axis
|
uint min[3];
|
||||||
|
|
||||||
// Constructor
|
/// Maximum values on the three axis
|
||||||
|
uint max[3];
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
AABBInt(const AABB& aabb);
|
AABBInt(const AABB& aabb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Class SweepAndPruneAlgorithm
|
||||||
/* --------------------------------------------------------------------
|
/**
|
||||||
Class SweepAndPruneAlgorithm :
|
* This class implements the Sweep-And-Prune (SAP) broad-phase
|
||||||
This class implements the Sweep-And-Prune (SAP) broad-phase
|
* collision detection algorithm. This class implements an
|
||||||
collision detection algorithm. This class implements an
|
* array-based implementation of the algorithm from Pierre Terdiman
|
||||||
array-based implementation of the algorithm from Pierre Terdiman
|
* that is described here : www.codercorner.com/SAP.pdf.
|
||||||
that is described here : www.codercorner.com/SAP.pdf.
|
*/
|
||||||
--------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
class SweepAndPruneAlgorithm : public BroadPhaseAlgorithm {
|
class SweepAndPruneAlgorithm : public BroadPhaseAlgorithm {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Invalid array index
|
/// Invalid array index
|
||||||
static bodyindex INVALID_INDEX;
|
static bodyindex INVALID_INDEX;
|
||||||
|
|
||||||
// Array that contains all the AABB boxes of the broad-phase
|
/// Array that contains all the AABB boxes of the broad-phase
|
||||||
BoxAABB* mBoxes;
|
BoxAABB* mBoxes;
|
||||||
|
|
||||||
// Array of end-points on the three axis
|
/// Array of end-points on the three axis
|
||||||
EndPoint* mEndPoints[3];
|
EndPoint* mEndPoints[3];
|
||||||
|
|
||||||
// Number of AABB boxes in the broad-phase
|
/// Number of AABB boxes in the broad-phase
|
||||||
bodyindex mNbBoxes;
|
bodyindex mNbBoxes;
|
||||||
|
|
||||||
// Max number of boxes in the boxes array
|
/// Max number of boxes in the boxes array
|
||||||
bodyindex mNbMaxBoxes;
|
bodyindex mNbMaxBoxes;
|
||||||
|
|
||||||
// Indices that are not used by any boxes
|
/// Indices that are not used by any boxes
|
||||||
std::vector<bodyindex> mFreeBoxIndices;
|
std::vector<bodyindex> mFreeBoxIndices;
|
||||||
|
|
||||||
// Map a body pointer to a box index
|
/// Map a body pointer to a box index
|
||||||
std::map<CollisionBody*,bodyindex> mMapBodyToBoxIndex;
|
std::map<CollisionBody*,bodyindex> mMapBodyToBoxIndex;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
SweepAndPruneAlgorithm(const SweepAndPruneAlgorithm& algorithm);
|
SweepAndPruneAlgorithm(const SweepAndPruneAlgorithm& algorithm);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
SweepAndPruneAlgorithm& operator=(const SweepAndPruneAlgorithm& algorithm);
|
SweepAndPruneAlgorithm& operator=(const SweepAndPruneAlgorithm& algorithm);
|
||||||
|
|
||||||
// Resize the boxes and end-points arrays when it's full
|
/// Resize the boxes and end-points arrays when it's full
|
||||||
void resizeArrays();
|
void resizeArrays();
|
||||||
|
|
||||||
// Add an overlapping pair of AABBS
|
/// Add an overlapping pair of AABBS
|
||||||
void addPair(CollisionBody* body1, CollisionBody* body2);
|
void addPair(CollisionBody* body1, CollisionBody* body2);
|
||||||
|
|
||||||
// Check for 1D box intersection
|
/// Check for 1D box intersection between two boxes that are sorted on the given axis.
|
||||||
bool testIntersect1DSortedAABBs(const BoxAABB& box1, const AABBInt& box2,
|
bool testIntersect1DSortedAABBs(const BoxAABB& box1, const AABBInt& box2,
|
||||||
const EndPoint* const baseEndPoint, uint axis) const;
|
const EndPoint* const baseEndPoint, uint axis) const;
|
||||||
|
|
||||||
// Check for 2D box intersection
|
/// Check for 2D box intersection.
|
||||||
bool testIntersect2D(const BoxAABB& box1, const BoxAABB& box2,
|
bool testIntersect2D(const BoxAABB& box1, const BoxAABB& box2,
|
||||||
luint axis1, uint axis2) const;
|
luint axis1, uint axis2) const;
|
||||||
|
|
||||||
|
@ -140,28 +158,28 @@ class SweepAndPruneAlgorithm : public BroadPhaseAlgorithm {
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
SweepAndPruneAlgorithm(CollisionDetection& mCollisionDetection);
|
SweepAndPruneAlgorithm(CollisionDetection& mCollisionDetection);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~SweepAndPruneAlgorithm();
|
virtual ~SweepAndPruneAlgorithm();
|
||||||
|
|
||||||
// Notify the broad-phase about a new object in the world
|
/// Notify the broad-phase about a new object in the world.
|
||||||
virtual void addObject(CollisionBody* body, const AABB& aabb);
|
virtual void addObject(CollisionBody* 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
|
||||||
virtual void removeObject(CollisionBody* body);
|
virtual void removeObject(CollisionBody* 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
|
||||||
virtual void updateObject(CollisionBody* body, const AABB& aabb);
|
virtual void updateObject(CollisionBody* body, const AABB& aabb);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Encode a floating value into a integer value in order to
|
/// Encode a floating value into a integer value in order to
|
||||||
// work with integer comparison in the Sweep-And-Prune algorithm
|
/// work with integer comparison in the Sweep-And-Prune algorithm
|
||||||
// because it is faster. The main issue when encoding floating
|
/// because it is faster. The main issue when encoding floating
|
||||||
// number into integer is to keep to sorting order. This is a
|
/// number into integer is to keep to sorting order. This is a
|
||||||
// problem for negative float number. This article describes
|
/// problem for negative float number. This article describes
|
||||||
// how to solve this issue : http://www.stereopsis.com/radix.html
|
/// how to solve this issue : http://www.stereopsis.com/radix.html
|
||||||
inline uint encodeFloatIntoInteger(float number) {
|
inline uint encodeFloatIntoInteger(float number) {
|
||||||
uint intNumber = (uint&) number;
|
uint intNumber = (uint&) number;
|
||||||
|
|
||||||
|
@ -176,9 +194,9 @@ inline uint encodeFloatIntoInteger(float number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check for 1D box intersection between two boxes that are sorted on the
|
// Check for 1D box intersection between two boxes that are sorted on the given axis.
|
||||||
// given axis. Therefore, only one test is necessary here. We know that the
|
/// Therefore, only one test is necessary here. We know that the
|
||||||
// minimum of box1 cannot be larger that the maximum of box2 on the axis.
|
/// minimum of box1 cannot be larger that the maximum of box2 on the axis.
|
||||||
inline bool SweepAndPruneAlgorithm::testIntersect1DSortedAABBs(const BoxAABB& box1,
|
inline bool SweepAndPruneAlgorithm::testIntersect1DSortedAABBs(const BoxAABB& box1,
|
||||||
const AABBInt& box2,
|
const AABBInt& box2,
|
||||||
const EndPoint* const endPointsArray,
|
const EndPoint* const endPointsArray,
|
||||||
|
@ -187,15 +205,15 @@ inline bool SweepAndPruneAlgorithm::testIntersect1DSortedAABBs(const BoxAABB& bo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for 2D box intersection. This method is used when we know
|
// Check for 2D box intersection. This method is used when we know
|
||||||
// that two boxes already overlap on one axis and when want to test
|
/// that two boxes already overlap on one axis and when want to test
|
||||||
// if they also overlap on the two others axis.
|
/// if they also overlap on the two others axis.
|
||||||
inline bool SweepAndPruneAlgorithm::testIntersect2D(const BoxAABB& box1, const BoxAABB& box2,
|
inline bool SweepAndPruneAlgorithm::testIntersect2D(const BoxAABB& box1, const BoxAABB& box2,
|
||||||
luint axis1, uint axis2) const {
|
luint axis1, uint axis2) const {
|
||||||
return !(box2.max[axis1] < box1.min[axis1] || box1.max[axis1] < box2.min[axis1] ||
|
return !(box2.max[axis1] < box1.min[axis1] || box1.max[axis1] < box2.min[axis1] ||
|
||||||
box2.max[axis2] < box1.min[axis2] || box1.max[axis2] < box2.min[axis2]);
|
box2.max[axis2] < box1.min[axis2] || box1.max[axis2] < box2.min[axis2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of reactphysics3d namespace
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -42,9 +42,9 @@ EPAAlgorithm::~EPAAlgorithm() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decide if the origin is in the tetrahedron
|
// Decide if the origin is in the tetrahedron.
|
||||||
// Return 0 if the origin is in the tetrahedron and return the number (1,2,3 or 4) of
|
/// Return 0 if the origin is in the tetrahedron and return the number (1,2,3 or 4) of
|
||||||
// the vertex that is wrong if the origin is not in the tetrahedron
|
/// the vertex that is wrong if the origin is not in the tetrahedron
|
||||||
int EPAAlgorithm::isOriginInTetrahedron(const Vector3& p1, const Vector3& p2,
|
int EPAAlgorithm::isOriginInTetrahedron(const Vector3& p1, const Vector3& p2,
|
||||||
const Vector3& p3, const Vector3& p4) const {
|
const Vector3& p3, const Vector3& p4) const {
|
||||||
|
|
||||||
|
@ -76,12 +76,12 @@ int EPAAlgorithm::isOriginInTetrahedron(const Vector3& p1, const Vector3& p2,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the penetration depth with the EPA algorithms
|
// Compute the penetration depth with the EPA algorithm.
|
||||||
// This method computes the penetration depth and contact points between two
|
/// This method computes the penetration depth and contact points between two
|
||||||
// enlarged objects (with margin) where the original objects (without margin)
|
/// enlarged objects (with margin) where the original objects (without margin)
|
||||||
// intersect. An initial simplex that contains origin has been computed with
|
/// intersect. An initial simplex that contains origin has been computed with
|
||||||
// GJK algorithm. The EPA Algorithm will extend this simplex polytope to find
|
/// GJK algorithm. The EPA Algorithm will extend this simplex polytope to find
|
||||||
// the correct penetration depth
|
/// the correct penetration depth
|
||||||
bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simplex,
|
bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simplex,
|
||||||
const CollisionShape* collisionShape1,
|
const CollisionShape* collisionShape1,
|
||||||
const Transform& transform1,
|
const Transform& transform1,
|
||||||
|
|
|
@ -35,67 +35,75 @@
|
||||||
#include "../../../memory/MemoryPool.h"
|
#include "../../../memory/MemoryPool.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Constants
|
// ---------- Constants ---------- //
|
||||||
const unsigned int MAX_SUPPORT_POINTS = 100; // Maximum number of support points of the polytope
|
|
||||||
const unsigned int MAX_FACETS = 200; // Maximum number of facets of the polytope
|
/// Maximum number of support points of the polytope
|
||||||
|
const unsigned int MAX_SUPPORT_POINTS = 100;
|
||||||
|
|
||||||
|
/// Maximum number of facets of the polytope
|
||||||
|
const unsigned int MAX_FACETS = 200;
|
||||||
|
|
||||||
|
|
||||||
// Class TriangleComparison that allow the comparison of two triangles in the heap
|
// Class TriangleComparison
|
||||||
// The comparison between two triangles is made using their square distance to the closest
|
/**
|
||||||
// point to the origin. The goal is that in the heap, the first triangle is the one with the
|
* This class allows the comparison of two triangles in the heap
|
||||||
// smallest square distance.
|
* The comparison between two triangles is made using their square distance to the closest
|
||||||
|
* point to the origin. The goal is that in the heap, the first triangle is the one with the
|
||||||
|
* smallest square distance.
|
||||||
|
*/
|
||||||
class TriangleComparison {
|
class TriangleComparison {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Comparison operator
|
|
||||||
|
/// Comparison operator
|
||||||
bool operator()(const TriangleEPA* face1, const TriangleEPA* face2) {
|
bool operator()(const TriangleEPA* face1, const TriangleEPA* face2) {
|
||||||
return (face1->getDistSquare() > face2->getDistSquare());
|
return (face1->getDistSquare() > face2->getDistSquare());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class EPAAlgorithm
|
||||||
Class EPAAlgorithm :
|
/**
|
||||||
This class is the implementation of the Expanding Polytope Algorithm (EPA).
|
* This class is the implementation of the Expanding Polytope Algorithm (EPA).
|
||||||
The EPA algorithm computes the penetration depth and contact points between
|
* The EPA algorithm computes the penetration depth and contact points between
|
||||||
two enlarged objects (with margin) where the original objects (without margin)
|
* two enlarged objects (with margin) where the original objects (without margin)
|
||||||
intersect. The penetration depth of a pair of intersecting objects A and B is
|
* intersect. The penetration depth of a pair of intersecting objects A and B is
|
||||||
the length of a point on the boundary of the Minkowski sum (A-B) closest to the
|
* the length of a point on the boundary of the Minkowski sum (A-B) closest to the
|
||||||
origin. The goal of the EPA algorithm is to start with an initial simplex polytope
|
* origin. The goal of the EPA algorithm is to start with an initial simplex polytope
|
||||||
that contains the origin and expend it in order to find the point on the boundary
|
* that contains the origin and expend it in order to find the point on the boundary
|
||||||
of (A-B) that is closest to the origin. An initial simplex that contains origin
|
* of (A-B) that is closest to the origin. An initial simplex that contains origin
|
||||||
has been computed wit GJK algorithm. The EPA Algorithm will extend this simplex
|
* has been computed wit GJK algorithm. The EPA Algorithm will extend this simplex
|
||||||
polytope to find the correct penetration depth. The implementation of the EPA
|
* polytope to find the correct penetration depth. The implementation of the EPA
|
||||||
algorithm is based on the book "Collision Detection in 3D Environments".
|
* algorithm is based on the book "Collision Detection in 3D Environments".
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class EPAAlgorithm {
|
class EPAAlgorithm {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Reference to the memory pool
|
/// Reference to the memory pool
|
||||||
MemoryPool<ContactInfo>& mMemoryPoolContactInfos;
|
MemoryPool<ContactInfo>& mMemoryPoolContactInfos;
|
||||||
|
|
||||||
// Triangle comparison operator
|
/// Triangle comparison operator
|
||||||
TriangleComparison mTriangleComparison;
|
TriangleComparison mTriangleComparison;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
EPAAlgorithm(const EPAAlgorithm& algorithm);
|
EPAAlgorithm(const EPAAlgorithm& algorithm);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
EPAAlgorithm& operator=(const EPAAlgorithm& algorithm);
|
EPAAlgorithm& operator=(const EPAAlgorithm& algorithm);
|
||||||
|
|
||||||
// Add a triangle face in the candidate triangle heap
|
/// Add a triangle face in the candidate triangle heap
|
||||||
void addFaceCandidate(TriangleEPA* triangle, TriangleEPA** heap, uint& nbTriangles,
|
void addFaceCandidate(TriangleEPA* triangle, TriangleEPA** heap, uint& nbTriangles,
|
||||||
decimal upperBoundSquarePenDepth);
|
decimal upperBoundSquarePenDepth);
|
||||||
|
|
||||||
// Decide if the origin is in the tetrahedron
|
/// Decide if the origin is in the tetrahedron.
|
||||||
int isOriginInTetrahedron(const Vector3& p1, const Vector3& p2,
|
int isOriginInTetrahedron(const Vector3& p1, const Vector3& p2,
|
||||||
const Vector3& p3, const Vector3& p4) const;
|
const Vector3& p3, const Vector3& p4) const;
|
||||||
|
|
||||||
|
@ -103,13 +111,13 @@ class EPAAlgorithm {
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
EPAAlgorithm(MemoryPool<ContactInfo>& memoryPoolContactInfos);
|
EPAAlgorithm(MemoryPool<ContactInfo>& memoryPoolContactInfos);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~EPAAlgorithm();
|
~EPAAlgorithm();
|
||||||
|
|
||||||
// Compute the penetration depth with EPA algorithm
|
/// Compute the penetration depth with EPA algorithm.
|
||||||
bool computePenetrationDepthAndContactPoints(const Simplex& simplex,
|
bool computePenetrationDepthAndContactPoints(const Simplex& simplex,
|
||||||
const CollisionShape* collisionShape1,
|
const CollisionShape* collisionShape1,
|
||||||
const Transform& transform1,
|
const Transform& transform1,
|
||||||
|
|
|
@ -30,64 +30,62 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "../../../mathematics/mathematics.h"
|
#include "../../../mathematics/mathematics.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Class declarations
|
// Class declarations
|
||||||
class TriangleEPA;
|
class TriangleEPA;
|
||||||
class TrianglesStore;
|
class TrianglesStore;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class EdgeEPA
|
||||||
Class EdgeEPA :
|
/**
|
||||||
This class represents an edge of the current polytope in the EPA
|
* This class represents an edge of the current polytope in the EPA algorithm.
|
||||||
algorithm.
|
*/
|
||||||
-------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
class EdgeEPA {
|
class EdgeEPA {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Pointer to the triangle that contains this edge
|
/// Pointer to the triangle that contains this edge
|
||||||
TriangleEPA* mOwnerTriangle;
|
TriangleEPA* mOwnerTriangle;
|
||||||
|
|
||||||
// Index of the edge in the triangle (between 0 and 2).
|
/// Index of the edge in the triangle (between 0 and 2).
|
||||||
// The edge with index i connect triangle vertices i and (i+1 % 3)
|
/// The edge with index i connect triangle vertices i and (i+1 % 3)
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
EdgeEPA();
|
EdgeEPA();
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
EdgeEPA(TriangleEPA* ownerTriangle, int index);
|
EdgeEPA(TriangleEPA* ownerTriangle, int index);
|
||||||
|
|
||||||
// Copy-constructor
|
/// Copy-constructor
|
||||||
EdgeEPA(const EdgeEPA& edge);
|
EdgeEPA(const EdgeEPA& edge);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~EdgeEPA();
|
~EdgeEPA();
|
||||||
|
|
||||||
// Return the pointer to the owner triangle
|
/// Return the pointer to the owner triangle
|
||||||
TriangleEPA* getOwnerTriangle() const;
|
TriangleEPA* getOwnerTriangle() const;
|
||||||
|
|
||||||
// Return the index of the edge in the triangle
|
/// Return the index of the edge in the triangle
|
||||||
int getIndex() const;
|
int getIndex() const;
|
||||||
|
|
||||||
// Return index of the source vertex of the edge
|
/// Return index of the source vertex of the edge
|
||||||
uint getSourceVertexIndex() const;
|
uint getSourceVertexIndex() const;
|
||||||
|
|
||||||
// Return the index of the target vertex of the edge
|
/// Return the index of the target vertex of the edge
|
||||||
uint getTargetVertexIndex() const;
|
uint getTargetVertexIndex() const;
|
||||||
|
|
||||||
// Execute the recursive silhouette algorithm from this edge
|
/// Execute the recursive silhouette algorithm from this edge
|
||||||
bool computeSilhouette(const Vector3* vertices, uint index, TrianglesStore& triangleStore);
|
bool computeSilhouette(const Vector3* vertices, uint index, TrianglesStore& triangleStore);
|
||||||
|
|
||||||
// Assignment operator
|
/// Assignment operator
|
||||||
EdgeEPA& operator=(const EdgeEPA& edge);
|
EdgeEPA& operator=(const EdgeEPA& edge);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -83,9 +83,9 @@ bool TriangleEPA::computeClosestPoint(const Vector3* vertices) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link an edge with another one (meaning that the current edge of a triangle will
|
/// Link an edge with another one. It means that the current edge of a triangle will
|
||||||
// be associated with the edge of another triangle in order that both triangles
|
/// be associated with the edge of another triangle in order that both triangles
|
||||||
// are neighbour along both edges)
|
/// are neighbour along both edges).
|
||||||
bool reactphysics3d::link(const EdgeEPA& edge0, const EdgeEPA& edge1) {
|
bool reactphysics3d::link(const EdgeEPA& edge0, const EdgeEPA& edge1) {
|
||||||
bool isPossible = (edge0.getSourceVertexIndex() == edge1.getTargetVertexIndex() &&
|
bool isPossible = (edge0.getSourceVertexIndex() == edge1.getTargetVertexIndex() &&
|
||||||
edge0.getTargetVertexIndex() == edge1.getSourceVertexIndex());
|
edge0.getTargetVertexIndex() == edge1.getSourceVertexIndex());
|
||||||
|
@ -98,10 +98,10 @@ bool reactphysics3d::link(const EdgeEPA& edge0, const EdgeEPA& edge1) {
|
||||||
return isPossible;
|
return isPossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make an half link of an edge with another one from another triangle. An half-link
|
/// Make an half link of an edge with another one from another triangle. An half-link
|
||||||
// between an edge "edge0" and an edge "edge1" represents the fact that "edge1" is an
|
/// between an edge "edge0" and an edge "edge1" represents the fact that "edge1" is an
|
||||||
// adjacent edge of "edge0" but not the opposite. The opposite edge connection will
|
/// adjacent edge of "edge0" but not the opposite. The opposite edge connection will
|
||||||
// be made later.
|
/// be made later.
|
||||||
void reactphysics3d::halfLink(const EdgeEPA& edge0, const EdgeEPA& edge1) {
|
void reactphysics3d::halfLink(const EdgeEPA& edge0, const EdgeEPA& edge1) {
|
||||||
assert(edge0.getSourceVertexIndex() == edge1.getTargetVertexIndex() &&
|
assert(edge0.getSourceVertexIndex() == edge1.getTargetVertexIndex() &&
|
||||||
edge0.getTargetVertexIndex() == edge1.getSourceVertexIndex());
|
edge0.getTargetVertexIndex() == edge1.getSourceVertexIndex());
|
||||||
|
@ -110,17 +110,17 @@ void reactphysics3d::halfLink(const EdgeEPA& edge0, const EdgeEPA& edge1) {
|
||||||
edge0.getOwnerTriangle()->mAdjacentEdges[edge0.getIndex()] = edge1;
|
edge0.getOwnerTriangle()->mAdjacentEdges[edge0.getIndex()] = edge1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the recursive silhouette algorithm from this triangle face
|
// Execute the recursive silhouette algorithm from this triangle face.
|
||||||
// The parameter "vertices" is an array that contains the vertices of the current polytope and the
|
/// The parameter "vertices" is an array that contains the vertices of the current polytope and the
|
||||||
// parameter "indexNewVertex" is the index of the new vertex in this array. The goal of the
|
/// parameter "indexNewVertex" is the index of the new vertex in this array. The goal of the
|
||||||
// silhouette algorithm is to add the new vertex in the polytope by keeping it convex. Therefore,
|
/// silhouette algorithm is to add the new vertex in the polytope by keeping it convex. Therefore,
|
||||||
// the triangle faces that are visible from the new vertex must be removed from the polytope and we
|
/// the triangle faces that are visible from the new vertex must be removed from the polytope and we
|
||||||
// need to add triangle faces where each face contains the new vertex and an edge of the silhouette.
|
/// need to add triangle faces where each face contains the new vertex and an edge of the silhouette.
|
||||||
// The silhouette is the connected set of edges that are part of the border between faces that
|
/// The silhouette is the connected set of edges that are part of the border between faces that
|
||||||
// are seen and faces that are not seen from the new vertex. This method starts from the nearest
|
/// are seen and faces that are not seen from the new vertex. This method starts from the nearest
|
||||||
// face from the new vertex, computes the silhouette and create the new faces from the new vertex in
|
/// face from the new vertex, computes the silhouette and create the new faces from the new vertex in
|
||||||
// order that we always have a convex polytope. The faces visible from the new vertex are set
|
/// order that we always have a convex polytope. The faces visible from the new vertex are set
|
||||||
// obselete and will not be considered as being a candidate face in the future.
|
/// obselete and will not be considered as being a candidate face in the future.
|
||||||
bool TriangleEPA::computeSilhouette(const Vector3* vertices, uint indexNewVertex,
|
bool TriangleEPA::computeSilhouette(const Vector3* vertices, uint indexNewVertex,
|
||||||
TrianglesStore& triangleStore) {
|
TrianglesStore& triangleStore) {
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "EdgeEPA.h"
|
#include "EdgeEPA.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
|
@ -40,103 +40,101 @@ bool link(const EdgeEPA& edge0, const EdgeEPA& edge1);
|
||||||
void halfLink(const EdgeEPA& edge0, const EdgeEPA& edge1);
|
void halfLink(const EdgeEPA& edge0, const EdgeEPA& edge1);
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class TriangleEPA
|
||||||
Class TriangleEPA :
|
/**
|
||||||
This class represents a triangle face of the current polytope in the EPA
|
* This class represents a triangle face of the current polytope in the EPA algorithm.
|
||||||
algorithm.
|
*/
|
||||||
-------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
class TriangleEPA {
|
class TriangleEPA {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Indices of the vertices y_i of the triangle
|
/// Indices of the vertices y_i of the triangle
|
||||||
uint mIndicesVertices[3];
|
uint mIndicesVertices[3];
|
||||||
|
|
||||||
// Three adjacent edges of the triangle (edges of other triangles)
|
/// Three adjacent edges of the triangle (edges of other triangles)
|
||||||
EdgeEPA mAdjacentEdges[3];
|
EdgeEPA mAdjacentEdges[3];
|
||||||
|
|
||||||
// True if the triangle face is visible from the new support point
|
/// True if the triangle face is visible from the new support point
|
||||||
bool mIsObsolete;
|
bool mIsObsolete;
|
||||||
|
|
||||||
// Determinant
|
/// Determinant
|
||||||
decimal mDet;
|
decimal mDet;
|
||||||
|
|
||||||
// Point v closest to the origin on the affine hull of the triangle
|
/// Point v closest to the origin on the affine hull of the triangle
|
||||||
Vector3 mClosestPoint;
|
Vector3 mClosestPoint;
|
||||||
|
|
||||||
// Lambda1 value such that v = lambda0 * y_0 + lambda1 * y_1 + lambda2 * y_2
|
/// Lambda1 value such that v = lambda0 * y_0 + lambda1 * y_1 + lambda2 * y_2
|
||||||
decimal mLambda1;
|
decimal mLambda1;
|
||||||
|
|
||||||
// Lambda1 value such that v = lambda0 * y_0 + lambda1 * y_1 + lambda2 * y_2
|
/// Lambda1 value such that v = lambda0 * y_0 + lambda1 * y_1 + lambda2 * y_2
|
||||||
decimal mLambda2;
|
decimal mLambda2;
|
||||||
|
|
||||||
// Square distance of the point closest point v to the origin
|
/// Square distance of the point closest point v to the origin
|
||||||
decimal mDistSquare;
|
decimal mDistSquare;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
TriangleEPA(const TriangleEPA& triangle);
|
TriangleEPA(const TriangleEPA& triangle);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
TriangleEPA& operator=(const TriangleEPA& triangle);
|
TriangleEPA& operator=(const TriangleEPA& triangle);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
TriangleEPA();
|
TriangleEPA();
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
TriangleEPA(uint v1, uint v2, uint v3);
|
TriangleEPA(uint v1, uint v2, uint v3);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~TriangleEPA();
|
~TriangleEPA();
|
||||||
|
|
||||||
// Return an adjacent edge of the triangle
|
/// Return an adjacent edge of the triangle
|
||||||
EdgeEPA& getAdjacentEdge(int index);
|
EdgeEPA& getAdjacentEdge(int index);
|
||||||
|
|
||||||
// Set an adjacent edge of the triangle
|
/// Set an adjacent edge of the triangle
|
||||||
void setAdjacentEdge(int index, EdgeEPA& edge);
|
void setAdjacentEdge(int index, EdgeEPA& edge);
|
||||||
|
|
||||||
// Return the square distance of the closest point to origin
|
/// Return the square distance of the closest point to origin
|
||||||
decimal getDistSquare() const;
|
decimal getDistSquare() const;
|
||||||
|
|
||||||
// Set the isObsolete value
|
/// Set the isObsolete value
|
||||||
void setIsObsolete(bool isObsolete);
|
void setIsObsolete(bool isObsolete);
|
||||||
|
|
||||||
// Return true if the triangle face is obsolete
|
/// Return true if the triangle face is obsolete
|
||||||
bool getIsObsolete() const;
|
bool getIsObsolete() const;
|
||||||
|
|
||||||
// Return the point closest to the origin
|
/// Return the point closest to the origin
|
||||||
const Vector3& getClosestPoint() const;
|
const Vector3& getClosestPoint() const;
|
||||||
|
|
||||||
// Return true if the closest point on affine hull is inside the triangle
|
// Return true if the closest point on affine hull is inside the triangle
|
||||||
bool isClosestPointInternalToTriangle() const;
|
bool isClosestPointInternalToTriangle() const;
|
||||||
|
|
||||||
// Return true if the triangle is visible from a given vertex
|
/// Return true if the triangle is visible from a given vertex
|
||||||
bool isVisibleFromVertex(const Vector3* vertices, uint index) const;
|
bool isVisibleFromVertex(const Vector3* vertices, uint index) const;
|
||||||
|
|
||||||
// Compute the point v closest to the origin of this triangle
|
/// Compute the point v closest to the origin of this triangle
|
||||||
bool computeClosestPoint(const Vector3* vertices);
|
bool computeClosestPoint(const Vector3* vertices);
|
||||||
|
|
||||||
// Compute the point of an object closest to the origin
|
/// Compute the point of an object closest to the origin
|
||||||
Vector3 computeClosestPointOfObject(const Vector3* supportPointsOfObject) const;
|
Vector3 computeClosestPointOfObject(const Vector3* supportPointsOfObject) const;
|
||||||
|
|
||||||
// Execute the recursive silhouette algorithm from this triangle face
|
/// Execute the recursive silhouette algorithm from this triangle face.
|
||||||
bool computeSilhouette(const Vector3* vertices, uint index, TrianglesStore& triangleStore);
|
bool computeSilhouette(const Vector3* vertices, uint index, TrianglesStore& triangleStore);
|
||||||
|
|
||||||
// Access operator
|
/// Access operator
|
||||||
uint operator[](int i) const;
|
uint operator[](int i) const;
|
||||||
|
|
||||||
// Associate two edges
|
/// Associate two edges
|
||||||
friend bool link(const EdgeEPA& edge0, const EdgeEPA& edge1);
|
friend bool link(const EdgeEPA& edge0, const EdgeEPA& edge1);
|
||||||
|
|
||||||
// Make a half-link between two edges
|
/// Make a half-link between two edges
|
||||||
friend void halfLink(const EdgeEPA& edge0, const EdgeEPA& edge1);
|
friend void halfLink(const EdgeEPA& edge0, const EdgeEPA& edge1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,65 +32,62 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const unsigned int MAX_TRIANGLES = 200; // Maximum number of triangles
|
const unsigned int MAX_TRIANGLES = 200; // Maximum number of triangles
|
||||||
|
|
||||||
|
// Class TriangleStore
|
||||||
/* -------------------------------------------------------------------
|
/**
|
||||||
Class TrianglesStore :
|
* This class stores several triangles of the polytope in the EPA algorithm.
|
||||||
This class stores several triangles of the polytope in the EPA
|
*/
|
||||||
algorithm.
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
class TrianglesStore {
|
class TrianglesStore {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Triangles
|
/// Triangles
|
||||||
TriangleEPA mTriangles[MAX_TRIANGLES];
|
TriangleEPA mTriangles[MAX_TRIANGLES];
|
||||||
|
|
||||||
// Number of triangles
|
/// Number of triangles
|
||||||
int mNbTriangles;
|
int mNbTriangles;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
TrianglesStore(const TrianglesStore& triangleStore);
|
TrianglesStore(const TrianglesStore& triangleStore);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
TrianglesStore& operator=(const TrianglesStore& triangleStore);
|
TrianglesStore& operator=(const TrianglesStore& triangleStore);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
TrianglesStore();
|
TrianglesStore();
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~TrianglesStore();
|
~TrianglesStore();
|
||||||
|
|
||||||
// Clear all the storage
|
/// Clear all the storage
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
// Return the number of triangles
|
/// Return the number of triangles
|
||||||
int getNbTriangles() const;
|
int getNbTriangles() const;
|
||||||
|
|
||||||
// Set the number of triangles
|
/// Set the number of triangles
|
||||||
void setNbTriangles(int backup);
|
void setNbTriangles(int backup);
|
||||||
|
|
||||||
// Return the last triangle
|
/// Return the last triangle
|
||||||
TriangleEPA& last();
|
TriangleEPA& last();
|
||||||
|
|
||||||
// Create a new triangle
|
/// Create a new triangle
|
||||||
TriangleEPA* newTriangle(const Vector3* vertices, uint v0, uint v1, uint v2);
|
TriangleEPA* newTriangle(const Vector3* vertices, uint v0, uint v1, uint v2);
|
||||||
|
|
||||||
// Access operator
|
/// Access operator
|
||||||
TriangleEPA& operator[](int i);
|
TriangleEPA& operator[](int i);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,16 +47,16 @@ GJKAlgorithm::~GJKAlgorithm() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true and compute a contact info if the two bounding volume collide.
|
// Return true and compute a contact info if the two bounding volumes collide.
|
||||||
// This method implements the Hybrid Technique for computing the penetration depth by
|
/// This method implements the Hybrid Technique for computing the penetration depth by
|
||||||
// running the GJK algorithm on original objects (without margin).
|
/// running the GJK algorithm on original objects (without margin).
|
||||||
// If the objects don't intersect, this method returns false. If they intersect
|
/// If the objects don't intersect, this method returns false. If they intersect
|
||||||
// only in the margins, the method compute the penetration depth and contact points
|
/// only in the margins, the method compute the penetration depth and contact points
|
||||||
// (of enlarged objects). If the original objects (without margin) intersect, we
|
/// (of enlarged objects). If the original objects (without margin) intersect, we
|
||||||
// call the computePenetrationDepthForEnlargedObjects() method that run the GJK
|
/// call the computePenetrationDepthForEnlargedObjects() method that run the GJK
|
||||||
// algorithm on the enlarged object to obtain a simplex polytope that contains the
|
/// algorithm on the enlarged object to obtain a simplex polytope that contains the
|
||||||
// origin, they we give that simplex polytope to the EPA algorithm which will compute
|
/// origin, they we give that simplex polytope to the EPA algorithm which will compute
|
||||||
// the correct penetration depth and contact points between the enlarged objects.
|
/// the correct penetration depth and contact points between the enlarged objects.
|
||||||
bool GJKAlgorithm::testCollision(const CollisionShape* collisionShape1,
|
bool GJKAlgorithm::testCollision(const CollisionShape* collisionShape1,
|
||||||
const Transform& transform1,
|
const Transform& transform1,
|
||||||
const CollisionShape* collisionShape2,
|
const CollisionShape* collisionShape2,
|
||||||
|
@ -254,11 +254,11 @@ bool GJKAlgorithm::testCollision(const CollisionShape* collisionShape1,
|
||||||
transform2, contactInfo, v);
|
transform2, contactInfo, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method runs the GJK algorithm on the two enlarged objects (with margin)
|
/// This method runs the GJK algorithm on the two enlarged objects (with margin)
|
||||||
// to compute a simplex polytope that contains the origin. The two objects are
|
/// to compute a simplex polytope that contains the origin. The two objects are
|
||||||
// assumed to intersect in the original objects (without margin). Therefore such
|
/// assumed to intersect in the original objects (without margin). Therefore such
|
||||||
// a polytope must exist. Then, we give that polytope to the EPA algorithm to
|
/// a polytope must exist. Then, we give that polytope to the EPA algorithm to
|
||||||
// compute the correct penetration depth and contact points of the enlarged objects.
|
/// compute the correct penetration depth and contact points of the enlarged objects.
|
||||||
bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(const CollisionShape* collisionShape1,
|
bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(const CollisionShape* collisionShape1,
|
||||||
const Transform& transform1,
|
const Transform& transform1,
|
||||||
const CollisionShape* collisionShape2,
|
const CollisionShape* collisionShape2,
|
||||||
|
|
|
@ -33,48 +33,47 @@
|
||||||
#include "../EPA/EPAAlgorithm.h"
|
#include "../EPA/EPAAlgorithm.h"
|
||||||
|
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const decimal REL_ERROR = decimal(1.0e-3);
|
const decimal REL_ERROR = decimal(1.0e-3);
|
||||||
const decimal REL_ERROR_SQUARE = REL_ERROR * REL_ERROR;
|
const decimal REL_ERROR_SQUARE = REL_ERROR * REL_ERROR;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class GJKAlgorithm
|
||||||
Class GJKAlgorithm :
|
/**
|
||||||
This class implements a narrow-phase collision detection algorithm. This
|
* This class implements a narrow-phase collision detection algorithm. This
|
||||||
algorithm uses the ISA-GJK algorithm and the EPA algorithm. This
|
* algorithm uses the ISA-GJK algorithm and the EPA algorithm. This
|
||||||
implementation is based on the implementation discussed in the book
|
* implementation is based on the implementation discussed in the book
|
||||||
"Collision Detection in 3D Environments".
|
* "Collision Detection in 3D Environments".
|
||||||
This method implements the Hybrid Technique for calculating the
|
* This method implements the Hybrid Technique for calculating the
|
||||||
penetration depth. The two objects are enlarged with a small margin. If
|
* penetration depth. The two objects are enlarged with a small margin. If
|
||||||
the object intersection, the penetration depth is quickly computed using
|
* the object intersection, the penetration depth is quickly computed using
|
||||||
GJK algorithm on the original objects (without margin). If the
|
* GJK algorithm on the original objects (without margin). If the
|
||||||
original objects (without margin) intersect, we run again the GJK
|
* original objects (without margin) intersect, we run again the GJK
|
||||||
algorithm on the enlarged objects (with margin) to compute simplex
|
* algorithm on the enlarged objects (with margin) to compute simplex
|
||||||
polytope that contains the origin and give it to the EPA (Expanding
|
* polytope that contains the origin and give it to the EPA (Expanding
|
||||||
Polytope Algorithm) to compute the correct penetration depth between the
|
* Polytope Algorithm) to compute the correct penetration depth between the
|
||||||
enlarged objects.
|
* enlarged objects.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class GJKAlgorithm : public NarrowPhaseAlgorithm {
|
class GJKAlgorithm : public NarrowPhaseAlgorithm {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// EPA Algorithm
|
/// EPA Algorithm
|
||||||
EPAAlgorithm mAlgoEPA;
|
EPAAlgorithm mAlgoEPA;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
GJKAlgorithm(const GJKAlgorithm& algorithm);
|
GJKAlgorithm(const GJKAlgorithm& algorithm);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
GJKAlgorithm& operator=(const GJKAlgorithm& algorithm);
|
GJKAlgorithm& operator=(const GJKAlgorithm& algorithm);
|
||||||
|
|
||||||
// Compute the penetration depth for enlarged objects
|
/// Compute the penetration depth for enlarged objects.
|
||||||
bool computePenetrationDepthForEnlargedObjects(const CollisionShape* collisionShape1,
|
bool computePenetrationDepthForEnlargedObjects(const CollisionShape* collisionShape1,
|
||||||
const Transform& transform1,
|
const Transform& transform1,
|
||||||
const CollisionShape* collisionShape2,
|
const CollisionShape* collisionShape2,
|
||||||
|
@ -85,13 +84,13 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm {
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
GJKAlgorithm(MemoryPool<ContactInfo>& memoryPoolContactInfos);
|
GJKAlgorithm(MemoryPool<ContactInfo>& memoryPoolContactInfos);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~GJKAlgorithm();
|
~GJKAlgorithm();
|
||||||
|
|
||||||
// Return true and compute a contact info if the two bounding volume collide
|
/// Return true and compute a contact info if the two bounding volumes collide.
|
||||||
virtual bool testCollision(const CollisionShape* collisionShape1,
|
virtual bool testCollision(const CollisionShape* collisionShape1,
|
||||||
const Transform& transform1,
|
const Transform& transform1,
|
||||||
const CollisionShape* collisionShape2,
|
const CollisionShape* collisionShape2,
|
||||||
|
|
|
@ -41,9 +41,9 @@ Simplex::~Simplex() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new support point of (A-B) into the simplex
|
// Add a new support point of (A-B) into the simplex
|
||||||
// suppPointA : support point of object A in a direction -v
|
/// suppPointA : support point of object A in a direction -v
|
||||||
// suppPointB : support point of object B in a direction v
|
/// suppPointB : support point of object B in a direction v
|
||||||
// point : support point of object (A-B) => point = suppPointA - suppPointB
|
/// point : support point of object (A-B) => point = suppPointA - suppPointB
|
||||||
void Simplex::addPoint(const Vector3& point, const Vector3& suppPointA, const Vector3& suppPointB) {
|
void Simplex::addPoint(const Vector3& point, const Vector3& suppPointA, const Vector3& suppPointB) {
|
||||||
assert(!isFull());
|
assert(!isFull());
|
||||||
|
|
||||||
|
@ -220,9 +220,9 @@ void Simplex::computeDeterminants() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the subset is a proper subset
|
// Return true if the subset is a proper subset.
|
||||||
// A proper subset X is a subset where for all point "y_i" in X, we have
|
/// A proper subset X is a subset where for all point "y_i" in X, we have
|
||||||
// detX_i value bigger than zero
|
/// detX_i value bigger than zero
|
||||||
bool Simplex::isProperSubset(Bits subset) const {
|
bool Simplex::isProperSubset(Bits subset) const {
|
||||||
int i;
|
int i;
|
||||||
Bits bit;
|
Bits bit;
|
||||||
|
@ -237,8 +237,9 @@ bool Simplex::isProperSubset(Bits subset) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the set is affinely dependent meaning that a point of the set
|
// Return true if the set is affinely dependent.
|
||||||
// is an affine combination of other points in the set
|
/// A set if affinely dependent if a point of the set
|
||||||
|
/// is an affine combination of other points in the set
|
||||||
bool Simplex::isAffinelyDependent() const {
|
bool Simplex::isAffinelyDependent() const {
|
||||||
decimal sum = 0.0;
|
decimal sum = 0.0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -254,10 +255,10 @@ bool Simplex::isAffinelyDependent() const {
|
||||||
return (sum <= 0.0);
|
return (sum <= 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the subset is a valid one for the closest point computation
|
// Return true if the subset is a valid one for the closest point computation.
|
||||||
// A subset X is valid if :
|
/// A subset X is valid if :
|
||||||
// 1. delta(X)_i > 0 for each "i" in I_x and
|
/// 1. delta(X)_i > 0 for each "i" in I_x and
|
||||||
// 2. delta(X U {y_j})_j <= 0 for each "j" not in I_x_
|
/// 2. delta(X U {y_j})_j <= 0 for each "j" not in I_x_
|
||||||
bool Simplex::isValidSubset(Bits subset) const {
|
bool Simplex::isValidSubset(Bits subset) const {
|
||||||
int i;
|
int i;
|
||||||
Bits bit;
|
Bits bit;
|
||||||
|
@ -285,11 +286,11 @@ bool Simplex::isValidSubset(Bits subset) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the closest points "pA" and "pB" of object A and B
|
// Compute the closest points "pA" and "pB" of object A and B.
|
||||||
// The points are computed as follows :
|
/// The points are computed as follows :
|
||||||
// pA = sum(lambda_i * a_i) where "a_i" are the support points of object A
|
/// pA = sum(lambda_i * a_i) where "a_i" are the support points of object A
|
||||||
// pB = sum(lambda_i * b_i) where "b_i" are the support points of object B
|
/// pB = sum(lambda_i * b_i) where "b_i" are the support points of object B
|
||||||
// with lambda_i = deltaX_i / deltaX
|
/// with lambda_i = deltaX_i / deltaX
|
||||||
void Simplex::computeClosestPointsOfAandB(Vector3& pA, Vector3& pB) const {
|
void Simplex::computeClosestPointsOfAandB(Vector3& pA, Vector3& pB) const {
|
||||||
decimal deltaX = 0.0;
|
decimal deltaX = 0.0;
|
||||||
pA.setAllValues(0.0, 0.0, 0.0);
|
pA.setAllValues(0.0, 0.0, 0.0);
|
||||||
|
@ -313,10 +314,10 @@ void Simplex::computeClosestPointsOfAandB(Vector3& pA, Vector3& pB) const {
|
||||||
pB *= factor;
|
pB *= factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the closest point "v" to the origin of the current simplex
|
// Compute the closest point "v" to the origin of the current simplex.
|
||||||
// This method executes the Jonhnson's algorithm for computing the point
|
/// This method executes the Jonhnson's algorithm for computing the point
|
||||||
// "v" of simplex that is closest to the origin. The method returns true
|
/// "v" of simplex that is closest to the origin. The method returns true
|
||||||
// if a closest point has been found.
|
/// if a closest point has been found.
|
||||||
bool Simplex::computeClosestPoint(Vector3& v) {
|
bool Simplex::computeClosestPoint(Vector3& v) {
|
||||||
Bits subset;
|
Bits subset;
|
||||||
|
|
||||||
|
|
|
@ -30,133 +30,132 @@
|
||||||
#include "../../../mathematics/mathematics.h"
|
#include "../../../mathematics/mathematics.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Type definitions
|
// Type definitions
|
||||||
typedef unsigned int Bits;
|
typedef unsigned int Bits;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class Simplex
|
||||||
Class Simplex :
|
/**
|
||||||
This class represents a simplex which is a set of 3D points. This
|
* This class represents a simplex which is a set of 3D points. This
|
||||||
class is used in the GJK algorithm. This implementation is based on
|
* class is used in the GJK algorithm. This implementation is based on
|
||||||
the implementation discussed in the book "Collision Detection in 3D
|
* the implementation discussed in the book "Collision Detection in 3D
|
||||||
Environments". This class implements the Johnson's algorithm for
|
* Environments". This class implements the Johnson's algorithm for
|
||||||
computing the point of a simplex that is closest to the origin and also
|
* computing the point of a simplex that is closest to the origin and also
|
||||||
the smallest simplex needed to represent that closest point.
|
* the smallest simplex needed to represent that closest point.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class Simplex {
|
class Simplex {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Current points
|
/// Current points
|
||||||
Vector3 mPoints[4];
|
Vector3 mPoints[4];
|
||||||
|
|
||||||
// pointsLengthSquare[i] = (points[i].length)^2
|
/// pointsLengthSquare[i] = (points[i].length)^2
|
||||||
decimal mPointsLengthSquare[4];
|
decimal mPointsLengthSquare[4];
|
||||||
|
|
||||||
// Maximum length of pointsLengthSquare[i]
|
/// Maximum length of pointsLengthSquare[i]
|
||||||
decimal mMaxLengthSquare;
|
decimal mMaxLengthSquare;
|
||||||
|
|
||||||
// Support points of object A in local coordinates
|
/// Support points of object A in local coordinates
|
||||||
Vector3 mSuppPointsA[4];
|
Vector3 mSuppPointsA[4];
|
||||||
|
|
||||||
// Support points of object B in local coordinates
|
/// Support points of object B in local coordinates
|
||||||
Vector3 mSuppPointsB[4];
|
Vector3 mSuppPointsB[4];
|
||||||
|
|
||||||
// diff[i][j] contains points[i] - points[j]
|
/// diff[i][j] contains points[i] - points[j]
|
||||||
Vector3 mDiffLength[4][4];
|
Vector3 mDiffLength[4][4];
|
||||||
|
|
||||||
// Cached determinant values
|
/// Cached determinant values
|
||||||
decimal mDet[16][4];
|
decimal mDet[16][4];
|
||||||
|
|
||||||
// norm[i][j] = (diff[i][j].length())^2
|
/// norm[i][j] = (diff[i][j].length())^2
|
||||||
decimal mNormSquare[4][4];
|
decimal mNormSquare[4][4];
|
||||||
|
|
||||||
// 4 bits that identify the current points of the simplex
|
/// 4 bits that identify the current points of the simplex
|
||||||
// For instance, 0101 means that points[1] and points[3] are in the simplex
|
/// For instance, 0101 means that points[1] and points[3] are in the simplex
|
||||||
Bits mBitsCurrentSimplex;
|
Bits mBitsCurrentSimplex;
|
||||||
|
|
||||||
// Number between 1 and 4 that identify the last found support point
|
/// Number between 1 and 4 that identify the last found support point
|
||||||
Bits mLastFound;
|
Bits mLastFound;
|
||||||
|
|
||||||
// Position of the last found support point (lastFoundBit = 0x1 << lastFound)
|
/// Position of the last found support point (lastFoundBit = 0x1 << lastFound)
|
||||||
Bits mLastFoundBit;
|
Bits mLastFoundBit;
|
||||||
|
|
||||||
// allBits = bitsCurrentSimplex | lastFoundBit;
|
/// allBits = bitsCurrentSimplex | lastFoundBit;
|
||||||
Bits mAllBits;
|
Bits mAllBits;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
Simplex(const Simplex& simplex);
|
Simplex(const Simplex& simplex);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
Simplex& operator=(const Simplex& simplex);
|
Simplex& operator=(const Simplex& simplex);
|
||||||
|
|
||||||
// Return true if some bits of "a" overlap with bits of "b"
|
/// Return true if some bits of "a" overlap with bits of "b"
|
||||||
bool overlap(Bits a, Bits b) const;
|
bool overlap(Bits a, Bits b) const;
|
||||||
|
|
||||||
// Return true if the bits of "b" is a subset of the bits of "a"
|
/// Return true if the bits of "b" is a subset of the bits of "a"
|
||||||
bool isSubset(Bits a, Bits b) const;
|
bool isSubset(Bits a, Bits b) const;
|
||||||
|
|
||||||
// Return true if the subset is a valid one for the closest point computation
|
/// Return true if the subset is a valid one for the closest point computation.
|
||||||
bool isValidSubset(Bits subset) const;
|
bool isValidSubset(Bits subset) const;
|
||||||
|
|
||||||
// Return true if the subset is a proper subset
|
/// Return true if the subset is a proper subset.
|
||||||
bool isProperSubset(Bits subset) const;
|
bool isProperSubset(Bits subset) const;
|
||||||
|
|
||||||
// Update the cached values used during the GJK algorithm
|
/// Update the cached values used during the GJK algorithm
|
||||||
void updateCache();
|
void updateCache();
|
||||||
|
|
||||||
// Compute the cached determinant values
|
/// Compute the cached determinant values
|
||||||
void computeDeterminants();
|
void computeDeterminants();
|
||||||
|
|
||||||
// Return the closest point "v" in the convex hull of a subset of points
|
/// Return the closest point "v" in the convex hull of a subset of points
|
||||||
Vector3 computeClosestPointForSubset(Bits subset);
|
Vector3 computeClosestPointForSubset(Bits subset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Simplex();
|
Simplex();
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~Simplex();
|
~Simplex();
|
||||||
|
|
||||||
// Return true if the simplex contains 4 points
|
/// Return true if the simplex contains 4 points
|
||||||
bool isFull() const;
|
bool isFull() const;
|
||||||
|
|
||||||
// Return true if the simple is empty
|
/// Return true if the simple is empty
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
|
|
||||||
// Return the points of the simplex
|
/// Return the points of the simplex
|
||||||
unsigned int getSimplex(Vector3* mSuppPointsA, Vector3* mSuppPointsB,
|
unsigned int getSimplex(Vector3* mSuppPointsA, Vector3* mSuppPointsB,
|
||||||
Vector3* mPoints) const;
|
Vector3* mPoints) const;
|
||||||
|
|
||||||
// Return the maximum squared length of a point
|
/// Return the maximum squared length of a point
|
||||||
decimal getMaxLengthSquareOfAPoint() const;
|
decimal getMaxLengthSquareOfAPoint() const;
|
||||||
|
|
||||||
// Addd a point to the simplex
|
/// Add a new support point of (A-B) into the simplex.
|
||||||
void addPoint(const Vector3& point, const Vector3& suppPointA, const Vector3& suppPointB);
|
void addPoint(const Vector3& point, const Vector3& suppPointA, const Vector3& suppPointB);
|
||||||
|
|
||||||
// Return true if the point is in the simplex
|
/// Return true if the point is in the simplex
|
||||||
bool isPointInSimplex(const Vector3& point) const;
|
bool isPointInSimplex(const Vector3& point) const;
|
||||||
|
|
||||||
// Return true if the set is affinely dependent
|
/// Return true if the set is affinely dependent
|
||||||
bool isAffinelyDependent() const;
|
bool isAffinelyDependent() const;
|
||||||
|
|
||||||
// Backup the closest point
|
/// Backup the closest point
|
||||||
void backupClosestPointInSimplex(Vector3& point);
|
void backupClosestPointInSimplex(Vector3& point);
|
||||||
|
|
||||||
// Compute the closest points of object A and B
|
/// Compute the closest points "pA" and "pB" of object A and B.
|
||||||
void computeClosestPointsOfAandB(Vector3& pA, Vector3& pB) const;
|
void computeClosestPointsOfAandB(Vector3& pA, Vector3& pB) const;
|
||||||
|
|
||||||
// Compute the closest point to the origin of the current simplex
|
/// Compute the closest point to the origin of the current simplex.
|
||||||
bool computeClosestPoint(Vector3& v);
|
bool computeClosestPoint(Vector3& v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,52 +34,50 @@
|
||||||
#include "../BroadPhasePair.h"
|
#include "../BroadPhasePair.h"
|
||||||
|
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
/// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
|
// Class NarrowPhaseAlgorithm
|
||||||
/* -------------------------------------------------------------------
|
/**
|
||||||
Class NarrowPhaseAlgorithm :
|
* This class is an abstract class that represents an algorithm
|
||||||
This class is an abstract class that represents an algorithm
|
* used to perform the narrow-phase of a collision detection. The
|
||||||
used to perform the narrow-phase of a collision detection. The
|
* goal of the narrow phase algorithm is to compute contact
|
||||||
goal of the narrow phase algorithm is to compute contact
|
* informations of a collision between two bodies.
|
||||||
informations of a collision between two bodies.
|
*/
|
||||||
-------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
class NarrowPhaseAlgorithm {
|
class NarrowPhaseAlgorithm {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Reference to the memory pool
|
/// Reference to the memory pool
|
||||||
MemoryPool<ContactInfo>& mMemoryPoolContactInfos;
|
MemoryPool<ContactInfo>& mMemoryPoolContactInfos;
|
||||||
|
|
||||||
// Overlapping pair of the bodies currently tested for collision
|
/// Overlapping pair of the bodies currently tested for collision
|
||||||
BroadPhasePair* mCurrentOverlappingPair;
|
BroadPhasePair* mCurrentOverlappingPair;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
NarrowPhaseAlgorithm(const NarrowPhaseAlgorithm& algorithm);
|
NarrowPhaseAlgorithm(const NarrowPhaseAlgorithm& algorithm);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm);
|
NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
NarrowPhaseAlgorithm(MemoryPool<ContactInfo>& memoryPool);
|
NarrowPhaseAlgorithm(MemoryPool<ContactInfo>& memoryPool);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~NarrowPhaseAlgorithm();
|
virtual ~NarrowPhaseAlgorithm();
|
||||||
|
|
||||||
// Set the current overlapping pair of bodies
|
/// Set the current overlapping pair of bodies
|
||||||
void setCurrentOverlappingPair(BroadPhasePair* overlappingPair);
|
void setCurrentOverlappingPair(BroadPhasePair* overlappingPair);
|
||||||
|
|
||||||
// Return true and compute a contact info if the two bounding volume collide
|
/// Return true and compute a contact info if the two bounding volume collide
|
||||||
virtual bool testCollision(const CollisionShape* collisionShape1,
|
virtual bool testCollision(const CollisionShape* collisionShape1,
|
||||||
const Transform& transform1,
|
const Transform& transform1,
|
||||||
const CollisionShape* collisionShape2,
|
const CollisionShape* collisionShape2,
|
||||||
|
|
|
@ -32,38 +32,37 @@
|
||||||
#include "NarrowPhaseAlgorithm.h"
|
#include "NarrowPhaseAlgorithm.h"
|
||||||
|
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
/// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class SphereVsSphereAlgorithm
|
||||||
Class SphereVsSphereAlgorithm :
|
/**
|
||||||
This class is used to compute the narrow-phase collision detection
|
* This class is used to compute the narrow-phase collision detection
|
||||||
between two sphere collision shapes.
|
* between two sphere collision shapes.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class SphereVsSphereAlgorithm : public NarrowPhaseAlgorithm {
|
class SphereVsSphereAlgorithm : public NarrowPhaseAlgorithm {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
SphereVsSphereAlgorithm(const SphereVsSphereAlgorithm& algorithm);
|
SphereVsSphereAlgorithm(const SphereVsSphereAlgorithm& algorithm);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
SphereVsSphereAlgorithm& operator=(const SphereVsSphereAlgorithm& algorithm);
|
SphereVsSphereAlgorithm& operator=(const SphereVsSphereAlgorithm& algorithm);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
SphereVsSphereAlgorithm(MemoryPool<ContactInfo>& memoryPoolContactInfos);
|
SphereVsSphereAlgorithm(MemoryPool<ContactInfo>& memoryPoolContactInfos);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~SphereVsSphereAlgorithm();
|
virtual ~SphereVsSphereAlgorithm();
|
||||||
|
|
||||||
// Return true and compute a contact info if the two bounding volume collide
|
/// Return true and compute a contact info if the two bounding volume collide
|
||||||
virtual bool testCollision(const CollisionShape* collisionShape1,
|
virtual bool testCollision(const CollisionShape* collisionShape1,
|
||||||
const Transform& transform1,
|
const Transform& transform1,
|
||||||
const CollisionShape* collisionShape2,
|
const CollisionShape* collisionShape2,
|
||||||
|
|
|
@ -29,84 +29,83 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "../../mathematics/mathematics.h"
|
#include "../../mathematics/mathematics.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Declaration
|
// Declaration
|
||||||
class Body;
|
class Body;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class AABB
|
||||||
Class AABB :
|
/**
|
||||||
This class represents a bounding volume of type "Axis Aligned
|
* This class represents a bounding volume of type "Axis Aligned
|
||||||
Bounding Box". It's a box where all the edges are always aligned
|
* Bounding Box". It's a box where all the edges are always aligned
|
||||||
with the world coordinate system. The AABB is defined by the
|
* with the world coordinate system. The AABB is defined by the
|
||||||
minimum and maximum world coordinates of the three axis.
|
* minimum and maximum world coordinates of the three axis.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class AABB {
|
class AABB {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Minimum world coordinates of the AABB on the x,y and z axis
|
/// Minimum world coordinates of the AABB on the x,y and z axis
|
||||||
Vector3 mMinCoordinates;
|
Vector3 mMinCoordinates;
|
||||||
|
|
||||||
// Maximum world coordinates of the AABB on the x,y and z axis
|
/// Maximum world coordinates of the AABB on the x,y and z axis
|
||||||
Vector3 mMaxCoordinates;
|
Vector3 mMaxCoordinates;
|
||||||
|
|
||||||
// Pointer to the owner body (not the abstract class Body
|
/// Pointer to the owner body (not the abstract class Body
|
||||||
// but its derivative which is instanciable)
|
/// but its derivative which is instanciable)
|
||||||
Body* mBodyPointer;
|
Body* mBodyPointer;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
AABB(const AABB& aabb);
|
AABB(const AABB& aabb);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
AABB& operator=(const AABB& aabb);
|
AABB& operator=(const AABB& aabb);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
AABB();
|
AABB();
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
AABB(const Vector3& minCoordinates, const Vector3& maxCoordinates, Body* modyPointer);
|
AABB(const Vector3& minCoordinates, const Vector3& maxCoordinates, Body* modyPointer);
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
AABB(const Transform& transform, const Vector3& extents);
|
AABB(const Transform& transform, const Vector3& extents);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~AABB();
|
virtual ~AABB();
|
||||||
|
|
||||||
// Return the center point
|
/// Return the center point
|
||||||
Vector3 getCenter() const;
|
Vector3 getCenter() const;
|
||||||
|
|
||||||
// Return the minimum coordinates of the AABB
|
/// Return the minimum coordinates of the AABB
|
||||||
const Vector3& getMin() const;
|
const Vector3& getMin() const;
|
||||||
|
|
||||||
// Return the maximum coordinates of the AABB
|
/// Return the maximum coordinates of the AABB
|
||||||
const Vector3& getMax() const;
|
const Vector3& getMax() const;
|
||||||
|
|
||||||
// Return a pointer to the owner body
|
/// Return a pointer to the owner body
|
||||||
Body* getBodyPointer() const;
|
Body* getBodyPointer() const;
|
||||||
|
|
||||||
// Set the body pointer
|
/// Set the body pointer
|
||||||
void setBodyPointer(Body* bodyPointer);
|
void setBodyPointer(Body* bodyPointer);
|
||||||
|
|
||||||
// Return true if the current AABB is overlapping is the AABB in argument
|
/// Return true if the current AABB is overlapping with the AABB in argument
|
||||||
bool testCollision(const AABB& aabb) const;
|
bool testCollision(const AABB& aabb) const;
|
||||||
|
|
||||||
// Update the oriented bounding box orientation
|
/// Update the oriented bounding box orientation
|
||||||
// according to a new orientation of the rigid body
|
/// according to a new orientation of the rigid body
|
||||||
virtual void update(const Transform& newTransform, const Vector3& extents);
|
virtual void update(const Transform& newTransform, const Vector3& extents);
|
||||||
|
|
||||||
#ifdef VISUAL_DEBUG
|
#ifdef VISUAL_DEBUG
|
||||||
// Draw the AABB (only for testing purpose)
|
/// Draw the AABB (only for testing purpose)
|
||||||
virtual void draw() const;
|
virtual void draw() const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -136,8 +135,8 @@ inline void AABB::setBodyPointer(Body* bodyPointer) {
|
||||||
mBodyPointer = bodyPointer;
|
mBodyPointer = bodyPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the current AABB is overlapping with the AABB in argument
|
// Return true if the current AABB is overlapping with the AABB in argument.
|
||||||
// Two AABB overlap if they overlap in the three x, y and z axis at the same time
|
/// Two AABBs overlap if they overlap in the three x, y and z axis at the same time
|
||||||
inline bool AABB::testCollision(const AABB& aabb) const {
|
inline bool AABB::testCollision(const AABB& aabb) const {
|
||||||
if (mMaxCoordinates.x < aabb.mMinCoordinates.x ||
|
if (mMaxCoordinates.x < aabb.mMinCoordinates.x ||
|
||||||
aabb.mMaxCoordinates.x < mMinCoordinates.x) return false;
|
aabb.mMaxCoordinates.x < mMinCoordinates.x) return false;
|
||||||
|
|
|
@ -32,67 +32,66 @@
|
||||||
#include "../../mathematics/mathematics.h"
|
#include "../../mathematics/mathematics.h"
|
||||||
|
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class BoxShape
|
||||||
Class BoxShape :
|
/**
|
||||||
This class represents a 3D box shape. Those axis are unit length.
|
* This class represents a 3D box shape. Those axis are unit length.
|
||||||
The three extents are half-widths of the box along the three
|
* The three extents are half-widths of the box along the three
|
||||||
axis x, y, z local axis. The "transform" of the corresponding
|
* axis x, y, z local axis. The "transform" of the corresponding
|
||||||
rigid body gives an orientation and a position to the box.
|
* rigid body gives an orientation and a position to the box.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class BoxShape : public CollisionShape {
|
class BoxShape : public CollisionShape {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Extent sizes of the box in the x, y and z direction
|
/// Extent sizes of the box in the x, y and z direction
|
||||||
Vector3 mExtent;
|
Vector3 mExtent;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
BoxShape(const BoxShape& shape);
|
BoxShape(const BoxShape& shape);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
BoxShape& operator=(const BoxShape& shape);
|
BoxShape& operator=(const BoxShape& shape);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
BoxShape(const Vector3& extent);
|
BoxShape(const Vector3& extent);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~BoxShape();
|
virtual ~BoxShape();
|
||||||
|
|
||||||
// Return the extents of the box
|
/// Return the extents of the box
|
||||||
const Vector3& getExtent() const;
|
const Vector3& getExtent() const;
|
||||||
|
|
||||||
// Set the extents of the box
|
/// Set the extents of the box
|
||||||
void setExtent(const Vector3& extent);
|
void setExtent(const Vector3& extent);
|
||||||
|
|
||||||
// Return the local extents in x,y and z direction
|
/// Return the local extents in x,y and z direction.
|
||||||
virtual Vector3 getLocalExtents(decimal margin=0.0) const;
|
virtual Vector3 getLocalExtents(decimal margin=0.0) const;
|
||||||
|
|
||||||
// Return the margin distance around the shape
|
/// Return the margin distance around the shape
|
||||||
virtual decimal getMargin() const;
|
virtual decimal getMargin() const;
|
||||||
|
|
||||||
// Return a local support point in a given direction with the object margin
|
/// Return a local support point in a given direction with the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
|
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
|
||||||
|
|
||||||
// Return a local support point in a given direction without the object margin
|
/// Return a local support point in a given direction without the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
||||||
|
|
||||||
// Return the local inertia tensor of the collision shape
|
/// Return the local inertia tensor of the collision shape
|
||||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
||||||
|
|
||||||
#ifdef VISUAL_DEBUG
|
#ifdef VISUAL_DEBUG
|
||||||
// Draw the Box (only for testing purpose)
|
/// Draw the Box (only for testing purpose)
|
||||||
virtual void draw() const;
|
virtual void draw() const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -107,8 +106,8 @@ inline void BoxShape::setExtent(const Vector3& extent) {
|
||||||
this->mExtent = extent;
|
this->mExtent = extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the local extents of the box (half-width) in x,y and z local direction
|
// Return the local extents of the box (half-width) in x,y and z local direction.
|
||||||
// This method is used to compute the AABB of the box
|
/// This method is used to compute the AABB of the box
|
||||||
inline Vector3 BoxShape::getLocalExtents(decimal margin) const {
|
inline Vector3 BoxShape::getLocalExtents(decimal margin) const {
|
||||||
return mExtent + Vector3(getMargin(), getMargin(), getMargin());
|
return mExtent + Vector3(getMargin(), getMargin(), getMargin());
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,64 +31,63 @@
|
||||||
#include "../../mathematics/Vector3.h"
|
#include "../../mathematics/Vector3.h"
|
||||||
#include "../../mathematics/Matrix3x3.h"
|
#include "../../mathematics/Matrix3x3.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Enumeration
|
/// Type of the collision shape
|
||||||
enum CollisionShapeType {BOX, SPHERE, CONE, CYLINDER}; // Type of the collision shape
|
enum CollisionShapeType {BOX, SPHERE, CONE, CYLINDER};
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
class Body;
|
class Body;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class CollisionShape
|
||||||
Class CollisionShape :
|
/**
|
||||||
This abstract class represents the collision shape associated with a
|
* This abstract class represents the collision shape associated with a
|
||||||
body that is used during the narrow-phase collision detection.
|
* body that is used during the narrow-phase collision detection.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class CollisionShape {
|
class CollisionShape {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Type of the collision shape
|
/// Type of the collision shape
|
||||||
CollisionShapeType mType;
|
CollisionShapeType mType;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
CollisionShape(const CollisionShape& shape);
|
CollisionShape(const CollisionShape& shape);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
CollisionShape& operator=(const CollisionShape& shape);
|
CollisionShape& operator=(const CollisionShape& shape);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
CollisionShape(CollisionShapeType type);
|
CollisionShape(CollisionShapeType type);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~CollisionShape();
|
virtual ~CollisionShape();
|
||||||
|
|
||||||
// Return the type of the collision shapes
|
/// Return the type of the collision shapes
|
||||||
CollisionShapeType getType() const;
|
CollisionShapeType getType() const;
|
||||||
|
|
||||||
// Return a local support point in a given direction with the object margin
|
/// Return a local support point in a given direction with the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const=0;
|
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const=0;
|
||||||
|
|
||||||
// Return a local support point in a given direction without the object margin
|
/// Return a local support point in a given direction without the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const=0;
|
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const=0;
|
||||||
|
|
||||||
// Return the local extents in x,y and z direction
|
/// Return the local extents in x,y and z direction
|
||||||
virtual Vector3 getLocalExtents(decimal margin=0.0) const=0;
|
virtual Vector3 getLocalExtents(decimal margin=0.0) const=0;
|
||||||
|
|
||||||
// Return the margin distance around the shape
|
/// Return the margin distance around the shape
|
||||||
virtual decimal getMargin() const=0;
|
virtual decimal getMargin() const=0;
|
||||||
|
|
||||||
// Return the local inertia tensor of the collision shapes
|
/// Return the local inertia tensor of the collision shapes
|
||||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const=0;
|
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,81 +30,80 @@
|
||||||
#include "CollisionShape.h"
|
#include "CollisionShape.h"
|
||||||
#include "../../mathematics/mathematics.h"
|
#include "../../mathematics/mathematics.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class ConeShape
|
||||||
Class ConeShape :
|
/**
|
||||||
This class represents a cone collision shape centered at the
|
* This class represents a cone collision shape centered at the
|
||||||
origin and alligned with the Y axis. The cone is defined
|
* origin and alligned with the Y axis. The cone is defined
|
||||||
by its height and by the radius of its base. The center of the
|
* by its height and by the radius of its base. The center of the
|
||||||
cone is at the half of the height. The "transform" of the
|
* cone is at the half of the height. The "transform" of the
|
||||||
corresponding rigid body gives an orientation and a position
|
* corresponding rigid body gives an orientation and a position
|
||||||
to the cone.
|
* to the cone.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class ConeShape : public CollisionShape {
|
class ConeShape : public CollisionShape {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Radius of the base
|
/// Radius of the base
|
||||||
decimal mRadius;
|
decimal mRadius;
|
||||||
|
|
||||||
// Half height of the cone
|
/// Half height of the cone
|
||||||
decimal mHalfHeight;
|
decimal mHalfHeight;
|
||||||
|
|
||||||
// sine of the semi angle at the apex point
|
/// sine of the semi angle at the apex point
|
||||||
decimal mSinTheta;
|
decimal mSinTheta;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
ConeShape(const ConeShape& shape);
|
ConeShape(const ConeShape& shape);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
ConeShape& operator=(const ConeShape& shape);
|
ConeShape& operator=(const ConeShape& shape);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
ConeShape(decimal mRadius, decimal height);
|
ConeShape(decimal mRadius, decimal height);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~ConeShape();
|
virtual ~ConeShape();
|
||||||
|
|
||||||
// Return the radius
|
/// Return the radius
|
||||||
decimal getRadius() const;
|
decimal getRadius() const;
|
||||||
|
|
||||||
// Set the radius
|
/// Set the radius
|
||||||
void setRadius(decimal radius);
|
void setRadius(decimal radius);
|
||||||
|
|
||||||
// Return the height
|
/// Return the height
|
||||||
decimal getHeight() const;
|
decimal getHeight() const;
|
||||||
|
|
||||||
// Set the height
|
/// Set the height
|
||||||
void setHeight(decimal height);
|
void setHeight(decimal height);
|
||||||
|
|
||||||
// Return a local support point in a given direction with the object margin
|
/// Return a local support point in a given direction with the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
|
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
|
||||||
|
|
||||||
// Return a local support point in a given direction without the object margin
|
/// Return a local support point in a given direction without the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
||||||
|
|
||||||
// Return the local extents in x,y and z direction
|
/// Return the local extents in x,y and z direction
|
||||||
virtual Vector3 getLocalExtents(decimal margin=0.0) const;
|
virtual Vector3 getLocalExtents(decimal margin=0.0) const;
|
||||||
|
|
||||||
// Return the local inertia tensor of the collision shape
|
/// Return the local inertia tensor of the collision shape
|
||||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
||||||
|
|
||||||
// Return the margin distance around the shape
|
/// Return the margin distance around the shape
|
||||||
virtual decimal getMargin() const;
|
virtual decimal getMargin() const;
|
||||||
|
|
||||||
#ifdef VISUAL_DEBUG
|
#ifdef VISUAL_DEBUG
|
||||||
// Draw the sphere (only for testing purpose)
|
/// Draw the sphere (only for testing purpose)
|
||||||
virtual void draw() const;
|
virtual void draw() const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,76 +31,75 @@
|
||||||
#include "../../mathematics/mathematics.h"
|
#include "../../mathematics/mathematics.h"
|
||||||
|
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class CylinderShape
|
||||||
Class CylinderShape :
|
/**
|
||||||
This class represents a cylinder collision shape around the Y axis
|
* This class represents a cylinder collision shape around the Y axis
|
||||||
and centered at the origin. The cylinder is defined by its height
|
* and centered at the origin. The cylinder is defined by its height
|
||||||
and the radius of its base. The "transform" of the corresponding
|
* and the radius of its base. The "transform" of the corresponding
|
||||||
rigid body gives an orientation and a position to the cylinder.
|
* rigid body gives an orientation and a position to the cylinder.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class CylinderShape : public CollisionShape {
|
class CylinderShape : public CollisionShape {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Radius of the base
|
/// Radius of the base
|
||||||
decimal mRadius;
|
decimal mRadius;
|
||||||
|
|
||||||
// Half height of the cone
|
/// Half height of the cone
|
||||||
decimal mHalfHeight;
|
decimal mHalfHeight;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
CylinderShape(const CylinderShape& shape);
|
CylinderShape(const CylinderShape& shape);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
CylinderShape& operator=(const CylinderShape& shape);
|
CylinderShape& operator=(const CylinderShape& shape);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
CylinderShape(decimal radius, decimal height);
|
CylinderShape(decimal radius, decimal height);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~CylinderShape();
|
virtual ~CylinderShape();
|
||||||
|
|
||||||
// Return the radius
|
/// Return the radius
|
||||||
decimal getRadius() const;
|
decimal getRadius() const;
|
||||||
|
|
||||||
// Set the radius
|
/// Set the radius
|
||||||
void setRadius(decimal mRadius);
|
void setRadius(decimal mRadius);
|
||||||
|
|
||||||
// Return the height
|
/// Return the height
|
||||||
decimal getHeight() const;
|
decimal getHeight() const;
|
||||||
|
|
||||||
// Set the height
|
/// Set the height
|
||||||
void setHeight(decimal height);
|
void setHeight(decimal height);
|
||||||
|
|
||||||
// Return a local support point in a given direction with the object margin
|
/// Return a local support point in a given direction with the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
|
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
|
||||||
|
|
||||||
// Return a local support point in a given direction without the object margin
|
/// Return a local support point in a given direction without the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
||||||
|
|
||||||
// Return the local extents in x,y and z direction
|
/// Return the local extents in x,y and z direction
|
||||||
virtual Vector3 getLocalExtents(decimal margin=0.0) const;
|
virtual Vector3 getLocalExtents(decimal margin=0.0) const;
|
||||||
|
|
||||||
// Return the local inertia tensor of the collision shape
|
/// Return the local inertia tensor of the collision shape
|
||||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
||||||
|
|
||||||
// Return the margin distance around the shape
|
/// Return the margin distance around the shape
|
||||||
virtual decimal getMargin() const;
|
virtual decimal getMargin() const;
|
||||||
|
|
||||||
#ifdef VISUAL_DEBUG
|
#ifdef VISUAL_DEBUG
|
||||||
// Draw the sphere (only for testing purpose)
|
/// Draw the sphere (only for testing purpose)
|
||||||
virtual void draw() const;
|
virtual void draw() const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,62 +33,61 @@
|
||||||
// ReactPhysics3D namespace
|
// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class SphereShape
|
||||||
Class SphereShape :
|
/**
|
||||||
This class represents a sphere collision shape that is centered
|
* This class represents a sphere collision shape that is centered
|
||||||
at the origin and defined by its radius.
|
* at the origin and defined by its radius.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class SphereShape : public CollisionShape {
|
class SphereShape : public CollisionShape {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Radius of the sphere
|
/// Radius of the sphere
|
||||||
decimal mRadius;
|
decimal mRadius;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
SphereShape(const SphereShape& shape);
|
SphereShape(const SphereShape& shape);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
SphereShape& operator=(const SphereShape& shape);
|
SphereShape& operator=(const SphereShape& shape);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
SphereShape(decimal radius);
|
SphereShape(decimal radius);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~SphereShape();
|
virtual ~SphereShape();
|
||||||
|
|
||||||
// Return the radius of the sphere
|
/// Return the radius of the sphere
|
||||||
decimal getRadius() const;
|
decimal getRadius() const;
|
||||||
|
|
||||||
// Set the radius of the sphere
|
/// Set the radius of the sphere
|
||||||
void setRadius(decimal radius);
|
void setRadius(decimal radius);
|
||||||
|
|
||||||
// Return a local support point in a given direction with the object margin
|
/// Return a local support point in a given direction with the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
|
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
|
||||||
|
|
||||||
// Return a local support point in a given direction without the object margin
|
/// Return a local support point in a given direction without the object margin
|
||||||
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
||||||
|
|
||||||
// Return the local extents in x,y and z direction
|
/// Return the local extents in x,y and z direction
|
||||||
virtual Vector3 getLocalExtents(decimal margin=0.0) const;
|
virtual Vector3 getLocalExtents(decimal margin=0.0) const;
|
||||||
|
|
||||||
// Return the local inertia tensor of the collision shape
|
/// Return the local inertia tensor of the collision shape
|
||||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
||||||
|
|
||||||
// Return the margin distance around the shape
|
/// Return the margin distance around the shape
|
||||||
virtual decimal getMargin() const;
|
virtual decimal getMargin() const;
|
||||||
|
|
||||||
#ifdef VISUAL_DEBUG
|
#ifdef VISUAL_DEBUG
|
||||||
// Draw the sphere (only for testing purpose)
|
/// Draw the sphere (only for testing purpose)
|
||||||
virtual void draw() const;
|
virtual void draw() const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#define LINUX_OS
|
#define LINUX_OS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Namespace reactphysics3d
|
/// Namespace reactphysics3d
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// ------------------- Type definitions ------------------- //
|
// ------------------- Type definitions ------------------- //
|
||||||
|
@ -53,35 +53,37 @@ typedef std::pair<bodyindex, bodyindex> bodyindexpair;
|
||||||
|
|
||||||
// ------------------- Constants ------------------- //
|
// ------------------- Constants ------------------- //
|
||||||
|
|
||||||
|
/// Smallest decimal value (negative)
|
||||||
const decimal DECIMAL_SMALLEST = - std::numeric_limits<decimal>::max();
|
const decimal DECIMAL_SMALLEST = - std::numeric_limits<decimal>::max();
|
||||||
|
|
||||||
// Maximum decimal value
|
/// Maximum decimal value
|
||||||
const decimal DECIMAL_LARGEST = std::numeric_limits<decimal>::max();
|
const decimal DECIMAL_LARGEST = std::numeric_limits<decimal>::max();
|
||||||
|
|
||||||
// Machine epsilon
|
/// Machine epsilon
|
||||||
const decimal MACHINE_EPSILON = std::numeric_limits<decimal>::epsilon();
|
const decimal MACHINE_EPSILON = std::numeric_limits<decimal>::epsilon();
|
||||||
|
|
||||||
// Pi constant
|
/// Pi constant
|
||||||
const decimal PI = decimal(3.14159265);
|
const decimal PI = decimal(3.14159265);
|
||||||
|
|
||||||
// Default internal constant timestep in seconds
|
/// Default internal constant timestep in seconds
|
||||||
const decimal DEFAULT_TIMESTEP = decimal(1.0 / 60.0);
|
const decimal DEFAULT_TIMESTEP = decimal(1.0 / 60.0);
|
||||||
|
|
||||||
// Default friction coefficient for a rigid body
|
/// Default friction coefficient for a rigid body
|
||||||
const decimal DEFAULT_FRICTION_COEFFICIENT = decimal(0.3);
|
const decimal DEFAULT_FRICTION_COEFFICIENT = decimal(0.3);
|
||||||
|
|
||||||
// True if the deactivation (sleeping) of inactive bodies is enabled
|
/// True if the deactivation (sleeping) of inactive bodies is enabled
|
||||||
const bool DEACTIVATION_ENABLED = true;
|
const bool DEACTIVATION_ENABLED = true;
|
||||||
|
|
||||||
// // Object margin for collision detection in cm (For GJK-EPA Algorithm)
|
///Object margin for collision detection in cm (For GJK-EPA Algorithm)
|
||||||
const decimal OBJECT_MARGIN = decimal(0.04);
|
const decimal OBJECT_MARGIN = decimal(0.04);
|
||||||
|
|
||||||
// Distance threshold for two contact points for a valid persistent contact (in meters)
|
/// Distance threshold for two contact points for a valid persistent contact (in meters)
|
||||||
const decimal PERSISTENT_CONTACT_DIST_THRESHOLD = decimal(0.03);
|
const decimal PERSISTENT_CONTACT_DIST_THRESHOLD = decimal(0.03);
|
||||||
|
|
||||||
|
/// Velocity threshold for contact velocity restitution
|
||||||
const decimal RESTITUTION_VELOCITY_THRESHOLD = decimal(1.0);
|
const decimal RESTITUTION_VELOCITY_THRESHOLD = decimal(1.0);
|
||||||
|
|
||||||
// Number of iterations when solving a LCP problem
|
/// Number of iterations when solving a LCP problem
|
||||||
const uint DEFAULT_CONSTRAINTS_SOLVER_NB_ITERATIONS = 15;
|
const uint DEFAULT_CONSTRAINTS_SOLVER_NB_ITERATIONS = 15;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "Constraint.h"
|
#include "Constraint.h"
|
||||||
|
|
||||||
// We want ot use the ReactPhysics3D namespace
|
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
|
|
@ -36,77 +36,76 @@ namespace reactphysics3d {
|
||||||
// Enumeration for the type of a constraint
|
// Enumeration for the type of a constraint
|
||||||
enum ConstraintType {CONTACT};
|
enum ConstraintType {CONTACT};
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class Constraint
|
||||||
Class Constraint :
|
/**
|
||||||
This abstract class represents a constraint in the physics engine.
|
* This abstract class represents a constraint in the physics engine.
|
||||||
A constraint can be a collision contact or a joint for
|
* A constraint can be a collision contact or a joint for
|
||||||
instance. Each constraint can be made of several "mathematical
|
* instance. Each constraint can be made of several "mathematical
|
||||||
constraints" needed to represent the main constraint.
|
* constraints" needed to represent the main constraint.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class Constraint {
|
class Constraint {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Pointer to the first body of the constraint
|
/// Pointer to the first body of the constraint
|
||||||
RigidBody* const mBody1;
|
RigidBody* const mBody1;
|
||||||
|
|
||||||
// Pointer to the second body of the constraint
|
/// Pointer to the second body of the constraint
|
||||||
RigidBody* const mBody2;
|
RigidBody* const mBody2;
|
||||||
|
|
||||||
// True if the constraint is active
|
/// True if the constraint is active
|
||||||
bool mActive;
|
bool mActive;
|
||||||
|
|
||||||
// Number mathematical constraints associated with this Constraint
|
/// Number mathematical constraints associated with this Constraint
|
||||||
uint mNbConstraints;
|
uint mNbConstraints;
|
||||||
|
|
||||||
// Type of the constraint
|
/// Type of the constraint
|
||||||
const ConstraintType mType;
|
const ConstraintType mType;
|
||||||
|
|
||||||
// Cached lambda values of each mathematical constraint for
|
/// Cached lambda values of each mathematical constraint for
|
||||||
// more precise initializaton of LCP solver
|
/// more precise initializaton of LCP solver
|
||||||
std::vector<decimal> mCachedLambdas;
|
std::vector<decimal> mCachedLambdas;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
Constraint(const Constraint& constraint);
|
Constraint(const Constraint& constraint);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
Constraint& operator=(const Constraint& constraint);
|
Constraint& operator=(const Constraint& constraint);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Constraint(RigidBody* const body1, RigidBody* const body2, uint nbConstraints,
|
Constraint(RigidBody* const body1, RigidBody* const body2, uint nbConstraints,
|
||||||
bool active, ConstraintType type);
|
bool active, ConstraintType type);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~Constraint();
|
virtual ~Constraint();
|
||||||
|
|
||||||
// Return the reference to the body 1
|
/// Return the reference to the body 1
|
||||||
RigidBody* const getBody1() const;
|
RigidBody* const getBody1() const;
|
||||||
|
|
||||||
// Return the reference to the body 2
|
/// Return the reference to the body 2
|
||||||
RigidBody* const getBody2() const;
|
RigidBody* const getBody2() const;
|
||||||
|
|
||||||
// Return true if the constraint is active
|
/// Return true if the constraint is active
|
||||||
bool isActive() const;
|
bool isActive() const;
|
||||||
|
|
||||||
// Return the type of the constraint
|
/// Return the type of the constraint
|
||||||
ConstraintType getType() const;
|
ConstraintType getType() const;
|
||||||
|
|
||||||
// Return the number of mathematical constraints
|
/// Return the number of mathematical constraints
|
||||||
unsigned int getNbConstraints() const;
|
unsigned int getNbConstraints() const;
|
||||||
|
|
||||||
// Get one cached lambda value
|
/// Get one cached lambda value
|
||||||
decimal getCachedLambda(int index) const;
|
decimal getCachedLambda(int index) const;
|
||||||
|
|
||||||
// Set on cached lambda value
|
/// Set on cached lambda value
|
||||||
void setCachedLambda(int index, decimal lambda);
|
void setCachedLambda(int index, decimal lambda);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,111 +48,110 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class ContactPoint
|
||||||
Class ContactPoint :
|
/**
|
||||||
This class represents a collision contact point between two
|
* This class represents a collision contact point between two
|
||||||
bodies in the physics engine. The ContactPoint class inherits from
|
* bodies in the physics engine. The ContactPoint class inherits from
|
||||||
the Constraint class.
|
* the Constraint class.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class ContactPoint : public Constraint {
|
class ContactPoint : public Constraint {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Normal vector of the contact (From body1 toward body2) in world space
|
/// Normal vector of the contact (From body1 toward body2) in world space
|
||||||
const Vector3 mNormal;
|
const Vector3 mNormal;
|
||||||
|
|
||||||
// Penetration depth
|
/// Penetration depth
|
||||||
decimal mPenetrationDepth;
|
decimal mPenetrationDepth;
|
||||||
|
|
||||||
// Contact point on body 1 in local space of body 1
|
/// Contact point on body 1 in local space of body 1
|
||||||
const Vector3 mLocalPointOnBody1;
|
const Vector3 mLocalPointOnBody1;
|
||||||
|
|
||||||
// Contact point on body 2 in local space of body 2
|
/// Contact point on body 2 in local space of body 2
|
||||||
const Vector3 mLocalPointOnBody2;
|
const Vector3 mLocalPointOnBody2;
|
||||||
|
|
||||||
// Contact point on body 1 in world space
|
/// Contact point on body 1 in world space
|
||||||
Vector3 mWorldPointOnBody1;
|
Vector3 mWorldPointOnBody1;
|
||||||
|
|
||||||
// Contact point on body 2 in world space
|
/// Contact point on body 2 in world space
|
||||||
Vector3 mWorldPointOnBody2;
|
Vector3 mWorldPointOnBody2;
|
||||||
|
|
||||||
// True if the contact is a resting contact (exists for more than one time step)
|
/// True if the contact is a resting contact (exists for more than one time step)
|
||||||
bool mIsRestingContact;
|
bool mIsRestingContact;
|
||||||
|
|
||||||
// Two orthogonal vectors that span the tangential friction plane
|
/// Two orthogonal vectors that span the tangential friction plane
|
||||||
std::vector<Vector3> mFrictionVectors;
|
std::vector<Vector3> mFrictionVectors;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
ContactPoint(const ContactPoint& contact);
|
ContactPoint(const ContactPoint& contact);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
ContactPoint& operator=(const ContactPoint& contact);
|
ContactPoint& operator=(const ContactPoint& contact);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
ContactPoint(RigidBody* const body1, RigidBody* const body2, const ContactInfo* contactInfo);
|
ContactPoint(RigidBody* const body1, RigidBody* const body2, const ContactInfo* contactInfo);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~ContactPoint();
|
virtual ~ContactPoint();
|
||||||
|
|
||||||
// Return the normal vector of the contact
|
/// Return the normal vector of the contact
|
||||||
Vector3 getNormal() const;
|
Vector3 getNormal() const;
|
||||||
|
|
||||||
// Set the penetration depth of the contact
|
/// Set the penetration depth of the contact
|
||||||
void setPenetrationDepth(decimal penetrationDepth);
|
void setPenetrationDepth(decimal penetrationDepth);
|
||||||
|
|
||||||
// Return the contact local point on body 1
|
/// Return the contact local point on body 1
|
||||||
Vector3 getLocalPointOnBody1() const;
|
Vector3 getLocalPointOnBody1() const;
|
||||||
|
|
||||||
// Return the contact local point on body 2
|
/// Return the contact local point on body 2
|
||||||
Vector3 getLocalPointOnBody2() const;
|
Vector3 getLocalPointOnBody2() const;
|
||||||
|
|
||||||
// Return the contact world point on body 1
|
/// Return the contact world point on body 1
|
||||||
Vector3 getWorldPointOnBody1() const;
|
Vector3 getWorldPointOnBody1() const;
|
||||||
|
|
||||||
// Return the contact world point on body 2
|
/// Return the contact world point on body 2
|
||||||
Vector3 getWorldPointOnBody2() const;
|
Vector3 getWorldPointOnBody2() const;
|
||||||
|
|
||||||
// Set the contact world point on body 1
|
/// Set the contact world point on body 1
|
||||||
void setWorldPointOnBody1(const Vector3& worldPoint);
|
void setWorldPointOnBody1(const Vector3& worldPoint);
|
||||||
|
|
||||||
// Set the contact world point on body 2
|
/// Set the contact world point on body 2
|
||||||
void setWorldPointOnBody2(const Vector3& worldPoint);
|
void setWorldPointOnBody2(const Vector3& worldPoint);
|
||||||
|
|
||||||
// Return true if the contact is a resting contact
|
/// Return true if the contact is a resting contact
|
||||||
bool getIsRestingContact() const;
|
bool getIsRestingContact() const;
|
||||||
|
|
||||||
// Set the mIsRestingContact variable
|
/// Set the mIsRestingContact variable
|
||||||
void setIsRestingContact(bool isRestingContact);
|
void setIsRestingContact(bool isRestingContact);
|
||||||
|
|
||||||
// Get the first friction vector
|
/// Get the first friction vector
|
||||||
Vector3 getFrictionVector1() const;
|
Vector3 getFrictionVector1() const;
|
||||||
|
|
||||||
// Set the first friction vector
|
/// Set the first friction vector
|
||||||
void setFrictionVector1(const Vector3& frictionVector1);
|
void setFrictionVector1(const Vector3& frictionVector1);
|
||||||
|
|
||||||
// Get the second friction vector
|
/// Get the second friction vector
|
||||||
Vector3 getFrictionVector2() const;
|
Vector3 getFrictionVector2() const;
|
||||||
|
|
||||||
// Set the second friction vector
|
/// Set the second friction vector
|
||||||
void setFrictionVector2(const Vector3& frictionVector2);
|
void setFrictionVector2(const Vector3& frictionVector2);
|
||||||
|
|
||||||
// Return the penetration depth
|
/// Return the penetration depth
|
||||||
decimal getPenetrationDepth() const;
|
decimal getPenetrationDepth() const;
|
||||||
|
|
||||||
#ifdef VISUAL_DEBUG
|
#ifdef VISUAL_DEBUG
|
||||||
// Draw the contact (for debugging)
|
/// Draw the contact (for debugging)
|
||||||
void draw() const;
|
void draw() const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#ifndef DECIMAL_H
|
#ifndef DECIMAL_H
|
||||||
#define DECIMAL_H
|
#define DECIMAL_H
|
||||||
|
|
||||||
// ReactPhysiscs3D namespace
|
/// ReactPhysiscs3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
#if defined(DOUBLE_PRECISION_ENABLED) // If we are compiling for double precision
|
#if defined(DOUBLE_PRECISION_ENABLED) // If we are compiling for double precision
|
||||||
|
|
|
@ -38,84 +38,83 @@
|
||||||
#include "../constraint/ContactPoint.h"
|
#include "../constraint/ContactPoint.h"
|
||||||
#include "../memory/MemoryPool.h"
|
#include "../memory/MemoryPool.h"
|
||||||
|
|
||||||
// Namespace reactphysics3d
|
/// Namespace reactphysics3d
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class CollisionWorld
|
||||||
Class CollisionWorld :
|
/**
|
||||||
This class represent a world where it is possible to move bodies
|
* 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
|
* 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.
|
* world, the bodies movement is not computed using the laws of physics.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class CollisionWorld {
|
class CollisionWorld {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Reference to the collision detection
|
/// Reference to the collision detection
|
||||||
CollisionDetection mCollisionDetection;
|
CollisionDetection mCollisionDetection;
|
||||||
|
|
||||||
// All the bodies (rigid and soft) of the world
|
/// All the bodies (rigid and soft) of the world
|
||||||
std::set<CollisionBody*> mBodies;
|
std::set<CollisionBody*> mBodies;
|
||||||
|
|
||||||
// Broad-phase overlapping pairs of bodies
|
/// Broad-phase overlapping pairs of bodies
|
||||||
std::map<bodyindexpair, OverlappingPair*> mOverlappingPairs;
|
std::map<bodyindexpair, OverlappingPair*> mOverlappingPairs;
|
||||||
|
|
||||||
// Current body ID
|
/// Current body ID
|
||||||
bodyindex mCurrentBodyID;
|
bodyindex mCurrentBodyID;
|
||||||
|
|
||||||
// Memory pool
|
/// Memory pool
|
||||||
MemoryPool<CollisionBody> mMemoryPoolCollisionBodies;
|
MemoryPool<CollisionBody> mMemoryPoolCollisionBodies;
|
||||||
|
|
||||||
// List of free ID for rigid bodies
|
/// List of free ID for rigid bodies
|
||||||
std::vector<luint> mFreeBodiesIDs;
|
std::vector<luint> mFreeBodiesIDs;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
CollisionWorld(const CollisionWorld& world);
|
CollisionWorld(const CollisionWorld& world);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
CollisionWorld& operator=(const CollisionWorld& world);
|
CollisionWorld& operator=(const CollisionWorld& world);
|
||||||
|
|
||||||
// Notify the world about a new broad-phase overlapping pair
|
/// Notify the world about a new broad-phase overlapping pair
|
||||||
virtual void notifyAddedOverlappingPair(const BroadPhasePair* addedPair);
|
virtual void notifyAddedOverlappingPair(const BroadPhasePair* addedPair);
|
||||||
|
|
||||||
// Notify the world about a removed broad-phase overlapping pair
|
/// Notify the world about a removed broad-phase overlapping pair
|
||||||
virtual void notifyRemovedOverlappingPair(const BroadPhasePair* removedPair);
|
virtual void notifyRemovedOverlappingPair(const BroadPhasePair* removedPair);
|
||||||
|
|
||||||
// Notify the world about a new narrow-phase contact
|
/// Notify the world about a new narrow-phase contact
|
||||||
virtual void notifyNewContact(const BroadPhasePair* pair, const ContactInfo* contactInfo);
|
virtual void notifyNewContact(const BroadPhasePair* pair, const ContactInfo* contactInfo);
|
||||||
|
|
||||||
// Update the overlapping pair
|
/// Update the overlapping pair
|
||||||
virtual void updateOverlappingPair(const BroadPhasePair* pair);
|
virtual void updateOverlappingPair(const BroadPhasePair* pair);
|
||||||
|
|
||||||
// Return the next available body ID
|
/// Return the next available body ID
|
||||||
bodyindex computeNextAvailableBodyID();
|
bodyindex computeNextAvailableBodyID();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// ----- Methods ----- //
|
// ----- Methods ----- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
CollisionWorld();
|
CollisionWorld();
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~CollisionWorld();
|
virtual ~CollisionWorld();
|
||||||
|
|
||||||
// Return an iterator to the beginning of the bodies of the physics world
|
/// Return an iterator to the beginning of the bodies of the physics world
|
||||||
std::set<CollisionBody*>::iterator getBodiesBeginIterator();
|
std::set<CollisionBody*>::iterator getBodiesBeginIterator();
|
||||||
|
|
||||||
// Return an iterator to the end of the bodies of the physics world
|
/// Return an iterator to the end of the bodies of the physics world
|
||||||
std::set<CollisionBody*>::iterator getBodiesEndIterator();
|
std::set<CollisionBody*>::iterator getBodiesEndIterator();
|
||||||
|
|
||||||
// Create a collision body
|
/// Create a collision body
|
||||||
CollisionBody* createCollisionBody(const Transform& transform,
|
CollisionBody* createCollisionBody(const Transform& transform,
|
||||||
CollisionShape* collisionShape);
|
CollisionShape* collisionShape);
|
||||||
|
|
||||||
// Destroy a collision body
|
/// Destroy a collision body
|
||||||
void destroyCollisionBody(CollisionBody* collisionBody);
|
void destroyCollisionBody(CollisionBody* collisionBody);
|
||||||
|
|
||||||
// ----- Friends ----- //
|
// ----- Friends ----- //
|
||||||
|
|
|
@ -95,11 +95,11 @@ void ContactManifold::removeContactPoint(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the contact manifold
|
// Update the contact manifold
|
||||||
// First the world space coordinates of the current contacts in the manifold are recomputed from
|
/// First the world space coordinates of the current contacts in the manifold are recomputed from
|
||||||
// the corresponding transforms of the bodies because they have moved. Then we remove the contacts
|
/// the corresponding transforms of the bodies because they have moved. Then we remove the contacts
|
||||||
// with a negative penetration depth (meaning that the bodies are not penetrating anymore) and also
|
/// with a negative penetration depth (meaning that the bodies are not penetrating anymore) and also
|
||||||
// the contacts with a too large distance between the contact points in the plane orthogonal to the
|
/// the contacts with a too large distance between the contact points in the plane orthogonal to the
|
||||||
// contact normal
|
/// contact normal.
|
||||||
void ContactManifold::update(const Transform& transform1, const Transform& transform2) {
|
void ContactManifold::update(const Transform& transform1, const Transform& transform2) {
|
||||||
if (mNbContactPoints == 0) return;
|
if (mNbContactPoints == 0) return;
|
||||||
|
|
||||||
|
@ -140,9 +140,9 @@ void ContactManifold::update(const Transform& transform1, const Transform& trans
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the index of the contact point with the larger penetration depth. This
|
// Return the index of the contact point with the larger penetration depth.
|
||||||
// corresponding contact will be kept in the cache. The method returns -1 is
|
/// This corresponding contact will be kept in the cache. The method returns -1 is
|
||||||
// the new contact is the deepest.
|
/// the new contact is the deepest.
|
||||||
int ContactManifold::getIndexOfDeepestPenetration(ContactPoint* newContact) const {
|
int ContactManifold::getIndexOfDeepestPenetration(ContactPoint* newContact) const {
|
||||||
assert(mNbContactPoints == MAX_CONTACT_POINTS_IN_MANIFOLD);
|
assert(mNbContactPoints == MAX_CONTACT_POINTS_IN_MANIFOLD);
|
||||||
int indexMaxPenetrationDepth = -1;
|
int indexMaxPenetrationDepth = -1;
|
||||||
|
@ -162,14 +162,15 @@ int ContactManifold::getIndexOfDeepestPenetration(ContactPoint* newContact) cons
|
||||||
return indexMaxPenetrationDepth;
|
return indexMaxPenetrationDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the index that will be removed. The index of the contact point with the larger penetration
|
// Return the index that will be removed.
|
||||||
// depth is given as a parameter. This contact won't be removed. Given this contact, we compute
|
/// The index of the contact point with the larger penetration
|
||||||
// the different area and we want to keep the contacts with the largest area. The new point is also
|
/// depth is given as a parameter. This contact won't be removed. Given this contact, we compute
|
||||||
// kept. In order to compute the area of a quadrilateral, we use the formula :
|
/// the different area and we want to keep the contacts with the largest area. The new point is also
|
||||||
// Area = 0.5 * | AC x BD | where AC and BD form the diagonals of the quadrilateral. Note that
|
/// kept. In order to compute the area of a quadrilateral, we use the formula :
|
||||||
// when we compute this area, we do not calculate it exactly but we
|
/// Area = 0.5 * | AC x BD | where AC and BD form the diagonals of the quadrilateral. Note that
|
||||||
// only estimate it because we do not compute the actual diagonals of the quadrialteral. Therefore,
|
/// when we compute this area, we do not calculate it exactly but we
|
||||||
// this is only a guess that is faster to compute.
|
/// only estimate it because we do not compute the actual diagonals of the quadrialteral. Therefore,
|
||||||
|
/// this is only a guess that is faster to compute.
|
||||||
int ContactManifold::getIndexToRemove(int indexMaxPenetration, const Vector3& newPoint) const {
|
int ContactManifold::getIndexToRemove(int indexMaxPenetration, const Vector3& newPoint) const {
|
||||||
|
|
||||||
assert(mNbContactPoints == MAX_CONTACT_POINTS_IN_MANIFOLD);
|
assert(mNbContactPoints == MAX_CONTACT_POINTS_IN_MANIFOLD);
|
||||||
|
|
|
@ -31,141 +31,140 @@
|
||||||
#include "../body/Body.h"
|
#include "../body/Body.h"
|
||||||
#include "../constraint/ContactPoint.h"
|
#include "../constraint/ContactPoint.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const uint MAX_CONTACT_POINTS_IN_MANIFOLD = 4; // Maximum number of contacts in the manifold
|
const uint MAX_CONTACT_POINTS_IN_MANIFOLD = 4; // Maximum number of contacts in the manifold
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class ContactManifold
|
||||||
Class ContactManifold :
|
/**
|
||||||
This class represents the set of contact points between two bodies.
|
* This class represents the set of contact points between two bodies.
|
||||||
The contact manifold is implemented in a way to cache the contact
|
* The contact manifold is implemented in a way to cache the contact
|
||||||
points among the frames for better stability following the
|
* points among the frames for better stability following the
|
||||||
"Contact Generation" presentation of Erwin Coumans at GDC 2010
|
* "Contact Generation" presentation of Erwin Coumans at GDC 2010
|
||||||
conference (bullet.googlecode.com/files/GDC10_Coumans_Erwin_Contact.pdf).
|
* conference (bullet.googlecode.com/files/GDC10_Coumans_Erwin_Contact.pdf).
|
||||||
Some code of this class is based on the implementation of the
|
* Some code of this class is based on the implementation of the
|
||||||
btPersistentManifold class from Bullet physics engine (www.http://bulletphysics.org).
|
* btPersistentManifold class from Bullet physics engine (www.http://bulletphysics.org).
|
||||||
The contacts between two bodies are added one after the other in the cache.
|
* The contacts between two bodies are added one after the other in the cache.
|
||||||
When the cache is full, we have to remove one point. The idea is to keep
|
* When the cache is full, we have to remove one point. The idea is to keep
|
||||||
the point with the deepest penetration depth and also to keep the
|
* the point with the deepest penetration depth and also to keep the
|
||||||
points producing the larger area (for a more stable contact manifold).
|
* points producing the larger area (for a more stable contact manifold).
|
||||||
The new added point is always kept.
|
* The new added point is always kept.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class ContactManifold {
|
class ContactManifold {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Pointer to the first body
|
/// Pointer to the first body
|
||||||
Body* const mBody1;
|
Body* const mBody1;
|
||||||
|
|
||||||
// Pointer to the second body
|
/// Pointer to the second body
|
||||||
Body* const mBody2;
|
Body* const mBody2;
|
||||||
|
|
||||||
// Contact points in the manifold
|
/// Contact points in the manifold
|
||||||
ContactPoint* mContactPoints[MAX_CONTACT_POINTS_IN_MANIFOLD];
|
ContactPoint* mContactPoints[MAX_CONTACT_POINTS_IN_MANIFOLD];
|
||||||
|
|
||||||
// Number of contacts in the cache
|
/// Number of contacts in the cache
|
||||||
uint mNbContactPoints;
|
uint mNbContactPoints;
|
||||||
|
|
||||||
// First friction vector of the contact manifold
|
/// First friction vector of the contact manifold
|
||||||
Vector3 mFrictionVector1;
|
Vector3 mFrictionVector1;
|
||||||
|
|
||||||
// Second friction vector of the contact manifold
|
/// Second friction vector of the contact manifold
|
||||||
Vector3 mFrictionVector2;
|
Vector3 mFrictionVector2;
|
||||||
|
|
||||||
// First friction constraint accumulated impulse
|
/// First friction constraint accumulated impulse
|
||||||
decimal mFrictionImpulse1;
|
decimal mFrictionImpulse1;
|
||||||
|
|
||||||
// Second friction constraint accumulated impulse
|
/// Second friction constraint accumulated impulse
|
||||||
decimal mFrictionImpulse2;
|
decimal mFrictionImpulse2;
|
||||||
|
|
||||||
// Twist friction constraint accumulated impulse
|
/// Twist friction constraint accumulated impulse
|
||||||
decimal mFrictionTwistImpulse;
|
decimal mFrictionTwistImpulse;
|
||||||
|
|
||||||
// Reference to the memory pool with the contacts
|
/// Reference to the memory pool with the contacts
|
||||||
MemoryPool<ContactPoint>& mMemoryPoolContacts;
|
MemoryPool<ContactPoint>& mMemoryPoolContacts;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
ContactManifold(const ContactManifold& contactManifold);
|
ContactManifold(const ContactManifold& contactManifold);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
ContactManifold& operator=(const ContactManifold& contactManifold);
|
ContactManifold& operator=(const ContactManifold& contactManifold);
|
||||||
|
|
||||||
// Return the index of maximum area
|
/// Return the index of maximum area
|
||||||
int getMaxArea(decimal area0, decimal area1, decimal area2, decimal area3) const;
|
int getMaxArea(decimal area0, decimal area1, decimal area2, decimal area3) const;
|
||||||
|
|
||||||
// Return the index of the contact with the larger penetration depth
|
/// Return the index of the contact with the larger penetration depth.
|
||||||
int getIndexOfDeepestPenetration(ContactPoint* newContact) const;
|
int getIndexOfDeepestPenetration(ContactPoint* newContact) const;
|
||||||
|
|
||||||
// Return the index that will be removed
|
/// Return the index that will be removed.
|
||||||
int getIndexToRemove(int indexMaxPenetration, const Vector3& newPoint) const;
|
int getIndexToRemove(int indexMaxPenetration, const Vector3& newPoint) const;
|
||||||
|
|
||||||
// Remove a contact point from the manifold
|
/// Remove a contact point from the manifold
|
||||||
void removeContactPoint(int index);
|
void removeContactPoint(int index);
|
||||||
|
|
||||||
// Return true if two vectors are approximatively equal
|
/// Return true if two vectors are approximatively equal
|
||||||
bool isApproxEqual(const Vector3& vector1, const Vector3& vector2) const;
|
bool isApproxEqual(const Vector3& vector1, const Vector3& vector2) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
ContactManifold(Body* const mBody1, Body* const mBody2,
|
ContactManifold(Body* const mBody1, Body* const mBody2,
|
||||||
MemoryPool<ContactPoint>& mMemoryPoolContacts);
|
MemoryPool<ContactPoint>& mMemoryPoolContacts);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~ContactManifold();
|
~ContactManifold();
|
||||||
|
|
||||||
// Add a contact point to the manifold
|
/// Add a contact point to the manifold
|
||||||
void addContactPoint(ContactPoint* contact);
|
void addContactPoint(ContactPoint* contact);
|
||||||
|
|
||||||
// Update the contact manifold
|
/// Update the contact manifold.
|
||||||
void update(const Transform& transform1, const Transform& transform2);
|
void update(const Transform& transform1, const Transform& transform2);
|
||||||
|
|
||||||
// Clear the contact manifold
|
/// Clear the contact manifold
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
// Return the number of contact points in the manifold
|
/// Return the number of contact points in the manifold
|
||||||
uint getNbContactPoints() const;
|
uint getNbContactPoints() const;
|
||||||
|
|
||||||
// Return the first friction vector at the center of the contact manifold
|
/// Return the first friction vector at the center of the contact manifold
|
||||||
const Vector3& getFrictionVector1() const;
|
const Vector3& getFrictionVector1() const;
|
||||||
|
|
||||||
// set the first friction vector at the center of the contact manifold
|
/// set the first friction vector at the center of the contact manifold
|
||||||
void setFrictionVector1(const Vector3& mFrictionVector1);
|
void setFrictionVector1(const Vector3& mFrictionVector1);
|
||||||
|
|
||||||
// Return the second friction vector at the center of the contact manifold
|
/// Return the second friction vector at the center of the contact manifold
|
||||||
const Vector3& getFrictionVector2() const;
|
const Vector3& getFrictionVector2() const;
|
||||||
|
|
||||||
// set the second friction vector at the center of the contact manifold
|
/// set the second friction vector at the center of the contact manifold
|
||||||
void setFrictionVector2(const Vector3& mFrictionVector2);
|
void setFrictionVector2(const Vector3& mFrictionVector2);
|
||||||
|
|
||||||
// Return the first friction accumulated impulse
|
/// Return the first friction accumulated impulse
|
||||||
decimal getFrictionImpulse1() const;
|
decimal getFrictionImpulse1() const;
|
||||||
|
|
||||||
// Set the first friction accumulated impulse
|
/// Set the first friction accumulated impulse
|
||||||
void setFrictionImpulse1(decimal frictionImpulse1);
|
void setFrictionImpulse1(decimal frictionImpulse1);
|
||||||
|
|
||||||
// Return the second friction accumulated impulse
|
/// Return the second friction accumulated impulse
|
||||||
decimal getFrictionImpulse2() const;
|
decimal getFrictionImpulse2() const;
|
||||||
|
|
||||||
// Set the second friction accumulated impulse
|
/// Set the second friction accumulated impulse
|
||||||
void setFrictionImpulse2(decimal frictionImpulse2);
|
void setFrictionImpulse2(decimal frictionImpulse2);
|
||||||
|
|
||||||
// Return the friction twist accumulated impulse
|
/// Return the friction twist accumulated impulse
|
||||||
decimal getFrictionTwistImpulse() const;
|
decimal getFrictionTwistImpulse() const;
|
||||||
|
|
||||||
// Set the friction twist accumulated impulse
|
/// Set the friction twist accumulated impulse
|
||||||
void setFrictionTwistImpulse(decimal frictionTwistImpulse);
|
void setFrictionTwistImpulse(decimal frictionTwistImpulse);
|
||||||
|
|
||||||
// Return a contact point of the manifold
|
/// Return a contact point of the manifold
|
||||||
ContactPoint* getContactPoint(uint index) const;
|
ContactPoint* getContactPoint(uint index) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -371,10 +371,10 @@ void ContactSolver::initializeContactConstraints() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warm start the solver
|
// Warm start the solver.
|
||||||
// For each constraint, we apply the previous impulse (from the previous step)
|
/// For each constraint, we apply the previous impulse (from the previous step)
|
||||||
// at the beginning. With this technique, we will converge faster towards
|
/// at the beginning. With this technique, we will converge faster towards
|
||||||
// the solution of the linear system
|
/// the solution of the linear system
|
||||||
void ContactSolver::warmStart() {
|
void ContactSolver::warmStart() {
|
||||||
|
|
||||||
// For each constraint
|
// For each constraint
|
||||||
|
@ -836,7 +836,7 @@ void ContactSolver::applySplitImpulse(const Impulse& impulse,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction plane
|
// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction plane
|
||||||
// for a contact point constraint. The two vectors have to be such that : t1 x t2 = contactNormal.
|
// for a contact point. The two vectors have to be such that : t1 x t2 = contactNormal.
|
||||||
void ContactSolver::computeFrictionVectors(const Vector3& deltaVelocity,
|
void ContactSolver::computeFrictionVectors(const Vector3& deltaVelocity,
|
||||||
ContactPointSolver& contactPoint) const {
|
ContactPointSolver& contactPoint) const {
|
||||||
|
|
||||||
|
@ -866,7 +866,7 @@ void ContactSolver::computeFrictionVectors(const Vector3& deltaVelocity,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction plane
|
// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction plane
|
||||||
// for a contact constraint. The two vectors have to be such that : t1 x t2 = contactNormal.
|
// for a contact manifold. The two vectors have to be such that : t1 x t2 = contactNormal.
|
||||||
void ContactSolver::computeFrictionVectors(const Vector3& deltaVelocity,
|
void ContactSolver::computeFrictionVectors(const Vector3& deltaVelocity,
|
||||||
ContactManifoldSolver& contact) const {
|
ContactManifoldSolver& contact) const {
|
||||||
|
|
||||||
|
|
|
@ -34,22 +34,33 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Declarations
|
// Declarations
|
||||||
class DynamicsWorld;
|
class DynamicsWorld;
|
||||||
|
|
||||||
// Structure Impulse
|
// Structure Impulse
|
||||||
|
/**
|
||||||
|
* Represents an impulse that we can apply to bodies in the contact or constraint solver.
|
||||||
|
*/
|
||||||
struct Impulse {
|
struct Impulse {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Linear impulse applied to the first body
|
||||||
const Vector3 linearImpulseBody1;
|
const Vector3 linearImpulseBody1;
|
||||||
|
|
||||||
|
/// Linear impulse applied to the second body
|
||||||
const Vector3 linearImpulseBody2;
|
const Vector3 linearImpulseBody2;
|
||||||
|
|
||||||
|
/// Angular impulse applied to the first body
|
||||||
const Vector3 angularImpulseBody1;
|
const Vector3 angularImpulseBody1;
|
||||||
|
|
||||||
|
/// Angular impulse applied to the second body
|
||||||
const Vector3 angularImpulseBody2;
|
const Vector3 angularImpulseBody2;
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Impulse(const Vector3& linearImpulseBody1, const Vector3& angularImpulseBody1,
|
Impulse(const Vector3& linearImpulseBody1, const Vector3& angularImpulseBody1,
|
||||||
const Vector3& linearImpulseBody2, const Vector3& angularImpulseBody2)
|
const Vector3& linearImpulseBody2, const Vector3& angularImpulseBody2)
|
||||||
: linearImpulseBody1(linearImpulseBody1), angularImpulseBody1(angularImpulseBody1),
|
: linearImpulseBody1(linearImpulseBody1), angularImpulseBody1(angularImpulseBody1),
|
||||||
|
@ -59,270 +70,380 @@ struct Impulse {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Class Contact Solver
|
||||||
|
/**
|
||||||
|
* This class represents the contact solver that is used to solve rigid bodies contacts.
|
||||||
|
* The constraint solver is based on the "Sequential Impulse" technique described by
|
||||||
|
* Erin Catto in his GDC slides (http://code.google.com/p/box2d/downloads/list).
|
||||||
|
*
|
||||||
|
* A constraint between two bodies is represented by a function C(x) which is equal to zero
|
||||||
|
* when the constraint is satisfied. The condition C(x)=0 describes a valid position and the
|
||||||
|
* condition dC(x)/dt=0 describes a valid velocity. We have dC(x)/dt = Jv + b = 0 where J is
|
||||||
|
* the Jacobian matrix of the constraint, v is a vector that contains the velocity of both
|
||||||
|
* bodies and b is the constraint bias. We are looking for a force F_c that will act on the
|
||||||
|
* bodies to keep the constraint satisfied. Note that from the virtual work principle, we have
|
||||||
|
* F_c = J^t * lambda where J^t is the transpose of the Jacobian matrix and lambda is a
|
||||||
|
* Lagrange multiplier. Therefore, finding the force F_c is equivalent to finding the Lagrange
|
||||||
|
* multiplier lambda.
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
* An impulse P = F * dt where F is a force and dt is the timestep. We can apply impulses a
|
||||||
Class ContactSolver :
|
* body to change its velocity. The idea of the Sequential Impulse technique is to apply
|
||||||
This class represents the contact solver that is used is solve rigid bodies contacts.
|
* impulses to bodies of each constraints in order to keep the constraint satisfied.
|
||||||
The constraint solver is based on the "Sequential Impulse" technique described by
|
*
|
||||||
Erin Catto in his GDC slides (http://code.google.com/p/box2d/downloads/list).
|
* --- Step 1 ---
|
||||||
|
*
|
||||||
A constraint between two bodies is represented by a function C(x) which is equal to zero
|
* First, we integrate the applied force F_a acting of each rigid body (like gravity, ...) and
|
||||||
when the constraint is satisfied. The condition C(x)=0 describes a valid position and the
|
* we obtain some new velocities v2' that tends to violate the constraints.
|
||||||
condition dC(x)/dt=0 describes a valid velocity. We have dC(x)/dt = Jv + b = 0 where J is
|
*
|
||||||
the Jacobian matrix of the constraint, v is a vector that contains the velocity of both
|
* v2' = v1 + dt * M^-1 * F_a
|
||||||
bodies and b is the constraint bias. We are looking for a force F_c that will act on the
|
*
|
||||||
bodies to keep the constraint satisfied. Note that from the virtual work principle, we have
|
* where M is a matrix that contains mass and inertia tensor information.
|
||||||
F_c = J^t * lambda where J^t is the transpose of the Jacobian matrix and lambda is a
|
*
|
||||||
Lagrange multiplier. Therefore, finding the force F_c is equivalent to finding the Lagrange
|
* --- Step 2 ---
|
||||||
multiplier lambda.
|
*
|
||||||
|
* During the second step, we iterate over all the constraints for a certain number of
|
||||||
An impulse P = F * dt where F is a force and dt is the timestep. We can apply impulses a
|
* iterations and for each constraint we compute the impulse to apply to the bodies needed
|
||||||
body to change its velocity. The idea of the Sequential Impulse technique is to apply
|
* so that the new velocity of the bodies satisfy Jv + b = 0. From the Newton law, we know that
|
||||||
impulses to bodies of each constraints in order to keep the constraint satisfied.
|
* M * deltaV = P_c where M is the mass of the body, deltaV is the difference of velocity and
|
||||||
|
* P_c is the constraint impulse to apply to the body. Therefore, we have
|
||||||
--- Step 1 ---
|
* v2 = v2' + M^-1 * P_c. For each constraint, we can compute the Lagrange multiplier lambda
|
||||||
|
* using : lambda = -m_c (Jv2' + b) where m_c = 1 / (J * M^-1 * J^t). Now that we have the
|
||||||
First, we integrate the applied force F_a acting of each rigid body (like gravity, ...) and
|
* Lagrange multiplier lambda, we can compute the impulse P_c = J^t * lambda * dt to apply to
|
||||||
we obtain some new velocities v2' that tends to violate the constraints.
|
* the bodies to satisfy the constraint.
|
||||||
|
*
|
||||||
v2' = v1 + dt * M^-1 * F_a
|
* --- Step 3 ---
|
||||||
|
*
|
||||||
where M is a matrix that contains mass and inertia tensor information.
|
* In the third step, we integrate the new position x2 of the bodies using the new velocities
|
||||||
|
* v2 computed in the second step with : x2 = x1 + dt * v2.
|
||||||
--- Step 2 ---
|
*
|
||||||
|
* Note that in the following code (as it is also explained in the slides from Erin Catto),
|
||||||
During the second step, we iterate over all the constraints for a certain number of
|
* the value lambda is not only the lagrange multiplier but is the multiplication of the
|
||||||
iterations and for each constraint we compute the impulse to apply to the bodies needed
|
* Lagrange multiplier with the timestep dt. Therefore, in the following code, when we use
|
||||||
so that the new velocity of the bodies satisfy Jv + b = 0. From the Newton law, we know that
|
* lambda, we mean (lambda * dt).
|
||||||
M * deltaV = P_c where M is the mass of the body, deltaV is the difference of velocity and
|
*
|
||||||
P_c is the constraint impulse to apply to the body. Therefore, we have
|
* We are using the accumulated impulse technique that is also described in the slides from
|
||||||
v2 = v2' + M^-1 * P_c. For each constraint, we can compute the Lagrange multiplier lambda
|
* Erin Catto.
|
||||||
using : lambda = -m_c (Jv2' + b) where m_c = 1 / (J * M^-1 * J^t). Now that we have the
|
*
|
||||||
Lagrange multiplier lambda, we can compute the impulse P_c = J^t * lambda * dt to apply to
|
* We are also using warm starting. The idea is to warm start the solver at the beginning of
|
||||||
the bodies to satisfy the constraint.
|
* each step by applying the last impulstes for the constraints that we already existing at the
|
||||||
|
* previous step. This allows the iterative solver to converge faster towards the solution.
|
||||||
--- Step 3 ---
|
*
|
||||||
|
* For contact constraints, we are also using split impulses so that the position correction
|
||||||
In the third step, we integrate the new position x2 of the bodies using the new velocities
|
* that uses Baumgarte stabilization does not change the momentum of the bodies.
|
||||||
v2 computed in the second step with : x2 = x1 + dt * v2.
|
*
|
||||||
|
* There are two ways to apply the friction constraints. Either the friction constraints are
|
||||||
Note that in the following code (as it is also explained in the slides from Erin Catto),
|
* applied at each contact point or they are applied only at the center of the contact manifold
|
||||||
the value lambda is not only the lagrange multiplier but is the multiplication of the
|
* between two bodies. If we solve the friction constraints at each contact point, we need
|
||||||
Lagrange multiplier with the timestep dt. Therefore, in the following code, when we use
|
* two constraints (two tangential friction directions) and if we solve the friction
|
||||||
lambda, we mean (lambda * dt).
|
* constraints at the center of the contact manifold, we need two constraints for tangential
|
||||||
|
* friction but also another twist friction constraint to prevent spin of the body around the
|
||||||
We are using the accumulated impulse technique that is also described in the slides from
|
* contact manifold center.
|
||||||
Erin Catto.
|
*/
|
||||||
|
|
||||||
We are also using warm starting. The idea is to warm start the solver at the beginning of
|
|
||||||
each step by applying the last impulstes for the constraints that we already existing at the
|
|
||||||
previous step. This allows the iterative solver to converge faster towards the solution.
|
|
||||||
|
|
||||||
For contact constraints, we are also using split impulses so that the position correction
|
|
||||||
that uses Baumgarte stabilization does not change the momentum of the bodies.
|
|
||||||
|
|
||||||
There are two ways to apply the friction constraints. Either the friction constraints are
|
|
||||||
applied at each contact point or they are applied only at the center of the contact manifold
|
|
||||||
between two bodies. If we solve the friction constraints at each contact point, we need
|
|
||||||
two constraints (two tangential friction directions) and if we solve the friction
|
|
||||||
constraints at the center of the contact manifold, we need two constraints for tangential
|
|
||||||
friction but also another twist friction constraint to prevent spin of the body around the
|
|
||||||
contact manifold center.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
class ContactSolver {
|
class ContactSolver {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Structure ContactPointSolver
|
// Structure ContactPointSolver
|
||||||
// Contact solver internal data structure that to store all the
|
/**
|
||||||
// information relative to a contact point
|
* Contact solver internal data structure that to store all the
|
||||||
|
* information relative to a contact point
|
||||||
|
*/
|
||||||
struct ContactPointSolver {
|
struct ContactPointSolver {
|
||||||
|
|
||||||
decimal penetrationImpulse; // Accumulated normal impulse
|
/// Accumulated normal impulse
|
||||||
decimal friction1Impulse; // Accumulated impulse in the 1st friction direction
|
decimal penetrationImpulse;
|
||||||
decimal friction2Impulse; // Accumulated impulse in the 2nd friction direction
|
|
||||||
decimal penetrationSplitImpulse; // Accumulated split impulse for penetration correction
|
/// Accumulated impulse in the 1st friction direction
|
||||||
Vector3 normal; // Normal vector of the contact
|
decimal friction1Impulse;
|
||||||
Vector3 frictionVector1; // First friction vector in the tangent plane
|
|
||||||
Vector3 frictionVector2; // Second friction vector in the tangent plane
|
/// Accumulated impulse in the 2nd friction direction
|
||||||
Vector3 oldFrictionVector1; // Old first friction vector in the tangent plane
|
decimal friction2Impulse;
|
||||||
Vector3 oldFrictionVector2; // Old second friction vector in the tangent plane
|
|
||||||
Vector3 r1; // Vector from the body 1 center to the contact point
|
/// Accumulated split impulse for penetration correction
|
||||||
Vector3 r2; // Vector from the body 2 center to the contact point
|
decimal penetrationSplitImpulse;
|
||||||
Vector3 r1CrossT1; // Cross product of r1 with 1st friction vector
|
|
||||||
Vector3 r1CrossT2; // Cross product of r1 with 2nd friction vector
|
/// Normal vector of the contact
|
||||||
Vector3 r2CrossT1; // Cross product of r2 with 1st friction vector
|
Vector3 normal;
|
||||||
Vector3 r2CrossT2; // Cross product of r2 with 2nd friction vector
|
|
||||||
Vector3 r1CrossN; // Cross product of r1 with the contact normal
|
/// First friction vector in the tangent plane
|
||||||
Vector3 r2CrossN; // Cross product of r2 with the contact normal
|
Vector3 frictionVector1;
|
||||||
decimal penetrationDepth; // Penetration depth
|
|
||||||
decimal restitutionBias; // Velocity restitution bias
|
/// Second friction vector in the tangent plane
|
||||||
decimal inversePenetrationMass; // Inverse of the matrix K for the penenetration
|
Vector3 frictionVector2;
|
||||||
decimal inverseFriction1Mass; // Inverse of the matrix K for the 1st friction
|
|
||||||
decimal inverseFriction2Mass; // Inverse of the matrix K for the 2nd friction
|
/// Old first friction vector in the tangent plane
|
||||||
bool isRestingContact; // True if the contact was existing last time step
|
Vector3 oldFrictionVector1;
|
||||||
ContactPoint* externalContact; // Pointer to the external contact
|
|
||||||
|
/// Old second friction vector in the tangent plane
|
||||||
|
Vector3 oldFrictionVector2;
|
||||||
|
|
||||||
|
/// Vector from the body 1 center to the contact point
|
||||||
|
Vector3 r1;
|
||||||
|
|
||||||
|
/// Vector from the body 2 center to the contact point
|
||||||
|
Vector3 r2;
|
||||||
|
|
||||||
|
/// Cross product of r1 with 1st friction vector
|
||||||
|
Vector3 r1CrossT1;
|
||||||
|
|
||||||
|
/// Cross product of r1 with 2nd friction vector
|
||||||
|
Vector3 r1CrossT2;
|
||||||
|
|
||||||
|
/// Cross product of r2 with 1st friction vector
|
||||||
|
Vector3 r2CrossT1;
|
||||||
|
|
||||||
|
/// Cross product of r2 with 2nd friction vector
|
||||||
|
Vector3 r2CrossT2;
|
||||||
|
|
||||||
|
/// Cross product of r1 with the contact normal
|
||||||
|
Vector3 r1CrossN;
|
||||||
|
|
||||||
|
/// Cross product of r2 with the contact normal
|
||||||
|
Vector3 r2CrossN;
|
||||||
|
|
||||||
|
/// Penetration depth
|
||||||
|
decimal penetrationDepth;
|
||||||
|
|
||||||
|
/// Velocity restitution bias
|
||||||
|
decimal restitutionBias;
|
||||||
|
|
||||||
|
/// Inverse of the matrix K for the penenetration
|
||||||
|
decimal inversePenetrationMass;
|
||||||
|
|
||||||
|
/// Inverse of the matrix K for the 1st friction
|
||||||
|
decimal inverseFriction1Mass;
|
||||||
|
|
||||||
|
/// Inverse of the matrix K for the 2nd friction
|
||||||
|
decimal inverseFriction2Mass;
|
||||||
|
|
||||||
|
/// True if the contact was existing last time step
|
||||||
|
bool isRestingContact;
|
||||||
|
|
||||||
|
/// Pointer to the external contact
|
||||||
|
ContactPoint* externalContact;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Structure ContactManifoldSolver
|
// Structure ContactManifoldSolver
|
||||||
// Contact solver internal data structure to store all the
|
/**
|
||||||
// information relative to a contact manifold
|
* Contact solver internal data structure to store all the
|
||||||
|
* information relative to a contact manifold.
|
||||||
|
*/
|
||||||
struct ContactManifoldSolver {
|
struct ContactManifoldSolver {
|
||||||
|
|
||||||
uint indexBody1; // Index of body 1 in the constraint solver
|
/// Index of body 1 in the constraint solver
|
||||||
uint indexBody2; // Index of body 2 in the constraint solver
|
uint indexBody1;
|
||||||
decimal massInverseBody1; // Inverse of the mass of body 1
|
|
||||||
decimal massInverseBody2; // Inverse of the mass of body 2
|
|
||||||
Matrix3x3 inverseInertiaTensorBody1; // Inverse inertia tensor of body 1
|
|
||||||
Matrix3x3 inverseInertiaTensorBody2; // Inverse inertia tensor of body 2
|
|
||||||
bool isBody1Moving; // True if the body 1 is allowed to move
|
|
||||||
bool isBody2Moving; // True if the body 2 is allowed to move
|
|
||||||
ContactPointSolver contacts[MAX_CONTACT_POINTS_IN_MANIFOLD];// Contact point constraints
|
|
||||||
uint nbContacts; // Number of contact points
|
|
||||||
decimal restitutionFactor; // Mix of the restitution factor for two bodies
|
|
||||||
decimal frictionCoefficient; // Mix friction coefficient for the two bodies
|
|
||||||
ContactManifold* externalContactManifold; // Pointer to the external contact manifold
|
|
||||||
|
|
||||||
// Variables used when friction constraints are apply at the center of the manifold //
|
/// Index of body 2 in the constraint solver
|
||||||
|
uint indexBody2;
|
||||||
|
|
||||||
Vector3 normal; // Average normal vector of the contact manifold
|
/// Inverse of the mass of body 1
|
||||||
Vector3 frictionPointBody1; // Point on body 1 where to apply the friction constraints
|
decimal massInverseBody1;
|
||||||
Vector3 frictionPointBody2; // Point on body 2 where to apply the friction constraints
|
|
||||||
Vector3 r1Friction; // R1 vector for the friction constraints
|
// Inverse of the mass of body 2
|
||||||
Vector3 r2Friction; // R2 vector for the friction constraints
|
decimal massInverseBody2;
|
||||||
Vector3 r1CrossT1; // Cross product of r1 with 1st friction vector
|
|
||||||
Vector3 r1CrossT2; // Cross product of r1 with 2nd friction vector
|
/// Inverse inertia tensor of body 1
|
||||||
Vector3 r2CrossT1; // Cross product of r2 with 1st friction vector
|
Matrix3x3 inverseInertiaTensorBody1;
|
||||||
Vector3 r2CrossT2; // Cross product of r2 with 2nd friction vector
|
|
||||||
decimal inverseFriction1Mass; // Matrix K for the first friction constraint
|
/// Inverse inertia tensor of body 2
|
||||||
decimal inverseFriction2Mass; // Matrix K for the second friction constraint
|
Matrix3x3 inverseInertiaTensorBody2;
|
||||||
decimal inverseTwistFrictionMass; // Matrix K for the twist friction constraint
|
|
||||||
Vector3 frictionVector1; // First friction direction at contact manifold center
|
/// True if the body 1 is allowed to move
|
||||||
Vector3 frictionVector2; // Second friction direction at contact manifold center
|
bool isBody1Moving;
|
||||||
Vector3 oldFrictionVector1; // Old 1st friction direction at contact manifold center
|
|
||||||
Vector3 oldFrictionVector2; // Old 2nd friction direction at contact manifold center
|
/// True if the body 2 is allowed to move
|
||||||
decimal friction1Impulse; // First friction direction impulse at manifold center
|
bool isBody2Moving;
|
||||||
decimal friction2Impulse; // Second friction direction impulse at manifold center
|
|
||||||
decimal frictionTwistImpulse; // Twist friction impulse at contact manifold center
|
/// Contact point constraints
|
||||||
|
ContactPointSolver contacts[MAX_CONTACT_POINTS_IN_MANIFOLD];
|
||||||
|
|
||||||
|
/// Number of contact points
|
||||||
|
uint nbContacts;
|
||||||
|
|
||||||
|
/// Mix of the restitution factor for two bodies
|
||||||
|
decimal restitutionFactor;
|
||||||
|
|
||||||
|
/// Mix friction coefficient for the two bodies
|
||||||
|
decimal frictionCoefficient;
|
||||||
|
|
||||||
|
/// Pointer to the external contact manifold
|
||||||
|
ContactManifold* externalContactManifold;
|
||||||
|
|
||||||
|
// - Variables used when friction constraints are apply at the center of the manifold-//
|
||||||
|
|
||||||
|
/// Average normal vector of the contact manifold
|
||||||
|
Vector3 normal;
|
||||||
|
|
||||||
|
/// Point on body 1 where to apply the friction constraints
|
||||||
|
Vector3 frictionPointBody1;
|
||||||
|
|
||||||
|
/// Point on body 2 where to apply the friction constraints
|
||||||
|
Vector3 frictionPointBody2;
|
||||||
|
|
||||||
|
/// R1 vector for the friction constraints
|
||||||
|
Vector3 r1Friction;
|
||||||
|
|
||||||
|
/// R2 vector for the friction constraints
|
||||||
|
Vector3 r2Friction;
|
||||||
|
|
||||||
|
/// Cross product of r1 with 1st friction vector
|
||||||
|
Vector3 r1CrossT1;
|
||||||
|
|
||||||
|
/// Cross product of r1 with 2nd friction vector
|
||||||
|
Vector3 r1CrossT2;
|
||||||
|
|
||||||
|
/// Cross product of r2 with 1st friction vector
|
||||||
|
Vector3 r2CrossT1;
|
||||||
|
|
||||||
|
/// Cross product of r2 with 2nd friction vector
|
||||||
|
Vector3 r2CrossT2;
|
||||||
|
|
||||||
|
/// Matrix K for the first friction constraint
|
||||||
|
decimal inverseFriction1Mass;
|
||||||
|
|
||||||
|
/// Matrix K for the second friction constraint
|
||||||
|
decimal inverseFriction2Mass;
|
||||||
|
|
||||||
|
/// Matrix K for the twist friction constraint
|
||||||
|
decimal inverseTwistFrictionMass;
|
||||||
|
|
||||||
|
/// First friction direction at contact manifold center
|
||||||
|
Vector3 frictionVector1;
|
||||||
|
|
||||||
|
/// Second friction direction at contact manifold center
|
||||||
|
Vector3 frictionVector2;
|
||||||
|
|
||||||
|
/// Old 1st friction direction at contact manifold center
|
||||||
|
Vector3 oldFrictionVector1;
|
||||||
|
|
||||||
|
/// Old 2nd friction direction at contact manifold center
|
||||||
|
Vector3 oldFrictionVector2;
|
||||||
|
|
||||||
|
/// First friction direction impulse at manifold center
|
||||||
|
decimal friction1Impulse;
|
||||||
|
|
||||||
|
/// Second friction direction impulse at manifold center
|
||||||
|
decimal friction2Impulse;
|
||||||
|
|
||||||
|
/// Twist friction impulse at contact manifold center
|
||||||
|
decimal frictionTwistImpulse;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- Constants --------------------- //
|
// -------------------- Constants --------------------- //
|
||||||
|
|
||||||
// Beta value for the penetration depth position correction without split impulses
|
/// Beta value for the penetration depth position correction without split impulses
|
||||||
static const decimal BETA;
|
static const decimal BETA;
|
||||||
|
|
||||||
// Beta value for the penetration depth position correction with split impulses
|
/// Beta value for the penetration depth position correction with split impulses
|
||||||
static const decimal BETA_SPLIT_IMPULSE;
|
static const decimal BETA_SPLIT_IMPULSE;
|
||||||
|
|
||||||
// Slop distance (allowed penetration distance between bodies)
|
/// Slop distance (allowed penetration distance between bodies)
|
||||||
static const decimal SLOP;
|
static const decimal SLOP;
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Reference to the world
|
/// Reference to the world
|
||||||
DynamicsWorld& mWorld;
|
DynamicsWorld& mWorld;
|
||||||
|
|
||||||
// Number of iterations of the constraints solver
|
/// Number of iterations of the constraints solver
|
||||||
uint mNbIterations;
|
uint mNbIterations;
|
||||||
|
|
||||||
// Split linear velocities for the position contact solver (split impulse)
|
/// Split linear velocities for the position contact solver (split impulse)
|
||||||
Vector3* mSplitLinearVelocities;
|
Vector3* mSplitLinearVelocities;
|
||||||
|
|
||||||
// Split angular velocities for the position contact solver (split impulse)
|
/// Split angular velocities for the position contact solver (split impulse)
|
||||||
Vector3* mSplitAngularVelocities;
|
Vector3* mSplitAngularVelocities;
|
||||||
|
|
||||||
// Current time step
|
/// Current time step
|
||||||
decimal mTimeStep;
|
decimal mTimeStep;
|
||||||
|
|
||||||
// Contact constraints
|
/// Contact constraints
|
||||||
ContactManifoldSolver* mContactConstraints;
|
ContactManifoldSolver* mContactConstraints;
|
||||||
|
|
||||||
// Number of contact constraints
|
/// Number of contact constraints
|
||||||
uint mNbContactManifolds;
|
uint mNbContactManifolds;
|
||||||
|
|
||||||
// Constrained bodies
|
/// Constrained bodies
|
||||||
std::set<RigidBody*> mConstraintBodies;
|
std::set<RigidBody*> mConstraintBodies;
|
||||||
|
|
||||||
// Pointer to the array of constrained linear velocities (state of the linear velocities
|
/// Pointer to the array of constrained linear velocities (state of the linear velocities
|
||||||
// after solving the constraints)
|
/// after solving the constraints)
|
||||||
std::vector<Vector3>& mConstrainedLinearVelocities;
|
std::vector<Vector3>& mConstrainedLinearVelocities;
|
||||||
|
|
||||||
// Pointer to the array of constrained angular velocities (state of the angular velocities
|
/// Pointer to the array of constrained angular velocities (state of the angular velocities
|
||||||
// after solving the constraints)
|
/// after solving the constraints)
|
||||||
std::vector<Vector3>& mConstrainedAngularVelocities;
|
std::vector<Vector3>& mConstrainedAngularVelocities;
|
||||||
|
|
||||||
// Reference to the map of rigid body to their index in the constrained velocities array
|
/// Reference to the map of rigid body to their index in the constrained velocities array
|
||||||
const std::map<RigidBody*, uint>& mMapBodyToConstrainedVelocityIndex;
|
const std::map<RigidBody*, uint>& mMapBodyToConstrainedVelocityIndex;
|
||||||
|
|
||||||
// True if the warm starting of the solver is active
|
/// True if the warm starting of the solver is active
|
||||||
bool mIsWarmStartingActive;
|
bool mIsWarmStartingActive;
|
||||||
|
|
||||||
// True if the split impulse position correction is active
|
/// True if the split impulse position correction is active
|
||||||
bool mIsSplitImpulseActive;
|
bool mIsSplitImpulseActive;
|
||||||
|
|
||||||
// True if we solve 3 friction constraints at the contact manifold center only
|
/// True if we solve 3 friction constraints at the contact manifold center only
|
||||||
// instead of 2 friction constraints at each contact point
|
/// instead of 2 friction constraints at each contact point
|
||||||
bool mIsSolveFrictionAtContactManifoldCenterActive;
|
bool mIsSolveFrictionAtContactManifoldCenterActive;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Initialize the constraint solver
|
/// Initialize the constraint solver
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
// Initialize the split impulse velocities
|
/// Initialize the split impulse velocities
|
||||||
void initializeSplitImpulseVelocities();
|
void initializeSplitImpulseVelocities();
|
||||||
|
|
||||||
// Initialize the contact constraints before solving the system
|
/// Initialize the contact constraints before solving the system
|
||||||
void initializeContactConstraints();
|
void initializeContactConstraints();
|
||||||
|
|
||||||
// Store the computed impulses to use them to
|
/// Store the computed impulses to use them to
|
||||||
// warm start the solver at the next iteration
|
/// warm start the solver at the next iteration
|
||||||
void storeImpulses();
|
void storeImpulses();
|
||||||
|
|
||||||
// Warm start the solver
|
/// Warm start the solver.
|
||||||
void warmStart();
|
void warmStart();
|
||||||
|
|
||||||
// Solve the contact constraints by applying sequential impulses
|
/// Solve the contact constraints by applying sequential impulses
|
||||||
void solveContactConstraints();
|
void solveContactConstraints();
|
||||||
|
|
||||||
// Apply an impulse to the two bodies of a constraint
|
/// Apply an impulse to the two bodies of a constraint
|
||||||
void applyImpulse(const Impulse& impulse, const ContactManifoldSolver& manifold);
|
void applyImpulse(const Impulse& impulse, const ContactManifoldSolver& manifold);
|
||||||
|
|
||||||
// Apply an impulse to the two bodies of a constraint
|
/// Apply an impulse to the two bodies of a constraint
|
||||||
void applySplitImpulse(const Impulse& impulse,
|
void applySplitImpulse(const Impulse& impulse,
|
||||||
const ContactManifoldSolver& manifold);
|
const ContactManifoldSolver& manifold);
|
||||||
|
|
||||||
// Compute the collision restitution factor from the restitution factor of each body
|
/// Compute the collision restitution factor from the restitution factor of each body
|
||||||
decimal computeMixedRestitutionFactor(const RigidBody* body1,
|
decimal computeMixedRestitutionFactor(const RigidBody* body1,
|
||||||
const RigidBody* body2) const;
|
const RigidBody* body2) const;
|
||||||
|
|
||||||
// Compute the mixed friction coefficient from the friction coefficient of each body
|
/// Compute the mixed friction coefficient from the friction coefficient of each body
|
||||||
decimal computeMixedFrictionCoefficient(const RigidBody* body1,
|
decimal computeMixedFrictionCoefficient(const RigidBody* body1,
|
||||||
const RigidBody* body2)const;
|
const RigidBody* body2)const;
|
||||||
|
|
||||||
// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
/// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
||||||
// plane for a contact point constraint. The two vectors have to be
|
/// plane for a contact point. The two vectors have to be
|
||||||
// such that : t1 x t2 = contactNormal.
|
/// such that : t1 x t2 = contactNormal.
|
||||||
void computeFrictionVectors(const Vector3& deltaVelocity,
|
void computeFrictionVectors(const Vector3& deltaVelocity,
|
||||||
ContactPointSolver &contactPoint) const;
|
ContactPointSolver &contactPoint) const;
|
||||||
|
|
||||||
// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
/// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
||||||
// plane for a contact constraint. The two vectors have to be
|
/// plane for a contact manifold. The two vectors have to be
|
||||||
// such that : t1 x t2 = contactNormal.
|
/// such that : t1 x t2 = contactNormal.
|
||||||
void computeFrictionVectors(const Vector3& deltaVelocity,
|
void computeFrictionVectors(const Vector3& deltaVelocity,
|
||||||
ContactManifoldSolver& contactPoint) const;
|
ContactManifoldSolver& contactPoint) const;
|
||||||
|
|
||||||
// Compute a penetration constraint impulse
|
/// Compute a penetration constraint impulse
|
||||||
const Impulse computePenetrationImpulse(decimal deltaLambda,
|
const Impulse computePenetrationImpulse(decimal deltaLambda,
|
||||||
const ContactPointSolver& contactPoint) const;
|
const ContactPointSolver& contactPoint) const;
|
||||||
|
|
||||||
// Compute the first friction constraint impulse
|
/// Compute the first friction constraint impulse
|
||||||
const Impulse computeFriction1Impulse(decimal deltaLambda,
|
const Impulse computeFriction1Impulse(decimal deltaLambda,
|
||||||
const ContactPointSolver& contactPoint) const;
|
const ContactPointSolver& contactPoint) const;
|
||||||
|
|
||||||
// Compute the second friction constraint impulse
|
/// Compute the second friction constraint impulse
|
||||||
const Impulse computeFriction2Impulse(decimal deltaLambda,
|
const Impulse computeFriction2Impulse(decimal deltaLambda,
|
||||||
const ContactPointSolver& contactPoint) const;
|
const ContactPointSolver& contactPoint) const;
|
||||||
|
|
||||||
|
@ -330,43 +451,43 @@ class ContactSolver {
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
ContactSolver(DynamicsWorld& mWorld, std::vector<Vector3>& constrainedLinearVelocities,
|
ContactSolver(DynamicsWorld& mWorld, std::vector<Vector3>& constrainedLinearVelocities,
|
||||||
std::vector<Vector3>& constrainedAngularVelocities,
|
std::vector<Vector3>& constrainedAngularVelocities,
|
||||||
const std::map<RigidBody*, uint>& mapBodyToVelocityIndex);
|
const std::map<RigidBody*, uint>& mapBodyToVelocityIndex);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~ContactSolver();
|
virtual ~ContactSolver();
|
||||||
|
|
||||||
// Solve the constraints
|
/// Solve the constraints
|
||||||
void solve(decimal timeStep);
|
void solve(decimal timeStep);
|
||||||
|
|
||||||
// Return true if the body is in at least one constraint
|
/// Return true if the body is in at least one constraint
|
||||||
bool isConstrainedBody(RigidBody* body) const;
|
bool isConstrainedBody(RigidBody* body) const;
|
||||||
|
|
||||||
// Return the constrained linear velocity of a body after solving the constraints
|
/// Return the constrained linear velocity of a body after solving the constraints
|
||||||
Vector3 getConstrainedLinearVelocityOfBody(RigidBody *body);
|
Vector3 getConstrainedLinearVelocityOfBody(RigidBody *body);
|
||||||
|
|
||||||
// Return the split linear velocity
|
/// Return the split linear velocity
|
||||||
Vector3 getSplitLinearVelocityOfBody(RigidBody* body);
|
Vector3 getSplitLinearVelocityOfBody(RigidBody* body);
|
||||||
|
|
||||||
// Return the constrained angular velocity of a body after solving the constraints
|
/// Return the constrained angular velocity of a body after solving the constraints
|
||||||
Vector3 getConstrainedAngularVelocityOfBody(RigidBody* body);
|
Vector3 getConstrainedAngularVelocityOfBody(RigidBody* body);
|
||||||
|
|
||||||
// Return the split angular velocity
|
/// Return the split angular velocity
|
||||||
Vector3 getSplitAngularVelocityOfBody(RigidBody* body);
|
Vector3 getSplitAngularVelocityOfBody(RigidBody* body);
|
||||||
|
|
||||||
// Clean up the constraint solver
|
/// Clean up the constraint solver
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
// Set the number of iterations of the constraint solver
|
/// Set the number of iterations of the constraint solver
|
||||||
void setNbIterationsSolver(uint nbIterations);
|
void setNbIterationsSolver(uint nbIterations);
|
||||||
|
|
||||||
// Activate or Deactivate the split impulses for contacts
|
/// Activate or Deactivate the split impulses for contacts
|
||||||
void setIsSplitImpulseActive(bool isActive);
|
void setIsSplitImpulseActive(bool isActive);
|
||||||
|
|
||||||
// Activate or deactivate the solving of friction constraints at the center of
|
/// Activate or deactivate the solving of friction constraints at the center of
|
||||||
// the contact manifold instead of solving them at each contact point
|
/// the contact manifold instead of solving them at each contact point
|
||||||
void setIsSolveFrictionAtContactManifoldCenterActive(bool isActive);
|
void setIsSolveFrictionAtContactManifoldCenterActive(bool isActive);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,188 +34,187 @@
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "../configuration.h"
|
#include "../configuration.h"
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
/// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class DynamicsWorld
|
||||||
Class DynamicsWorld :
|
/**
|
||||||
This class represents a dynamics world. This class inherits from
|
* This class represents a dynamics world. This class inherits from
|
||||||
the CollisionWorld class. In a dynamics world, bodies can collide
|
* the CollisionWorld class. In a dynamics world, bodies can collide
|
||||||
and their movements are simulated using the laws of physics.
|
* and their movements are simulated using the laws of physics.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class DynamicsWorld : public CollisionWorld {
|
class DynamicsWorld : public CollisionWorld {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Timer of the physics engine
|
/// Timer of the physics engine
|
||||||
Timer mTimer;
|
Timer mTimer;
|
||||||
|
|
||||||
// Contact solver
|
/// Contact solver
|
||||||
ContactSolver mContactSolver;
|
ContactSolver mContactSolver;
|
||||||
|
|
||||||
// True if the deactivation (sleeping) of inactive bodies is enabled
|
/// True if the deactivation (sleeping) of inactive bodies is enabled
|
||||||
bool mIsDeactivationActive;
|
bool mIsDeactivationActive;
|
||||||
|
|
||||||
// All the rigid bodies of the physics world
|
/// All the rigid bodies of the physics world
|
||||||
std::set<RigidBody*> mRigidBodies;
|
std::set<RigidBody*> mRigidBodies;
|
||||||
|
|
||||||
// All the contact constraints
|
/// All the contact constraints
|
||||||
std::vector<ContactManifold*> mContactManifolds;
|
std::vector<ContactManifold*> mContactManifolds;
|
||||||
|
|
||||||
// All the constraints (except contact constraints)
|
/// All the constraints (except contact constraints)
|
||||||
std::vector<Constraint*> mConstraints;
|
std::vector<Constraint*> mConstraints;
|
||||||
|
|
||||||
// Gravity vector of the world
|
/// Gravity vector of the world
|
||||||
Vector3 mGravity;
|
Vector3 mGravity;
|
||||||
|
|
||||||
// True if the gravity force is on
|
/// True if the gravity force is on
|
||||||
bool mIsGravityOn;
|
bool mIsGravityOn;
|
||||||
|
|
||||||
// Memory pool for the overlapping pairs
|
/// Memory pool for the overlapping pairs
|
||||||
MemoryPool<OverlappingPair> mMemoryPoolOverlappingPairs;
|
MemoryPool<OverlappingPair> mMemoryPoolOverlappingPairs;
|
||||||
|
|
||||||
// Memory pool for rigid bodies memory allocation
|
/// Memory pool for rigid bodies memory allocation
|
||||||
MemoryPool<RigidBody> mMemoryPoolRigidBodies;
|
MemoryPool<RigidBody> mMemoryPoolRigidBodies;
|
||||||
|
|
||||||
// Memory pool for the contacts
|
/// Memory pool for the contacts
|
||||||
MemoryPool<ContactPoint> mMemoryPoolContacts;
|
MemoryPool<ContactPoint> mMemoryPoolContacts;
|
||||||
|
|
||||||
// Array of constrained linear velocities (state of the linear velocities
|
/// Array of constrained linear velocities (state of the linear velocities
|
||||||
// after solving the constraints)
|
/// after solving the constraints)
|
||||||
std::vector<Vector3> mConstrainedLinearVelocities;
|
std::vector<Vector3> mConstrainedLinearVelocities;
|
||||||
|
|
||||||
// Array of constrained angular velocities (state of the angular velocities
|
/// Array of constrained angular velocities (state of the angular velocities
|
||||||
// after solving the constraints)
|
/// after solving the constraints)
|
||||||
std::vector<Vector3> mConstrainedAngularVelocities;
|
std::vector<Vector3> mConstrainedAngularVelocities;
|
||||||
|
|
||||||
// Map body to their index in the constrained velocities array
|
/// Map body to their index in the constrained velocities array
|
||||||
std::map<RigidBody*, uint> mMapBodyToConstrainedVelocityIndex;
|
std::map<RigidBody*, uint> mMapBodyToConstrainedVelocityIndex;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
DynamicsWorld(const DynamicsWorld& world);
|
DynamicsWorld(const DynamicsWorld& world);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
DynamicsWorld& operator=(const DynamicsWorld& world);
|
DynamicsWorld& operator=(const DynamicsWorld& world);
|
||||||
|
|
||||||
// Compute the motion of all bodies and update their positions and orientations
|
/// Compute the motion of all bodies and update their positions and orientations
|
||||||
void updateRigidBodiesPositionAndOrientation();
|
void updateRigidBodiesPositionAndOrientation();
|
||||||
|
|
||||||
// Update the position and orientation of a body
|
/// Update the position and orientation of a body
|
||||||
void updatePositionAndOrientationOfBody(RigidBody* body, Vector3 newLinVelocity,
|
void updatePositionAndOrientationOfBody(RigidBody* body, Vector3 newLinVelocity,
|
||||||
Vector3 newAngVelocity);
|
Vector3 newAngVelocity);
|
||||||
|
|
||||||
// Compute and set the interpolation factor to all bodies
|
/// Compute and set the interpolation factor to all bodies
|
||||||
void setInterpolationFactorToAllBodies();
|
void setInterpolationFactorToAllBodies();
|
||||||
|
|
||||||
// Initialize the constrained velocities array at each step
|
/// Initialize the constrained velocities array at each step
|
||||||
void initConstrainedVelocitiesArray();
|
void initConstrainedVelocitiesArray();
|
||||||
|
|
||||||
// Cleanup the constrained velocities array at each step
|
/// Cleanup the constrained velocities array at each step
|
||||||
void cleanupConstrainedVelocitiesArray();
|
void cleanupConstrainedVelocitiesArray();
|
||||||
|
|
||||||
// Apply the gravity force to all bodies
|
/// Apply the gravity force to all bodies
|
||||||
void applyGravity();
|
void applyGravity();
|
||||||
|
|
||||||
// Reset the boolean movement variable of each body
|
/// Reset the boolean movement variable of each body
|
||||||
void resetBodiesMovementVariable();
|
void resetBodiesMovementVariable();
|
||||||
|
|
||||||
// Update the overlapping pair
|
/// Update the overlapping pair
|
||||||
virtual void updateOverlappingPair(const BroadPhasePair* pair);
|
virtual void updateOverlappingPair(const BroadPhasePair* pair);
|
||||||
|
|
||||||
// Notify the world about a new broad-phase overlapping pair
|
/// Notify the world about a new broad-phase overlapping pair
|
||||||
virtual void notifyAddedOverlappingPair(const BroadPhasePair* addedPair);
|
virtual void notifyAddedOverlappingPair(const BroadPhasePair* addedPair);
|
||||||
|
|
||||||
// Notify the world about a removed broad-phase overlapping pair
|
/// Notify the world about a removed broad-phase overlapping pair
|
||||||
virtual void notifyRemovedOverlappingPair(const BroadPhasePair* removedPair);
|
virtual void notifyRemovedOverlappingPair(const BroadPhasePair* removedPair);
|
||||||
|
|
||||||
// Notify the world about a new narrow-phase contact
|
/// Notify the world about a new narrow-phase contact
|
||||||
virtual void notifyNewContact(const BroadPhasePair* pair, const ContactInfo* contactInfo);
|
virtual void notifyNewContact(const BroadPhasePair* pair, const ContactInfo* contactInfo);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
DynamicsWorld(const Vector3& mGravity, decimal timeStep);
|
DynamicsWorld(const Vector3& mGravity, decimal timeStep);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~DynamicsWorld();
|
virtual ~DynamicsWorld();
|
||||||
|
|
||||||
// Start the physics simulation
|
/// Start the physics simulation
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
// Stop the physics simulation
|
/// Stop the physics simulation
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
// Update the physics simulation
|
/// Update the physics simulation
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
// Set the number of iterations of the constraint solver
|
/// Set the number of iterations of the constraint solver
|
||||||
void setNbIterationsSolver(uint nbIterations);
|
void setNbIterationsSolver(uint nbIterations);
|
||||||
|
|
||||||
// Activate or Deactivate the split impulses for contacts
|
/// Activate or Deactivate the split impulses for contacts
|
||||||
void setIsSplitImpulseActive(bool isActive);
|
void setIsSplitImpulseActive(bool isActive);
|
||||||
|
|
||||||
// Activate or deactivate the solving of friction constraints at the center of
|
/// Activate or deactivate the solving of friction constraints at the center of
|
||||||
// the contact manifold instead of solving them at each contact point
|
/// the contact manifold instead of solving them at each contact point
|
||||||
void setIsSolveFrictionAtContactManifoldCenterActive(bool isActive);
|
void setIsSolveFrictionAtContactManifoldCenterActive(bool isActive);
|
||||||
|
|
||||||
// Set the isErrorCorrectionActive value
|
/// Set the isErrorCorrectionActive value
|
||||||
void setIsErrorCorrectionActive(bool isErrorCorrectionActive);
|
void setIsErrorCorrectionActive(bool isErrorCorrectionActive);
|
||||||
|
|
||||||
// Create a rigid body into the physics world
|
/// Create a rigid body into the physics world
|
||||||
RigidBody* createRigidBody(const Transform& transform, decimal mass,
|
RigidBody* createRigidBody(const Transform& transform, decimal mass,
|
||||||
const Matrix3x3& inertiaTensorLocal,
|
const Matrix3x3& inertiaTensorLocal,
|
||||||
CollisionShape* collisionShape);
|
CollisionShape* collisionShape);
|
||||||
|
|
||||||
// Destroy a rigid body
|
/// Destroy a rigid body
|
||||||
void destroyRigidBody(RigidBody* rigidBody);
|
void destroyRigidBody(RigidBody* rigidBody);
|
||||||
|
|
||||||
// Return the gravity vector of the world
|
/// Return the gravity vector of the world
|
||||||
Vector3 getGravity() const;
|
Vector3 getGravity() const;
|
||||||
|
|
||||||
// Return if the gravity is on
|
/// Return if the gravity is on
|
||||||
bool getIsGravityOn() const;
|
bool getIsGravityOn() const;
|
||||||
|
|
||||||
// Set the isGravityOn attribute
|
/// Set the isGravityOn attribute
|
||||||
void setIsGratityOn(bool isGravityOn);
|
void setIsGratityOn(bool isGravityOn);
|
||||||
|
|
||||||
// Return the number of rigid bodies in the world
|
/// Return the number of rigid bodies in the world
|
||||||
uint getNbRigidBodies() const;
|
uint getNbRigidBodies() const;
|
||||||
|
|
||||||
// Add a constraint
|
/// Add a constraint
|
||||||
void addConstraint(Constraint* constraint);
|
void addConstraint(Constraint* constraint);
|
||||||
|
|
||||||
// Remove a constraint
|
/// Remove a constraint
|
||||||
void removeConstraint(Constraint* constraint);
|
void removeConstraint(Constraint* constraint);
|
||||||
|
|
||||||
// Remove all constraints and delete them (free their memory)
|
/// Remove all constraints and delete them (free their memory)
|
||||||
void removeAllConstraints();
|
void removeAllConstraints();
|
||||||
|
|
||||||
// Return the number of contact constraints in the world
|
/// Return the number of contact constraints in the world
|
||||||
uint getNbContactManifolds() const;
|
uint getNbContactManifolds() const;
|
||||||
|
|
||||||
// Return a start iterator on the constraint list
|
/// Return a start iterator on the constraint list
|
||||||
std::vector<Constraint*>::iterator getConstraintsBeginIterator();
|
std::vector<Constraint*>::iterator getConstraintsBeginIterator();
|
||||||
|
|
||||||
// Return a end iterator on the constraint list
|
/// Return a end iterator on the constraint list
|
||||||
std::vector<Constraint*>::iterator getConstraintsEndIterator();
|
std::vector<Constraint*>::iterator getConstraintsEndIterator();
|
||||||
|
|
||||||
// Return a start iterator on the contact manifolds list
|
/// Return a start iterator on the contact manifolds list
|
||||||
std::vector<ContactManifold*>::iterator getContactManifoldsBeginIterator();
|
std::vector<ContactManifold*>::iterator getContactManifoldsBeginIterator();
|
||||||
|
|
||||||
// Return a end iterator on the contact manifolds list
|
/// Return a end iterator on the contact manifolds list
|
||||||
std::vector<ContactManifold*>::iterator getContactManifoldsEndIterator();
|
std::vector<ContactManifold*>::iterator getContactManifoldsEndIterator();
|
||||||
|
|
||||||
// Return an iterator to the beginning of the rigid bodies of the physics world
|
/// Return an iterator to the beginning of the rigid bodies of the physics world
|
||||||
std::set<RigidBody*>::iterator getRigidBodiesBeginIterator();
|
std::set<RigidBody*>::iterator getRigidBodiesBeginIterator();
|
||||||
|
|
||||||
// Return an iterator to the end of the rigid bodies of the physics world
|
/// Return an iterator to the end of the rigid bodies of the physics world
|
||||||
std::set<RigidBody*>::iterator getRigidBodiesEndIterator();
|
std::set<RigidBody*>::iterator getRigidBodiesEndIterator();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,77 +29,76 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "ContactManifold.h"
|
#include "ContactManifold.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class OverlappingPair
|
||||||
Class OverlappingPair :
|
/**
|
||||||
This class represents a pair of two bodies that are overlapping
|
* This class represents a pair of two bodies that are overlapping
|
||||||
during the broad-phase collision detection. It is created when
|
* during the broad-phase collision detection. It is created when
|
||||||
the two bodies start to overlap and is destroy when they do not
|
* the two bodies start to overlap and is destroyed when they do not
|
||||||
overlap anymore. This class contains the cache with all the
|
* overlap anymore. This class contains a contact manifold that
|
||||||
current contacts between the bodies.
|
* store all the contact points between the two bodies.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class OverlappingPair {
|
class OverlappingPair {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Pointer to the first body of the contact
|
/// Pointer to the first body of the contact
|
||||||
CollisionBody* const mBody1;
|
CollisionBody* const mBody1;
|
||||||
|
|
||||||
// Pointer to the second body of the contact
|
/// Pointer to the second body of the contact
|
||||||
CollisionBody* const mBody2;
|
CollisionBody* const mBody2;
|
||||||
|
|
||||||
// Persistent contact manifold
|
/// Persistent contact manifold
|
||||||
ContactManifold mContactManifold;
|
ContactManifold mContactManifold;
|
||||||
|
|
||||||
// Cached previous separating axis
|
/// Cached previous separating axis
|
||||||
Vector3 mCachedSeparatingAxis;
|
Vector3 mCachedSeparatingAxis;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
OverlappingPair(const OverlappingPair& pair);
|
OverlappingPair(const OverlappingPair& pair);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
OverlappingPair& operator=(const OverlappingPair& pair);
|
OverlappingPair& operator=(const OverlappingPair& pair);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
OverlappingPair(CollisionBody* body1, CollisionBody* body2,
|
OverlappingPair(CollisionBody* body1, CollisionBody* body2,
|
||||||
MemoryPool<ContactPoint>& memoryPoolContacts);
|
MemoryPool<ContactPoint>& memoryPoolContacts);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~OverlappingPair();
|
~OverlappingPair();
|
||||||
|
|
||||||
// Return the pointer to first body
|
/// Return the pointer to first body
|
||||||
CollisionBody* const getBody1() const;
|
CollisionBody* const getBody1() const;
|
||||||
|
|
||||||
// Return the pointer to second body
|
/// Return the pointer to second body
|
||||||
CollisionBody* const getBody2() const;
|
CollisionBody* const getBody2() const;
|
||||||
|
|
||||||
// Add a contact to the contact cache
|
/// Add a contact to the contact cache
|
||||||
void addContact(ContactPoint* contact);
|
void addContact(ContactPoint* contact);
|
||||||
|
|
||||||
// Update the contact cache
|
/// Update the contact cache
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
// Return the cached separating axis
|
/// Return the cached separating axis
|
||||||
Vector3 getCachedSeparatingAxis() const;
|
Vector3 getCachedSeparatingAxis() const;
|
||||||
|
|
||||||
// Set the cached separating axis
|
/// Set the cached separating axis
|
||||||
void setCachedSeparatingAxis(const Vector3& axis);
|
void setCachedSeparatingAxis(const Vector3& axis);
|
||||||
|
|
||||||
// Return the number of contacts in the cache
|
/// Return the number of contacts in the cache
|
||||||
uint getNbContactPoints() const;
|
uint getNbContactPoints() const;
|
||||||
|
|
||||||
// Return the contact manifold
|
/// Return the contact manifold
|
||||||
ContactManifold* getContactManifold();
|
ContactManifold* getContactManifold();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,86 +40,85 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
/// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class Timer
|
||||||
Class Timer :
|
/**
|
||||||
This class will take care of the time in the physics engine. It
|
* This class will take care of the time in the physics engine. It
|
||||||
uses fuunctions that depend on the current platform to get the
|
* uses fuunctions that depend on the current platform to get the
|
||||||
current time.
|
* current time.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class Timer {
|
class Timer {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Timestep dt of the physics engine (timestep > 0.0)
|
/// Timestep dt of the physics engine (timestep > 0.0)
|
||||||
double mTimeStep;
|
double mTimeStep;
|
||||||
|
|
||||||
// Current time of the physics engine
|
/// Current time of the physics engine
|
||||||
long double mTime;
|
long double mTime;
|
||||||
|
|
||||||
// Last time the timer has been updated
|
/// Last time the timer has been updated
|
||||||
long double mLastUpdateTime;
|
long double mLastUpdateTime;
|
||||||
|
|
||||||
// Time difference between the two last timer update() calls
|
/// Time difference between the two last timer update() calls
|
||||||
long double mDeltaTime;
|
long double mDeltaTime;
|
||||||
|
|
||||||
// Used to fix the time step and avoid strange time effects
|
/// Used to fix the time step and avoid strange time effects
|
||||||
double mAccumulator;
|
double mAccumulator;
|
||||||
|
|
||||||
// True if the timer is running
|
/// True if the timer is running
|
||||||
bool mIsRunning;
|
bool mIsRunning;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
Timer(const Timer& timer);
|
Timer(const Timer& timer);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
Timer& operator=(const Timer& timer);
|
Timer& operator=(const Timer& timer);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Timer(double timeStep);
|
Timer(double timeStep);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~Timer();
|
virtual ~Timer();
|
||||||
|
|
||||||
// Return the timestep of the physics engine
|
/// Return the timestep of the physics engine
|
||||||
double getTimeStep() const;
|
double getTimeStep() const;
|
||||||
|
|
||||||
// Set the timestep of the physics engine
|
/// Set the timestep of the physics engine
|
||||||
void setTimeStep(double timeStep);
|
void setTimeStep(double timeStep);
|
||||||
|
|
||||||
// Return the current time
|
/// Return the current time
|
||||||
long double getTime() const;
|
long double getTime() const;
|
||||||
|
|
||||||
// Start the timer
|
/// Start the timer
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
// Stop the timer
|
/// Stop the timer
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
// Return true if the timer is running
|
/// Return true if the timer is running
|
||||||
bool getIsRunning() const;
|
bool getIsRunning() const;
|
||||||
|
|
||||||
// True if it's possible to take a new step
|
/// True if it's possible to take a new step
|
||||||
bool isPossibleToTakeStep() const;
|
bool isPossibleToTakeStep() const;
|
||||||
|
|
||||||
// Compute the time since the last update() call and add it to the accumulator
|
/// Compute the time since the last update() call and add it to the accumulator
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
// Take a new step => update the timer by adding the timeStep value to the current time
|
/// Take a new step => update the timer by adding the timeStep value to the current time
|
||||||
void nextStep();
|
void nextStep();
|
||||||
|
|
||||||
// Compute the interpolation factor
|
/// Compute the interpolation factor
|
||||||
double computeInterpolationFactor();
|
double computeInterpolationFactor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,115 +31,114 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class Matrix3x3
|
||||||
Class Matrix3x3 :
|
/**
|
||||||
This class represents a 3x3 matrix.
|
* This class represents a 3x3 matrix.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class Matrix3x3 {
|
class Matrix3x3 {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Array with the values of the matrix
|
/// Array with the values of the matrix
|
||||||
decimal mArray[3][3];
|
decimal mArray[3][3];
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Matrix3x3();
|
Matrix3x3();
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Matrix3x3(decimal value);
|
Matrix3x3(decimal value);
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Matrix3x3(decimal a1, decimal a2, decimal a3, decimal b1, decimal b2, decimal b3,
|
Matrix3x3(decimal a1, decimal a2, decimal a3, decimal b1, decimal b2, decimal b3,
|
||||||
decimal c1, decimal c2, decimal c3);
|
decimal c1, decimal c2, decimal c3);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
virtual ~Matrix3x3();
|
virtual ~Matrix3x3();
|
||||||
|
|
||||||
// Copy-constructor
|
/// Copy-constructor
|
||||||
Matrix3x3(const Matrix3x3& matrix);
|
Matrix3x3(const Matrix3x3& matrix);
|
||||||
|
|
||||||
// Assignment operator
|
/// Assignment operator
|
||||||
Matrix3x3& operator=(const Matrix3x3& matrix);
|
Matrix3x3& operator=(const Matrix3x3& matrix);
|
||||||
|
|
||||||
// Get a value in the matrix
|
/// Get a value in the matrix
|
||||||
decimal getValue(int i, int j) const;
|
decimal getValue(int i, int j) const;
|
||||||
|
|
||||||
// Set a value in the matrix
|
/// Set a value in the matrix
|
||||||
void setValue(int i, int j, decimal value);
|
void setValue(int i, int j, decimal value);
|
||||||
|
|
||||||
// Set all the values in the matrix
|
/// Set all the values in the matrix
|
||||||
void setAllValues(decimal a1, decimal a2, decimal a3, decimal b1, decimal b2, decimal b3,
|
void setAllValues(decimal a1, decimal a2, decimal a3, decimal b1, decimal b2, decimal b3,
|
||||||
decimal c1, decimal c2, decimal c3);
|
decimal c1, decimal c2, decimal c3);
|
||||||
|
|
||||||
// Return a column
|
/// Return a column
|
||||||
Vector3 getColumn(int i) const;
|
Vector3 getColumn(int i) const;
|
||||||
|
|
||||||
// Return the transpose matrix
|
/// Return the transpose matrix
|
||||||
Matrix3x3 getTranspose() const;
|
Matrix3x3 getTranspose() const;
|
||||||
|
|
||||||
// Return the determinant of the matrix
|
/// Return the determinant of the matrix
|
||||||
decimal getDeterminant() const;
|
decimal getDeterminant() const;
|
||||||
|
|
||||||
// Return the trace of the matrix
|
/// Return the trace of the matrix
|
||||||
decimal getTrace() const;
|
decimal getTrace() const;
|
||||||
|
|
||||||
// Return the inverse matrix
|
/// Return the inverse matrix
|
||||||
Matrix3x3 getInverse() const;
|
Matrix3x3 getInverse() const;
|
||||||
|
|
||||||
// Return the matrix with absolute values
|
/// Return the matrix with absolute values
|
||||||
Matrix3x3 getAbsoluteMatrix() const;
|
Matrix3x3 getAbsoluteMatrix() const;
|
||||||
|
|
||||||
// Set the matrix to the identity matrix
|
/// Set the matrix to the identity matrix
|
||||||
void setToIdentity();
|
void setToIdentity();
|
||||||
|
|
||||||
// Return the 3x3 identity matrix
|
/// Return the 3x3 identity matrix
|
||||||
static Matrix3x3 identity();
|
static Matrix3x3 identity();
|
||||||
|
|
||||||
// Overloaded operator for addition
|
/// Overloaded operator for addition
|
||||||
friend Matrix3x3 operator+(const Matrix3x3& matrix1, const Matrix3x3& matrix2);
|
friend Matrix3x3 operator+(const Matrix3x3& matrix1, const Matrix3x3& matrix2);
|
||||||
|
|
||||||
// Overloaded operator for substraction
|
/// Overloaded operator for substraction
|
||||||
friend Matrix3x3 operator-(const Matrix3x3& matrix1, const Matrix3x3& matrix2);
|
friend Matrix3x3 operator-(const Matrix3x3& matrix1, const Matrix3x3& matrix2);
|
||||||
|
|
||||||
// Overloaded operator for the negative of the matrix
|
/// Overloaded operator for the negative of the matrix
|
||||||
friend Matrix3x3 operator-(const Matrix3x3& matrix);
|
friend Matrix3x3 operator-(const Matrix3x3& matrix);
|
||||||
|
|
||||||
// Overloaded operator for multiplication with a number
|
/// Overloaded operator for multiplication with a number
|
||||||
friend Matrix3x3 operator*(decimal nb, const Matrix3x3& matrix);
|
friend Matrix3x3 operator*(decimal nb, const Matrix3x3& matrix);
|
||||||
|
|
||||||
// Overloaded operator for multiplication with a matrix
|
/// Overloaded operator for multiplication with a matrix
|
||||||
friend Matrix3x3 operator*(const Matrix3x3& matrix, decimal nb);
|
friend Matrix3x3 operator*(const Matrix3x3& matrix, decimal nb);
|
||||||
|
|
||||||
// Overloaded operator for matrix multiplication
|
/// Overloaded operator for matrix multiplication
|
||||||
friend Matrix3x3 operator*(const Matrix3x3& matrix1, const Matrix3x3& matrix2);
|
friend Matrix3x3 operator*(const Matrix3x3& matrix1, const Matrix3x3& matrix2);
|
||||||
|
|
||||||
// Overloaded operator for multiplication with a vector
|
/// Overloaded operator for multiplication with a vector
|
||||||
friend Vector3 operator*(const Matrix3x3& matrix, const Vector3& vector);
|
friend Vector3 operator*(const Matrix3x3& matrix, const Vector3& vector);
|
||||||
|
|
||||||
// Overloaded operator for equality condition
|
/// Overloaded operator for equality condition
|
||||||
bool operator==(const Matrix3x3& matrix) const;
|
bool operator==(const Matrix3x3& matrix) const;
|
||||||
|
|
||||||
// Overloaded operator for the is different condition
|
/// Overloaded operator for the is different condition
|
||||||
bool operator!= (const Matrix3x3& matrix) const;
|
bool operator!= (const Matrix3x3& matrix) const;
|
||||||
|
|
||||||
// Overloaded operator for addition with assignment
|
/// Overloaded operator for addition with assignment
|
||||||
Matrix3x3& operator+=(const Matrix3x3& matrix);
|
Matrix3x3& operator+=(const Matrix3x3& matrix);
|
||||||
|
|
||||||
// Overloaded operator for substraction with assignment
|
/// Overloaded operator for substraction with assignment
|
||||||
Matrix3x3& operator-=(const Matrix3x3& matrix);
|
Matrix3x3& operator-=(const Matrix3x3& matrix);
|
||||||
|
|
||||||
// Overloaded operator for multiplication with a number with assignment
|
/// Overloaded operator for multiplication with a number with assignment
|
||||||
Matrix3x3& operator*=(decimal nb);
|
Matrix3x3& operator*=(decimal nb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -130,9 +130,9 @@ Quaternion::~Quaternion() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the rotation angle (in radians) and the 3D rotation axis
|
// Compute the rotation angle (in radians) and the rotation axis
|
||||||
// This method is used to get the rotation angle (in radian) and the unit
|
/// This method is used to get the rotation angle (in radian) and the unit
|
||||||
// rotation axis of an orientation quaternion.
|
/// rotation axis of an orientation quaternion.
|
||||||
void Quaternion::getRotationAngleAxis(decimal& angle, Vector3& axis) const {
|
void Quaternion::getRotationAngleAxis(decimal& angle, Vector3& axis) const {
|
||||||
Quaternion quaternion;
|
Quaternion quaternion;
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ Matrix3x3 Quaternion::getMatrix() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the spherical linear interpolation between two quaternions.
|
// Compute the spherical linear interpolation between two quaternions.
|
||||||
// The t argument has to be such that 0 <= t <= 1. This method is static.
|
/// The t argument has to be such that 0 <= t <= 1. This method is static.
|
||||||
Quaternion Quaternion::slerp(const Quaternion& quaternion1,
|
Quaternion Quaternion::slerp(const Quaternion& quaternion1,
|
||||||
const Quaternion& quaternion2, decimal t) {
|
const Quaternion& quaternion2, decimal t) {
|
||||||
assert(t >= 0.0 && t <= 1.0);
|
assert(t >= 0.0 && t <= 1.0);
|
||||||
|
@ -226,5 +226,3 @@ Quaternion Quaternion::slerp(const Quaternion& quaternion1,
|
||||||
// Compute and return the interpolated quaternion
|
// Compute and return the interpolated quaternion
|
||||||
return quaternion1 * coeff1 + quaternion2 * coeff2;
|
return quaternion1 * coeff1 + quaternion2 * coeff2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,91 +32,90 @@
|
||||||
#include "Matrix3x3.h"
|
#include "Matrix3x3.h"
|
||||||
#include "../decimal.h"
|
#include "../decimal.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class Quaternion
|
||||||
Class Quaternion :
|
/**
|
||||||
This class represents a quaternion. We use the notation :
|
* This class represents a quaternion. We use the notation :
|
||||||
q = (x*i, y*j, z*k, w) to represent a quaternion.
|
* q = (x*i, y*j, z*k, w) to represent a quaternion.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
struct Quaternion {
|
struct Quaternion {
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Components of the quaternion
|
/// Components of the quaternion
|
||||||
decimal x, y, z, w;
|
decimal x, y, z, w;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Quaternion();
|
Quaternion();
|
||||||
|
|
||||||
// Constructor with arguments
|
/// Constructor with arguments
|
||||||
Quaternion(decimal newX, decimal newY, decimal newZ, decimal newW);
|
Quaternion(decimal newX, decimal newY, decimal newZ, decimal newW);
|
||||||
|
|
||||||
// Constructor with the component w and the vector v=(x y z)
|
/// Constructor with the component w and the vector v=(x y z)
|
||||||
Quaternion(decimal newW, const Vector3& v);
|
Quaternion(decimal newW, const Vector3& v);
|
||||||
|
|
||||||
// Copy-constructor
|
/// Copy-constructor
|
||||||
Quaternion(const Quaternion& quaternion);
|
Quaternion(const Quaternion& quaternion);
|
||||||
|
|
||||||
// Create a unit quaternion from a rotation matrix
|
/// Create a unit quaternion from a rotation matrix
|
||||||
Quaternion(const Matrix3x3& matrix);
|
Quaternion(const Matrix3x3& matrix);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~Quaternion();
|
~Quaternion();
|
||||||
|
|
||||||
// Return the vector v=(x y z) of the quaternion
|
/// Return the vector v=(x y z) of the quaternion
|
||||||
Vector3 vectorV() const;
|
Vector3 vectorV() const;
|
||||||
|
|
||||||
// Return the length of the quaternion
|
/// Return the length of the quaternion
|
||||||
decimal length() const;
|
decimal length() const;
|
||||||
|
|
||||||
// Return the unit quaternion
|
/// Return the unit quaternion
|
||||||
Quaternion getUnit() const;
|
Quaternion getUnit() const;
|
||||||
|
|
||||||
// Return the conjugate quaternion
|
/// Return the conjugate quaternion
|
||||||
Quaternion getConjugate() const;
|
Quaternion getConjugate() const;
|
||||||
|
|
||||||
// Return the inverse of the quaternion
|
/// Return the inverse of the quaternion
|
||||||
Quaternion getInverse() const;
|
Quaternion getInverse() const;
|
||||||
|
|
||||||
// Return the orientation matrix corresponding to this quaternion
|
/// Return the orientation matrix corresponding to this quaternion
|
||||||
Matrix3x3 getMatrix() const;
|
Matrix3x3 getMatrix() const;
|
||||||
|
|
||||||
// Return the identity quaternion
|
/// Return the identity quaternion
|
||||||
static Quaternion identity();
|
static Quaternion identity();
|
||||||
|
|
||||||
// Dot product between two quaternions
|
/// Dot product between two quaternions
|
||||||
decimal dot(const Quaternion& quaternion) const;
|
decimal dot(const Quaternion& quaternion) const;
|
||||||
|
|
||||||
// Compute the rotation angle (in radians) and the axis
|
/// Compute the rotation angle (in radians) and the rotation axis
|
||||||
void getRotationAngleAxis(decimal& angle, Vector3& axis) const;
|
void getRotationAngleAxis(decimal& angle, Vector3& axis) const;
|
||||||
|
|
||||||
// Compute the spherical linear interpolation between two quaternions
|
/// Compute the spherical linear interpolation between two quaternions
|
||||||
static Quaternion slerp(const Quaternion& quaternion1, const Quaternion& quaternion2,
|
static Quaternion slerp(const Quaternion& quaternion1, const Quaternion& quaternion2,
|
||||||
decimal t);
|
decimal t);
|
||||||
|
|
||||||
// Overloaded operator for the addition
|
/// Overloaded operator for the addition
|
||||||
Quaternion operator+(const Quaternion& quaternion) const;
|
Quaternion operator+(const Quaternion& quaternion) const;
|
||||||
|
|
||||||
// Overloaded operator for the substraction
|
/// Overloaded operator for the substraction
|
||||||
Quaternion operator-(const Quaternion& quaternion) const;
|
Quaternion operator-(const Quaternion& quaternion) const;
|
||||||
|
|
||||||
// Overloaded operator for the multiplication with a constant
|
/// Overloaded operator for the multiplication with a constant
|
||||||
Quaternion operator*(decimal nb) const;
|
Quaternion operator*(decimal nb) const;
|
||||||
|
|
||||||
// Overloaded operator for the multiplication
|
/// Overloaded operator for the multiplication
|
||||||
Quaternion operator*(const Quaternion& quaternion) const;
|
Quaternion operator*(const Quaternion& quaternion) const;
|
||||||
|
|
||||||
// Overloaded operator for assignment
|
/// Overloaded operator for assignment
|
||||||
Quaternion& operator=(const Quaternion& quaternion);
|
Quaternion& operator=(const Quaternion& quaternion);
|
||||||
|
|
||||||
// Overloaded operator for equality condition
|
/// Overloaded operator for equality condition
|
||||||
bool operator==(const Quaternion& quaternion) const;
|
bool operator==(const Quaternion& quaternion) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,85 +34,84 @@
|
||||||
// ReactPhysiscs3D namespace
|
// ReactPhysiscs3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class Transform
|
||||||
Class Transform :
|
/**
|
||||||
This class represents a position and an orientation in 3D. It can
|
* This class represents a position and an orientation in 3D. It can
|
||||||
also be seen as representing a translation and a rotation
|
* also be seen as representing a translation and a rotation.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
class Transform {
|
class Transform {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Position
|
/// Position
|
||||||
Vector3 mPosition;
|
Vector3 mPosition;
|
||||||
|
|
||||||
// Orientation
|
/// Orientation
|
||||||
Quaternion mOrientation;
|
Quaternion mOrientation;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Transform();
|
Transform();
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Transform(const Vector3& position, const Matrix3x3& orientation);
|
Transform(const Vector3& position, const Matrix3x3& orientation);
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
Transform(const Vector3& position, const Quaternion& orientation);
|
Transform(const Vector3& position, const Quaternion& orientation);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~Transform();
|
~Transform();
|
||||||
|
|
||||||
// Copy-constructor
|
/// Copy-constructor
|
||||||
Transform(const Transform& transform);
|
Transform(const Transform& transform);
|
||||||
|
|
||||||
// Return the origin of the transform
|
/// Return the origin of the transform
|
||||||
const Vector3& getPosition() const;
|
const Vector3& getPosition() const;
|
||||||
|
|
||||||
// Set the origin of the transform
|
/// Set the origin of the transform
|
||||||
void setPosition(const Vector3& position);
|
void setPosition(const Vector3& position);
|
||||||
|
|
||||||
// Return the orientation quaternion
|
/// Return the orientation quaternion
|
||||||
const Quaternion& getOrientation() const;
|
const Quaternion& getOrientation() const;
|
||||||
|
|
||||||
// Set the rotation quaternion
|
/// Set the rotation quaternion
|
||||||
void setOrientation(const Quaternion& orientation);
|
void setOrientation(const Quaternion& orientation);
|
||||||
|
|
||||||
// Set the transform to the identity transform
|
/// Set the transform to the identity transform
|
||||||
void setToIdentity();
|
void setToIdentity();
|
||||||
|
|
||||||
// Set the transform from an OpenGL transform matrix
|
/// Set the transform from an OpenGL transform matrix
|
||||||
void setFromOpenGL(decimal* openglMatrix);
|
void setFromOpenGL(decimal* openglMatrix);
|
||||||
|
|
||||||
// Get the OpenGL matrix of the transform
|
/// Get the OpenGL matrix of the transform
|
||||||
void getOpenGLMatrix(decimal* openglMatrix) const;
|
void getOpenGLMatrix(decimal* openglMatrix) const;
|
||||||
|
|
||||||
// Return the inverse of the transform
|
/// Return the inverse of the transform
|
||||||
Transform inverse() const;
|
Transform inverse() const;
|
||||||
|
|
||||||
// Return an interpolated transform
|
/// Return an interpolated transform
|
||||||
static Transform interpolateTransforms(const Transform& oldTransform,
|
static Transform interpolateTransforms(const Transform& oldTransform,
|
||||||
const Transform& newTransform,
|
const Transform& newTransform,
|
||||||
decimal interpolationFactor);
|
decimal interpolationFactor);
|
||||||
|
|
||||||
// Return the transformed vector
|
/// Return the transformed vector
|
||||||
Vector3 operator*(const Vector3& vector) const;
|
Vector3 operator*(const Vector3& vector) const;
|
||||||
|
|
||||||
// Operator of multiplication of a transform with another one
|
/// Operator of multiplication of a transform with another one
|
||||||
Transform operator*(const Transform& transform2) const;
|
Transform operator*(const Transform& transform2) const;
|
||||||
|
|
||||||
// Return true if the two transforms are equal
|
/// Return true if the two transforms are equal
|
||||||
bool operator==(const Transform& transform2) const;
|
bool operator==(const Transform& transform2) const;
|
||||||
|
|
||||||
// Return true if the two transforms are different
|
/// Return true if the two transforms are different
|
||||||
bool operator!=(const Transform& transform2) const;
|
bool operator!=(const Transform& transform2) const;
|
||||||
|
|
||||||
// Assignment operator
|
/// Assignment operator
|
||||||
Transform& operator=(const Transform& transform);
|
Transform& operator=(const Transform& transform);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,104 +33,103 @@
|
||||||
#include "../decimal.h"
|
#include "../decimal.h"
|
||||||
|
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class Vector3
|
||||||
Structure Vector3 :
|
/**
|
||||||
This class represents a 3D vector.
|
* This class represents a 3D vector.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
struct Vector3 {
|
struct Vector3 {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Values of the 3D vector
|
/// Values of the 3D vector
|
||||||
decimal x, y, z;
|
decimal x, y, z;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor of the class Vector3D
|
/// Constructor of the class Vector3D
|
||||||
Vector3();
|
Vector3();
|
||||||
|
|
||||||
// Constructor with arguments
|
/// Constructor with arguments
|
||||||
Vector3(decimal newX, decimal newY, decimal newZ);
|
Vector3(decimal newX, decimal newY, decimal newZ);
|
||||||
|
|
||||||
// Copy-constructor
|
/// Copy-constructor
|
||||||
Vector3(const Vector3& vector);
|
Vector3(const Vector3& vector);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~Vector3();
|
~Vector3();
|
||||||
|
|
||||||
// Set all the values of the vector
|
/// Set all the values of the vector
|
||||||
void setAllValues(decimal newX, decimal newY, decimal newZ);
|
void setAllValues(decimal newX, decimal newY, decimal newZ);
|
||||||
|
|
||||||
// Return the lenght of the vector
|
/// Return the lenght of the vector
|
||||||
decimal length() const;
|
decimal length() const;
|
||||||
|
|
||||||
// Return the square of the length of the vector
|
/// Return the square of the length of the vector
|
||||||
decimal lengthSquare() const;
|
decimal lengthSquare() const;
|
||||||
|
|
||||||
// Return the corresponding unit vector
|
/// Return the corresponding unit vector
|
||||||
Vector3 getUnit() const;
|
Vector3 getUnit() const;
|
||||||
|
|
||||||
// Return one unit orthogonal vector of the current vector
|
/// Return one unit orthogonal vector of the current vector
|
||||||
Vector3 getOneUnitOrthogonalVector() const;
|
Vector3 getOneUnitOrthogonalVector() const;
|
||||||
|
|
||||||
// Return true if the vector is unit and false otherwise
|
/// Return true if the vector is unit and false otherwise
|
||||||
bool isUnit() const;
|
bool isUnit() const;
|
||||||
|
|
||||||
// Return true if the current vector is the zero vector
|
/// Return true if the current vector is the zero vector
|
||||||
bool isZero() const;
|
bool isZero() const;
|
||||||
|
|
||||||
// Dot product of two vectors
|
/// Dot product of two vectors
|
||||||
decimal dot(const Vector3& vector) const;
|
decimal dot(const Vector3& vector) const;
|
||||||
|
|
||||||
// Cross product of two vectors
|
/// Cross product of two vectors
|
||||||
Vector3 cross(const Vector3& vector) const;
|
Vector3 cross(const Vector3& vector) const;
|
||||||
|
|
||||||
// Normalize the vector
|
/// Normalize the vector
|
||||||
void normalize();
|
void normalize();
|
||||||
|
|
||||||
// Return the corresponding absolute value vector
|
/// Return the corresponding absolute value vector
|
||||||
Vector3 getAbsoluteVector() const;
|
Vector3 getAbsoluteVector() const;
|
||||||
|
|
||||||
// Return the axis with the minimal value
|
/// Return the axis with the minimal value
|
||||||
int getMinAxis() const;
|
int getMinAxis() const;
|
||||||
|
|
||||||
// Return the axis with the maximal value
|
/// Return the axis with the maximal value
|
||||||
int getMaxAxis() const;
|
int getMaxAxis() const;
|
||||||
|
|
||||||
// Return true if two vectors are parallel
|
/// Return true if two vectors are parallel
|
||||||
bool isParallelWith(const Vector3& vector) const;
|
bool isParallelWith(const Vector3& vector) const;
|
||||||
|
|
||||||
// Overloaded operator for the equality condition
|
/// Overloaded operator for the equality condition
|
||||||
bool operator== (const Vector3& vector) const;
|
bool operator== (const Vector3& vector) const;
|
||||||
|
|
||||||
// Overloaded operator for the is different condition
|
/// Overloaded operator for the is different condition
|
||||||
bool operator!= (const Vector3& vector) const;
|
bool operator!= (const Vector3& vector) const;
|
||||||
|
|
||||||
// Overloaded operator for addition with assignment
|
/// Overloaded operator for addition with assignment
|
||||||
Vector3& operator+=(const Vector3& vector);
|
Vector3& operator+=(const Vector3& vector);
|
||||||
|
|
||||||
// Overloaded operator for substraction with assignment
|
/// Overloaded operator for substraction with assignment
|
||||||
Vector3& operator-=(const Vector3& vector);
|
Vector3& operator-=(const Vector3& vector);
|
||||||
|
|
||||||
// Overloaded operator for multiplication with a number with assignment
|
/// Overloaded operator for multiplication with a number with assignment
|
||||||
Vector3& operator*=(decimal number);
|
Vector3& operator*=(decimal number);
|
||||||
|
|
||||||
// Overloaded operator for division by a number with assignment
|
/// Overloaded operator for division by a number with assignment
|
||||||
Vector3& operator/=(decimal number);
|
Vector3& operator/=(decimal number);
|
||||||
|
|
||||||
// Overloaded operator for value access
|
/// Overloaded operator for value access
|
||||||
decimal& operator[] (int index);
|
decimal& operator[] (int index);
|
||||||
|
|
||||||
// Overloaded operator for value access
|
/// Overloaded operator for value access
|
||||||
const decimal& operator[] (int index) const;
|
const decimal& operator[] (int index) const;
|
||||||
|
|
||||||
// Overloaded operator
|
/// Overloaded operator
|
||||||
Vector3& operator=(const Vector3& vector);
|
Vector3& operator=(const Vector3& vector);
|
||||||
|
|
||||||
// -------------------- Friends -------------------- //
|
// -------------------- Friends -------------------- //
|
||||||
|
|
|
@ -30,13 +30,13 @@
|
||||||
#include "../configuration.h"
|
#include "../configuration.h"
|
||||||
#include "../decimal.h"
|
#include "../decimal.h"
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// ---------- Mathematics functions ---------- //
|
// ---------- Mathematics functions ---------- //
|
||||||
|
|
||||||
// function to test if two real numbers are (almost) equal
|
/// function to test if two real numbers are (almost) equal
|
||||||
// We test if two numbers a and b are such that (a-b) are in [-EPSILON; EPSILON]
|
/// We test if two numbers a and b are such that (a-b) are in [-EPSILON; EPSILON]
|
||||||
inline bool approxEqual(decimal a, decimal b, decimal epsilon = 1.0e-10) {
|
inline bool approxEqual(decimal a, decimal b, decimal epsilon = 1.0e-10) {
|
||||||
decimal difference = a - b;
|
decimal difference = a - b;
|
||||||
return (difference < epsilon && difference > -epsilon);
|
return (difference < epsilon && difference > -epsilon);
|
||||||
|
|
|
@ -37,88 +37,88 @@
|
||||||
// C++ cast operator like reinterpret_cast<>, ...
|
// C++ cast operator like reinterpret_cast<>, ...
|
||||||
|
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
// Class MemoryPool
|
||||||
Class MemoryPool :
|
/**
|
||||||
This class represents a memory pool that allows us to allocate
|
* This class represents a memory pool. This memory pool allows us to allocate
|
||||||
dynamic memory at the beginning of the application in order to
|
* dynamic memory at the beginning of the application in order to
|
||||||
avoid memory fragmentation and also a large number of allocation
|
* avoid memory fragmentation and also a large number of allocation
|
||||||
and deallocation.
|
* and deallocation.
|
||||||
-------------------------------------------------------------------
|
*/
|
||||||
*/
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class MemoryPool {
|
class MemoryPool {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// MemoryUnit represents a unit of memory
|
/// MemoryUnit represents a unit of memory
|
||||||
struct MemoryUnit {
|
struct MemoryUnit {
|
||||||
struct MemoryUnit* pNext; // Pointer to the next memory unit
|
struct MemoryUnit* pNext; // Pointer to the next memory unit
|
||||||
struct MemoryUnit* pPrevious; // Pointer to the previous memory unit
|
struct MemoryUnit* pPrevious; // Pointer to the previous memory unit
|
||||||
};
|
};
|
||||||
|
|
||||||
// Memory block (that contains several memory units)
|
/// Memory block (that contains several memory units)
|
||||||
struct MemoryBlock {
|
struct MemoryBlock {
|
||||||
struct MemoryBlock* pNext; // Pointer to the next memory block
|
struct MemoryBlock* pNext; // Pointer to the next memory block
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- Constants -------------------- //
|
// -------------------- Constants -------------------- //
|
||||||
|
|
||||||
static const uint NB_OBJECTS_FIRST_BLOCK; // Number of objects allocated in the first block
|
// Number of objects allocated in the first block
|
||||||
|
static const uint NB_OBJECTS_FIRST_BLOCK;
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
// Pointer to the first allocated memory block
|
/// Pointer to the first allocated memory block
|
||||||
void* mPBlocks;
|
void* mPBlocks;
|
||||||
|
|
||||||
// Pointer to the first allocated memory unit
|
/// Pointer to the first allocated memory unit
|
||||||
MemoryUnit* mPAllocatedUnits;
|
MemoryUnit* mPAllocatedUnits;
|
||||||
|
|
||||||
// Pointer to the first free memory unit
|
/// Pointer to the first free memory unit
|
||||||
MemoryUnit* mPFreeUnits;
|
MemoryUnit* mPFreeUnits;
|
||||||
|
|
||||||
// Current number of objects in the pool
|
/// Current number of objects in the pool
|
||||||
uint mCurrentNbObjects;
|
uint mCurrentNbObjects;
|
||||||
|
|
||||||
// Current maximum number of objects that can be allocated in the pool
|
/// Current maximum number of objects that can be allocated in the pool
|
||||||
uint mCapacity;
|
uint mCapacity;
|
||||||
|
|
||||||
// Number of objects to allocate in the next block
|
/// Number of objects to allocate in the next block
|
||||||
uint mNbObjectsNextBlock;
|
uint mNbObjectsNextBlock;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Private copy-constructor
|
/// Private copy-constructor
|
||||||
MemoryPool(const MemoryPool& body);
|
MemoryPool(const MemoryPool& body);
|
||||||
|
|
||||||
// Private assignment operator
|
/// Private assignment operator
|
||||||
MemoryPool& operator=(const MemoryPool& timer);
|
MemoryPool& operator=(const MemoryPool& timer);
|
||||||
|
|
||||||
// Allocate more memory (more blocks) when needed
|
/// Allocate more memory (more blocks) when needed
|
||||||
void allocateMemory();
|
void allocateMemory();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
// Constructor
|
/// Constructor
|
||||||
MemoryPool(uint capacity = 0) throw(std::bad_alloc);
|
MemoryPool(uint capacity = 0) throw(std::bad_alloc);
|
||||||
|
|
||||||
// Destructor
|
/// Destructor
|
||||||
~MemoryPool();
|
~MemoryPool();
|
||||||
|
|
||||||
// Return the current maximum number of objects allowed in the pool
|
/// Return the current maximum number of objects allowed in the pool
|
||||||
uint getCapacity() const;
|
uint getCapacity() const;
|
||||||
|
|
||||||
// Return the current number of objects in the pool
|
/// Return the current number of objects in the pool
|
||||||
uint getCurrentNbObjects() const;
|
uint getCurrentNbObjects() const;
|
||||||
|
|
||||||
// Return a pointer to an memory allocated location to store a new object
|
/// Return a pointer to an memory allocated location to store a new object
|
||||||
void* allocateObject();
|
void* allocateObject();
|
||||||
|
|
||||||
// Tell the pool that an object doesn't need to be store in the pool anymore
|
/// Tell the pool that an object doesn't need to be store in the pool anymore
|
||||||
void freeObject(void* pObjectToFree);
|
void freeObject(void* pObjectToFree);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,8 +126,8 @@ class MemoryPool {
|
||||||
template<class T> const uint MemoryPool<T>::NB_OBJECTS_FIRST_BLOCK = 100;
|
template<class T> const uint MemoryPool<T>::NB_OBJECTS_FIRST_BLOCK = 100;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
// Allocate a large block of memory in order to contain
|
/// Allocate a large block of memory in order to contain
|
||||||
// a given number of object of the template type T
|
/// a given number of object of the template type T
|
||||||
template<class T>
|
template<class T>
|
||||||
MemoryPool<T>::MemoryPool(uint capacity) throw(std::bad_alloc)
|
MemoryPool<T>::MemoryPool(uint capacity) throw(std::bad_alloc)
|
||||||
: mCurrentNbObjects(0), mCapacity(capacity) {
|
: mCurrentNbObjects(0), mCapacity(capacity) {
|
||||||
|
@ -142,7 +142,7 @@ MemoryPool<T>::MemoryPool(uint capacity) throw(std::bad_alloc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
// Deallocate the blocks of memory that have been allocated previously
|
/// Deallocate the blocks of memory that have been allocated previously
|
||||||
template<class T>
|
template<class T>
|
||||||
MemoryPool<T>::~MemoryPool() {
|
MemoryPool<T>::~MemoryPool() {
|
||||||
|
|
||||||
|
@ -158,9 +158,9 @@ MemoryPool<T>::~MemoryPool() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a pointer to a memory allocated location to store a new object
|
// Return a pointer to a memory allocated location to store a new object.
|
||||||
// This method only allocates memory if needed and it returns a pointer
|
/// This method only allocates memory if needed and it returns a pointer
|
||||||
// to a location in an allocated block of memory where a new object can be stored
|
/// to a location in an allocated block of memory where a new object can be stored
|
||||||
template<class T>
|
template<class T>
|
||||||
void* MemoryPool<T>::allocateObject() {
|
void* MemoryPool<T>::allocateObject() {
|
||||||
|
|
||||||
|
@ -193,10 +193,10 @@ void* MemoryPool<T>::allocateObject() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
// This method does not deallocate memory because it will be done only at the
|
/// This method does not deallocate memory because it will be done only at the
|
||||||
// end but it notifies the memory pool that an object that was stored in the pool
|
/// end but it notifies the memory pool that an object that was stored in the pool
|
||||||
// does not need to be stored anymore and therefore we can use the corresponding
|
/// does not need to be stored anymore and therefore we can use the corresponding
|
||||||
// location in the pool for another object
|
/// location in the pool for another object
|
||||||
template<class T>
|
template<class T>
|
||||||
void MemoryPool<T>::freeObject(void* pObjectToFree) {
|
void MemoryPool<T>::freeObject(void* pObjectToFree) {
|
||||||
|
|
||||||
|
@ -218,9 +218,10 @@ void MemoryPool<T>::freeObject(void* pObjectToFree) {
|
||||||
mCurrentNbObjects--;
|
mCurrentNbObjects--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate more memory. This method is called when there are no
|
// Allocate more memory (more blocks) when needed
|
||||||
// free memory units available anymore. Therefore, we need to allocate
|
/// This method is called when there are no
|
||||||
// a new memory block in order to be able to store several new memory units.
|
/// free memory units available anymore. Therefore, we need to allocate
|
||||||
|
/// a new memory block in order to be able to store several new memory units.
|
||||||
template<class T>
|
template<class T>
|
||||||
void MemoryPool<T>::allocateMemory() {
|
void MemoryPool<T>::allocateMemory() {
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
#include "collision/shapes/CylinderShape.h"
|
#include "collision/shapes/CylinderShape.h"
|
||||||
#include "collision/shapes/AABB.h"
|
#include "collision/shapes/AABB.h"
|
||||||
|
|
||||||
// Alias to the ReactPhysics3D namespace
|
/// Alias to the ReactPhysics3D namespace
|
||||||
namespace rp3d = reactphysics3d;
|
namespace rp3d = reactphysics3d;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user