git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@303 92aac97c-a6ce-11dd-a772-7fcde58d38e6
This commit is contained in:
parent
047c2f847f
commit
d15751c1de
|
@ -21,6 +21,7 @@
|
||||||
#include "CollisionDetection.h"
|
#include "CollisionDetection.h"
|
||||||
#include "NoBroadPhaseAlgorithm.h"
|
#include "NoBroadPhaseAlgorithm.h"
|
||||||
#include "SATAlgorithm.h"
|
#include "SATAlgorithm.h"
|
||||||
|
#include "../body/Body.h"
|
||||||
#include "../body/OBB.h"
|
#include "../body/OBB.h"
|
||||||
#include "../body/RigidBody.h"
|
#include "../body/RigidBody.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -29,8 +30,9 @@
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
CollisionDetection::CollisionDetection() {
|
CollisionDetection::CollisionDetection(PhysicsWorld* world) {
|
||||||
|
this->world = world;
|
||||||
|
|
||||||
// Construct the broad-phase algorithm that will be used (Separating axis with AABB)
|
// Construct the broad-phase algorithm that will be used (Separating axis with AABB)
|
||||||
broadPhaseAlgorithm = new NoBroadPhaseAlgorithm();
|
broadPhaseAlgorithm = new NoBroadPhaseAlgorithm();
|
||||||
|
|
||||||
|
@ -44,9 +46,27 @@ CollisionDetection::~CollisionDetection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the collision detection
|
// Compute the collision detection
|
||||||
bool CollisionDetection::computeCollisionDetection(PhysicsWorld* world) {
|
bool CollisionDetection::computeCollisionDetection() {
|
||||||
|
|
||||||
bool existsCollision = false; // True if a collision is found in the time interval [0, timeMax]
|
world->removeAllContactConstraints();
|
||||||
|
possibleCollisionPairs.clear();
|
||||||
|
contactInfos.clear();
|
||||||
|
|
||||||
|
// Compute the broad-phase collision detection
|
||||||
|
computeBroadPhase();
|
||||||
|
|
||||||
|
// Compute the narrow-phase collision detection
|
||||||
|
computeNarrowPhase();
|
||||||
|
|
||||||
|
// Compute all the new contacts
|
||||||
|
computeAllContacts();
|
||||||
|
|
||||||
|
// Return true if at least one contact has been found
|
||||||
|
return (contactInfos.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the broad-phase collision detection
|
||||||
|
void CollisionDetection::computeBroadPhase() {
|
||||||
|
|
||||||
// For each pair of bodies in the physics world
|
// For each pair of bodies in the physics world
|
||||||
for(std::vector<Body*>::const_iterator it1 = world->getBodyListStartIterator(); it1 != world->getBodyListEndIterator(); ++it1) {
|
for(std::vector<Body*>::const_iterator it1 = world->getBodyListStartIterator(); it1 != world->getBodyListEndIterator(); ++it1) {
|
||||||
|
@ -61,20 +81,154 @@ bool CollisionDetection::computeCollisionDetection(PhysicsWorld* world) {
|
||||||
|
|
||||||
// Use the broad-phase algorithm to decide if the two bodies can collide
|
// Use the broad-phase algorithm to decide if the two bodies can collide
|
||||||
if(broadPhaseAlgorithm->testCollisionPair(&obb1, &obb2)) {
|
if(broadPhaseAlgorithm->testCollisionPair(&obb1, &obb2)) {
|
||||||
Contact* contact = 0;
|
// If the broad-phase thinks that the two bodies collide, we add the in the possible collision pair list
|
||||||
|
possibleCollisionPairs.push_back(std::pair<const OBB*, const OBB*>(&obb1, &obb2));
|
||||||
// Use the narrow-phase algorithm to check if the two bodies really collide
|
|
||||||
if(narrowPhaseAlgorithm->testCollision(&obb1, &obb2, &contact)) {
|
|
||||||
assert(contact != 0);
|
|
||||||
existsCollision = true;
|
|
||||||
|
|
||||||
// Add the new collision contact into the collision world
|
|
||||||
world->addConstraint(contact);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return existsCollision;
|
|
||||||
|
// Compute the narrow-phase collision detection
|
||||||
|
void CollisionDetection::computeNarrowPhase() {
|
||||||
|
// For each possible collision pair of bodies
|
||||||
|
for (unsigned int i=0; i<possibleCollisionPairs.size(); i++) {
|
||||||
|
ContactInfo* contactInfo = 0;
|
||||||
|
|
||||||
|
// Use the narrow-phase collision detection algorithm to check if the really are a contact
|
||||||
|
if (narrowPhaseAlgorithm->testCollision(possibleCollisionPairs.at(i).first, possibleCollisionPairs.at(i).second, contactInfo)) {
|
||||||
|
assert(contactInfo != 0);
|
||||||
|
|
||||||
|
// Add the contact info the current list of collision informations
|
||||||
|
contactInfos.push_back(contactInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute all the contacts from the contact info list
|
||||||
|
void CollisionDetection::computeAllContacts() {
|
||||||
|
// For each possible contact info (computed during narrow-phase collision detection)
|
||||||
|
for (unsigned int i=0; i<contactInfos.size(); i++) {
|
||||||
|
ContactInfo* contactInfo = contactInfos.at(i);
|
||||||
|
assert(contactInfo != 0);
|
||||||
|
|
||||||
|
// Compute one or several new contacts and add them into the physics world
|
||||||
|
computeContact(contactInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute a contact (and add it to the physics world) for two colliding bodies
|
||||||
|
void CollisionDetection::computeContact(const ContactInfo* const contactInfo) {
|
||||||
|
|
||||||
|
// Extract informations from the contact info structure
|
||||||
|
const OBB* const obb1 = contactInfo->obb1;
|
||||||
|
const OBB* const obb2 = contactInfo->obb2;
|
||||||
|
Vector3D normal = contactInfo->normal;
|
||||||
|
double penetrationDepth = contactInfo->penetrationDepth;
|
||||||
|
|
||||||
|
const std::vector<Vector3D> obb1ExtremePoints = obb1->getExtremeVertices(normal);
|
||||||
|
const std::vector<Vector3D> obb2ExtremePoints = obb2->getExtremeVertices(normal.getOpposite());
|
||||||
|
unsigned int nbVerticesExtremeOBB1 = obb1ExtremePoints.size();
|
||||||
|
unsigned int nbVerticesExtremeOBB2 = obb2ExtremePoints.size();
|
||||||
|
assert(nbVerticesExtremeOBB1==1 || nbVerticesExtremeOBB1==2 || nbVerticesExtremeOBB1==4);
|
||||||
|
assert(nbVerticesExtremeOBB2==1 || nbVerticesExtremeOBB2==2 || nbVerticesExtremeOBB2==4);
|
||||||
|
assert(approxEqual(normal.length(), 1.0));
|
||||||
|
|
||||||
|
// If it's a Vertex-Something contact
|
||||||
|
if (nbVerticesExtremeOBB1 == 1) {
|
||||||
|
// Create a new contact and add it to the physics world
|
||||||
|
world->addConstraint(new Contact(obb1->getBodyPointer(), obb2->getBodyPointer(), normal, penetrationDepth, obb1ExtremePoints.at(0)));
|
||||||
|
}
|
||||||
|
else if(nbVerticesExtremeOBB2 == 1) { // If its a Vertex-Something contact
|
||||||
|
// Create a new contact and add it to the physics world
|
||||||
|
world->addConstraint(new Contact(obb1->getBodyPointer(), obb2->getBodyPointer(), normal, penetrationDepth, obb2ExtremePoints.at(0)));
|
||||||
|
}
|
||||||
|
else if (nbVerticesExtremeOBB1 == 2 && nbVerticesExtremeOBB2 == 2) { // If it's an edge-edge contact
|
||||||
|
// Compute the two vectors of the segment lines
|
||||||
|
Vector3D d1 = obb1ExtremePoints[1] - obb1ExtremePoints[0];
|
||||||
|
Vector3D d2 = obb2ExtremePoints[1] - obb2ExtremePoints[0];
|
||||||
|
|
||||||
|
double alpha, beta;
|
||||||
|
std::vector<Vector3D> contactSet;
|
||||||
|
|
||||||
|
// If the two edges are parallel
|
||||||
|
if (d1.isParallelWith(d2)) {
|
||||||
|
Vector3D contactPointA;
|
||||||
|
Vector3D contactPointB;
|
||||||
|
|
||||||
|
// Compute the intersection between the two edges
|
||||||
|
computeParallelSegmentsIntersection(obb1ExtremePoints[0], obb1ExtremePoints[1], obb2ExtremePoints[0], obb2ExtremePoints[1],
|
||||||
|
contactPointA, contactPointB);
|
||||||
|
|
||||||
|
// Add the two contact points in the contact set
|
||||||
|
contactSet.push_back(contactPointA);
|
||||||
|
contactSet.push_back(contactPointB);
|
||||||
|
}
|
||||||
|
else { // If the two edges are not parallel
|
||||||
|
// Compute the closest two points between the two line segments
|
||||||
|
closestPointsBetweenTwoLines(obb1ExtremePoints[0], d1, obb2ExtremePoints[0], d2, &alpha, &beta);
|
||||||
|
Vector3D pointA = obb1ExtremePoints[0] + d1 * alpha;
|
||||||
|
Vector3D pointB = obb2ExtremePoints[0] + d2 * beta;
|
||||||
|
|
||||||
|
// Compute the contact point as halfway between the 2 closest points
|
||||||
|
Vector3D contactPoint = 0.5 * (pointA + pointB);
|
||||||
|
|
||||||
|
// Add the contact point into the contact set
|
||||||
|
contactSet.push_back(contactPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each point of the set of contact points
|
||||||
|
for (unsigned int i=0; i<contactSet.size(); i++) {
|
||||||
|
// Create a new contact and add it to the physics world
|
||||||
|
world->addConstraint(new Contact(obb1->getBodyPointer(), obb2->getBodyPointer(), normal, penetrationDepth, contactSet.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(nbVerticesExtremeOBB1 == 2 && nbVerticesExtremeOBB2 == 4) { // If it's an edge-face contact
|
||||||
|
// Compute the projection of the edge of OBB1 onto the same plane of the face of OBB2
|
||||||
|
std::vector<Vector3D> edge = projectPointsOntoPlane(obb1ExtremePoints, obb2ExtremePoints[0], normal);
|
||||||
|
|
||||||
|
// Clip the edge of OBB1 using the face of OBB2
|
||||||
|
std::vector<Vector3D> clippedEdge = clipSegmentWithRectangleInPlane(edge, obb2ExtremePoints);
|
||||||
|
|
||||||
|
// Move the clipped edge halway between the edge of OBB1 and the face of OBB2
|
||||||
|
clippedEdge = movePoints(clippedEdge, penetrationDepth/2.0 * normal.getOpposite());
|
||||||
|
|
||||||
|
// For each point of the contact set
|
||||||
|
for (unsigned int i=0; i<clippedEdge.size(); i++) {
|
||||||
|
// Create a new contact and add it to the physics world
|
||||||
|
world->addConstraint(new Contact(obb1->getBodyPointer(), obb2->getBodyPointer(), normal, penetrationDepth, clippedEdge.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(nbVerticesExtremeOBB1 == 4 && nbVerticesExtremeOBB2 == 2) { // If it's an edge-face contact
|
||||||
|
// Compute the projection of the edge of OBB2 onto the same plane of the face of OBB1
|
||||||
|
std::vector<Vector3D> edge = projectPointsOntoPlane(obb2ExtremePoints, obb1ExtremePoints[0], normal);
|
||||||
|
|
||||||
|
// Clip the edge of OBB2 using the face of OBB1
|
||||||
|
std::vector<Vector3D> clippedEdge = clipSegmentWithRectangleInPlane(edge, obb1ExtremePoints);
|
||||||
|
|
||||||
|
// Move the clipped edge halfway between the face of OBB1 and the edge of OBB2
|
||||||
|
clippedEdge = movePoints(clippedEdge, penetrationDepth/2.0 * normal);
|
||||||
|
|
||||||
|
// For each point of the contact set
|
||||||
|
for (unsigned int i=0; i<clippedEdge.size(); i++) {
|
||||||
|
// Create a new contact and add it to the physics world
|
||||||
|
world->addConstraint(new Contact(obb1->getBodyPointer(), obb2->getBodyPointer(), normal, penetrationDepth, clippedEdge.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // If it's a face-face contact
|
||||||
|
// Compute the projection of the face vertices of OBB2 onto the plane of the face of OBB1
|
||||||
|
std::vector<Vector3D> faceOBB2 = projectPointsOntoPlane(obb2ExtremePoints, obb1ExtremePoints[0], normal);
|
||||||
|
|
||||||
|
// Clip the face of OBB2 using the face of OBB1
|
||||||
|
std::vector<Vector3D> clippedFace = clipPolygonWithRectangleInPlane(faceOBB2, obb1ExtremePoints);
|
||||||
|
|
||||||
|
// Move the clipped face halfway between the face of OBB1 and the face of OBB2
|
||||||
|
clippedFace = movePoints(clippedFace, penetrationDepth/2.0 * normal);
|
||||||
|
|
||||||
|
// For each point of the contact set
|
||||||
|
for (unsigned int i=0; i<clippedFace.size(); i++) {
|
||||||
|
// Create a new contact and add it to the physics world
|
||||||
|
world->addConstraint(new Contact(obb1->getBodyPointer(), obb2->getBodyPointer(), normal, penetrationDepth, clippedFace.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "NarrowPhaseAlgorithm.h"
|
#include "NarrowPhaseAlgorithm.h"
|
||||||
#include "../body/Body.h"
|
#include "../body/Body.h"
|
||||||
#include "../engine/PhysicsWorld.h"
|
#include "../engine/PhysicsWorld.h"
|
||||||
|
#include "ContactInfo.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
// ReactPhysics3D namespace
|
||||||
|
@ -40,31 +41,26 @@ namespace reactphysics3d {
|
||||||
*/
|
*/
|
||||||
class CollisionDetection {
|
class CollisionDetection {
|
||||||
private :
|
private :
|
||||||
std::vector< std::pair<Body*, Body*> > possibleCollisionPairList; // List that contains the possible collision pairs of bodies
|
PhysicsWorld* world; // Pointer to the physics world
|
||||||
BroadPhaseAlgorithm* broadPhaseAlgorithm; // Broad-phase algorithm
|
std::vector<std::pair<const OBB*, const OBB* > > possibleCollisionPairs; // Possible collision pairs of bodies (computed by broadphase)
|
||||||
NarrowPhaseAlgorithm* narrowPhaseAlgorithm; // Narrow-phase algorithm
|
std::vector<ContactInfo*> contactInfos; // Contact informations (computed by narrowphase)
|
||||||
|
|
||||||
void addPossibleCollisionPair(Body* body1, Body* body2); // Add a possible collision pair of bodies in the possibleCollisionPairList
|
// TODO : Check if we can avoid pointers for the two following classes (to avoid dynamic alocation)
|
||||||
void initPossibleCollisionPairList(); // Initialize the possibleCollisionPairList
|
BroadPhaseAlgorithm* broadPhaseAlgorithm; // Broad-phase algorithm
|
||||||
|
NarrowPhaseAlgorithm* narrowPhaseAlgorithm; // Narrow-phase algorithm
|
||||||
|
|
||||||
|
void computeBroadPhase(); // Compute the broad-phase collision detection
|
||||||
|
void computeNarrowPhase(); // Compute the narrow-phase collision detection
|
||||||
|
void computeAllContacts(); // Compute all the contacts from the collision info list
|
||||||
|
void computeContact(const ContactInfo* const contactInfo); // Compute a contact (and add it to the physics world) for two colliding bodies
|
||||||
|
|
||||||
public :
|
public :
|
||||||
CollisionDetection(); // Constructor
|
CollisionDetection(PhysicsWorld* physicsWorld); // Constructor
|
||||||
~CollisionDetection(); // Destructor
|
~CollisionDetection(); // Destructor
|
||||||
|
|
||||||
bool computeCollisionDetection(PhysicsWorld* world); // Compute the collision detection
|
bool computeCollisionDetection(); // Compute the collision detection
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add a possible collision pair of bodies in the possibleCollisionPairList
|
|
||||||
inline void CollisionDetection::addPossibleCollisionPair(Body* body1, Body* body2) {
|
|
||||||
// TODO : Implement this method
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the possibleCollisionPairList
|
|
||||||
inline void CollisionDetection::initPossibleCollisionPairList() {
|
|
||||||
// TODO : Implement this method
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // End of the ReactPhysics3D namespace
|
} // End of the ReactPhysics3D namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "../body/BoundingVolume.h"
|
#include "../body/BoundingVolume.h"
|
||||||
#include "../constraint/Contact.h"
|
#include "ContactInfo.h"
|
||||||
|
|
||||||
// Namespace ReactPhysics3D
|
// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
@ -44,7 +44,7 @@ class NarrowPhaseAlgorithm {
|
||||||
NarrowPhaseAlgorithm(); // Constructor
|
NarrowPhaseAlgorithm(); // Constructor
|
||||||
virtual ~NarrowPhaseAlgorithm(); // Destructor
|
virtual ~NarrowPhaseAlgorithm(); // Destructor
|
||||||
|
|
||||||
virtual bool testCollision(const BoundingVolume* const boundingVolume1, const BoundingVolume* const boundingVolume2, Contact** contact)=0; // Return true and compute a collision contact if the two bounding volume collide
|
virtual bool testCollision(const BoundingVolume* const boundingVolume1, const BoundingVolume* const boundingVolume2, ContactInfo*& contactInfo)=0; // Return true and compute a contact info if the two bounding volume collide
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of reactphysics3d namespace
|
} // End of reactphysics3d namespace
|
||||||
|
|
|
@ -42,12 +42,11 @@ SATAlgorithm::~SATAlgorithm() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true and compute a collision contact if the two bounding volume collide.
|
// Return true and compute a contact info if the two bounding volume collide.
|
||||||
// The method returns false if there is no collision between the two bounding volumes.
|
// The method returns false if there is no collision between the two bounding volumes.
|
||||||
bool SATAlgorithm::testCollision(const BoundingVolume* const boundingVolume1, const BoundingVolume* const boundingVolume2, Contact** contact) {
|
bool SATAlgorithm::testCollision(const BoundingVolume* const boundingVolume1, const BoundingVolume* const boundingVolume2, ContactInfo*& contactInfo) {
|
||||||
|
|
||||||
assert(boundingVolume1 != boundingVolume2);
|
assert(boundingVolume1 != boundingVolume2);
|
||||||
assert(*contact == 0);
|
|
||||||
|
|
||||||
// If the two bounding volumes are OBB
|
// If the two bounding volumes are OBB
|
||||||
const OBB* const obb1 = dynamic_cast<const OBB* const>(boundingVolume1);
|
const OBB* const obb1 = dynamic_cast<const OBB* const>(boundingVolume1);
|
||||||
|
@ -56,7 +55,7 @@ bool SATAlgorithm::testCollision(const BoundingVolume* const boundingVolume1, co
|
||||||
// If the two bounding volumes are OBB
|
// If the two bounding volumes are OBB
|
||||||
if (obb1 && obb2) {
|
if (obb1 && obb2) {
|
||||||
// Compute the collision test between two OBB
|
// Compute the collision test between two OBB
|
||||||
return computeCollisionTest(obb1, obb2, contact);
|
return computeCollisionTest(obb1, obb2, contactInfo);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -64,14 +63,14 @@ bool SATAlgorithm::testCollision(const BoundingVolume* const boundingVolume1, co
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This method returns true and computes a collision contact if the two OBB intersect.
|
// This method returns true and computes a contact info if the two OBB intersect.
|
||||||
// This method implements the separating algorithm between two OBB. The goal of this method is to test if the
|
// This method implements the separating algorithm between two OBB. The goal of this method is to test if the
|
||||||
// two OBBs intersect or not. If they intersect we report a collision contact and the method returns true. If
|
// two OBBs intersect or not. If they intersect we report a contact info and the method returns true. If
|
||||||
// they don't intersect, the method returns false. The separation axis that have to be tested for two
|
// they don't intersect, the method returns false. The separation axis that have to be tested for two
|
||||||
// OBB are the six face normals (3 for each OBB) and the nine vectors V = Ai x Bj where Ai is the ith face normal
|
// OBB are the six face normals (3 for each OBB) and the nine vectors V = Ai x Bj where Ai is the ith face normal
|
||||||
// vector of OBB 1 and Bj is the jth face normal vector of OBB 2. We will use the notation Ai for the ith face
|
// vector of OBB 1 and Bj is the jth face normal vector of OBB 2. We will use the notation Ai for the ith face
|
||||||
// normal of OBB 1 and Bj for the jth face normal of OBB 2.
|
// normal of OBB 1 and Bj for the jth face normal of OBB 2.
|
||||||
bool SATAlgorithm::computeCollisionTest(const OBB* const obb1, const OBB* const obb2, Contact** contact) const {
|
bool SATAlgorithm::computeCollisionTest(const OBB* const obb1, const OBB* const obb2, ContactInfo*& contactInfo) const {
|
||||||
|
|
||||||
double center; // Center of a projection interval
|
double center; // Center of a projection interval
|
||||||
double radius1; // Radius of projection interval [min1, max1]
|
double radius1; // Radius of projection interval [min1, max1]
|
||||||
|
@ -240,9 +239,9 @@ bool SATAlgorithm::computeCollisionTest(const OBB* const obb1, const OBB* const
|
||||||
// There exists a parallel pair of face normals and we have already checked all the face
|
// There exists a parallel pair of face normals and we have already checked all the face
|
||||||
// normals for separation. Therefore the OBBs must intersect
|
// normals for separation. Therefore the OBBs must intersect
|
||||||
|
|
||||||
// Compute the collision contact
|
// Compute the contact info
|
||||||
computeContact(obb1, obb2, normal.getUnit(), minPenetrationDepth, obb1->getExtremeVertices(normal), obb2->getExtremeVertices(normal.getOpposite()), contact);
|
contactInfo = new ContactInfo(obb1, obb2, normal.getUnit(), minPenetrationDepth);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,9 +407,9 @@ bool SATAlgorithm::computeCollisionTest(const OBB* const obb1, const OBB* const
|
||||||
normal = computeContactNormal(obb1->getAxis(2).crossProduct(obb2->getAxis(2)), boxDistance); // Compute the contact normal with the correct sign
|
normal = computeContactNormal(obb1->getAxis(2).crossProduct(obb2->getAxis(2)), boxDistance); // Compute the contact normal with the correct sign
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the collision contact
|
// Compute the contact info
|
||||||
computeContact(obb1, obb2, normal.getUnit(), minPenetrationDepth, obb1->getExtremeVertices(normal), obb2->getExtremeVertices(normal.getOpposite()), contact);
|
contactInfo = new ContactInfo(obb1, obb2, normal.getUnit(), minPenetrationDepth);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +445,7 @@ double SATAlgorithm::computePenetrationDepth(double min1, double max1, double mi
|
||||||
return penetrationDepth;
|
return penetrationDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO : Remove this following code
|
||||||
// Compute a new collision contact between two OBBs
|
// Compute a new collision contact between two OBBs
|
||||||
void SATAlgorithm::computeContact(const OBB* const obb1, const OBB* const obb2, const Vector3D normal, double penetrationDepth,
|
void SATAlgorithm::computeContact(const OBB* const obb1, const OBB* const obb2, const Vector3D normal, double penetrationDepth,
|
||||||
const std::vector<Vector3D>& obb1ExtremePoints, const std::vector<Vector3D>& obb2ExtremePoints, Contact** contact) const {
|
const std::vector<Vector3D>& obb1ExtremePoints, const std::vector<Vector3D>& obb2ExtremePoints, Contact** contact) const {
|
||||||
|
@ -544,3 +544,4 @@ void SATAlgorithm::computeContact(const OBB* const obb1, const OBB* const obb2,
|
||||||
|
|
||||||
assert(*contact != 0);
|
assert(*contact != 0);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -44,17 +44,18 @@ namespace reactphysics3d {
|
||||||
*/
|
*/
|
||||||
class SATAlgorithm : public NarrowPhaseAlgorithm {
|
class SATAlgorithm : public NarrowPhaseAlgorithm {
|
||||||
private :
|
private :
|
||||||
bool computeCollisionTest(const OBB* const obb1, const OBB* const obb2, Contact** contact) const; // Return true and compute a collision contact if the two OBB collide
|
bool computeCollisionTest(const OBB* const obb1, const OBB* const obb2, ContactInfo*& contactInfo) const; // Return true and compute a contact info if the two OBB collide
|
||||||
double computePenetrationDepth(double min1, double max1, double min2, double max2, bool& side) const; // Compute the penetration depth of two projection intervals
|
double computePenetrationDepth(double min1, double max1, double min2, double max2, bool& side) const; // Compute the penetration depth of two projection intervals
|
||||||
void computeContact(const OBB* const obb1, const OBB* const obb2, const Vector3D normal, double penetrationDepth,
|
// TODO : Remove the following method
|
||||||
const std::vector<Vector3D>& obb1ExtremePoints, const std::vector<Vector3D>& obb2ExtremePoints, Contact** contact) const; // Compute a new contact // Compute a new collision contact between two projection intervals
|
//void computeContact(const OBB* const obb1, const OBB* const obb2, const Vector3D normal, double penetrationDepth,
|
||||||
Vector3D computeContactNormal(const Vector3D& axis, const Vector3D& distanceOfOBBs) const; // Compute a contact normal
|
// const std::vector<Vector3D>& obb1ExtremePoints, const std::vector<Vector3D>& obb2ExtremePoints, Contact** contact) const; // Compute a new contact // Compute a new collision contact between two projection intervals
|
||||||
|
Vector3D computeContactNormal(const Vector3D& axis, const Vector3D& distanceOfOBBs) const; // Compute a contact normal
|
||||||
|
|
||||||
public :
|
public :
|
||||||
SATAlgorithm(); // Constructor
|
SATAlgorithm(); // Constructor
|
||||||
~SATAlgorithm(); // Destructor
|
~SATAlgorithm(); // Destructor
|
||||||
|
|
||||||
virtual bool testCollision(const BoundingVolume* const boundingVolume1, const BoundingVolume* const boundingVolume2, Contact** contact); // Return true and compute a collision contact if the two bounding volume collide
|
virtual bool testCollision(const BoundingVolume* const boundingVolume1, const BoundingVolume* const boundingVolume2, ContactInfo*& contactInfo); // Return true and compute a contact info if the two bounding volume collide
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Inlines function --- //
|
// --- Inlines function --- //
|
||||||
|
|
|
@ -60,21 +60,22 @@ class Constraint {
|
||||||
Vector auxErrorValues; // Error values for the auxiliary constraints
|
Vector auxErrorValues; // Error values for the auxiliary constraints
|
||||||
|
|
||||||
public :
|
public :
|
||||||
Constraint(Body* const body1, Body* const body2, unsigned int nbAuxConstraints, bool active); // Constructor // Constructor
|
Constraint(Body* const body1, Body* const body2, unsigned int nbAuxConstraints, bool active); // Constructor // Constructor
|
||||||
virtual ~Constraint(); // Destructor
|
virtual ~Constraint(); // Destructor
|
||||||
Body* const getBody1() const; // Return the reference to the body 1
|
Body* const getBody1() const; // Return the reference to the body 1
|
||||||
Body* const getBody2() const; // Return the reference to the body 2
|
Body* const getBody2() const; // Return the reference to the body 2
|
||||||
virtual void evaluate()=0; // Evaluate the constraint
|
virtual void evaluate()=0; // Evaluate the constraint
|
||||||
bool isActive() const; // Return true if the constraint is active
|
bool isActive() const; // Return true if the constraint is active
|
||||||
Matrix getBody1Jacobian() const; // Return the jacobian matrix of body 1
|
const Matrix& getBody1Jacobian() const; // Return the jacobian matrix of body 1
|
||||||
Matrix getBody2Jacobian() const; // Return the jacobian matrix of body 2
|
const Matrix& getBody2Jacobian() const; // Return the jacobian matrix of body 2
|
||||||
unsigned int getNbAuxConstraints() const; // Return the number of auxiliary constraints
|
unsigned int getNbAuxConstraints() const; // Return the number of auxiliary constraints
|
||||||
void getAuxJacobian(Matrix& auxJacobian) const; // Return the jacobian matrix of auxiliary constraints
|
const Matrix& getAuxJacobian() const; // Return the jacobian matrix of auxiliary constraints
|
||||||
double getLowerBound() const; // Return the lower bound value of the constraint
|
double getLowerBound() const; // Return the lower bound value of the constraint
|
||||||
double getUpperBound() const; // Return the upper bound value of the constraint
|
double getUpperBound() const; // Return the upper bound value of the constraint
|
||||||
void getAuxLowerBounds(Vector& auxLowerBounds) const; // Return the vector of lower bounds values
|
const Vector& getAuxLowerBounds() const; // Return the vector of lower bounds values
|
||||||
void getAuxUpperBounds(Vector& auxUpperBounds) const; // Return the vector of the upper bounds values
|
const Vector& getAuxUpperBounds() const; // Return the vector of the upper bounds values
|
||||||
double getErrorValue() const; // Return the error value (bias) of the constraint
|
double getErrorValue() const; // Return the error value (bias) of the constraint
|
||||||
|
const Vector& getAuxErrorValues() const; // Return the auxiliary error values
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return the reference to the body 1
|
// Return the reference to the body 1
|
||||||
|
@ -93,12 +94,12 @@ inline bool Constraint::isActive() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the jacobian matrix of body 1
|
// Return the jacobian matrix of body 1
|
||||||
inline Matrix Constraint::getBody1Jacobian() const {
|
inline const Matrix& Constraint::getBody1Jacobian() const {
|
||||||
return body1Jacobian;
|
return body1Jacobian;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the jacobian matrix of body 2
|
// Return the jacobian matrix of body 2
|
||||||
inline Matrix Constraint::getBody2Jacobian() const {
|
inline const Matrix& Constraint::getBody2Jacobian() const {
|
||||||
return body2Jacobian;
|
return body2Jacobian;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +109,7 @@ inline unsigned int Constraint::getNbAuxConstraints() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the auxiliary jacobian matrix
|
// Return the auxiliary jacobian matrix
|
||||||
inline void Constraint::getAuxJacobian(Matrix& auxJacobian) const {
|
inline const Matrix& Constraint::getAuxJacobian() const {
|
||||||
auxJacobian = this->auxJacobian;
|
auxJacobian = this->auxJacobian;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,12 +124,12 @@ inline double Constraint::getUpperBound() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the vector of lower bounds values
|
// Return the vector of lower bounds values
|
||||||
inline void Constraint::getAuxLowerBounds(Vector& auxLowerBounds) const {
|
inline const Vector& Constraint::getAuxLowerBounds() const {
|
||||||
auxLowerBounds = this->auxLowerBounds;
|
auxLowerBounds = this->auxLowerBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the vector of the upper bounds values
|
// Return the vector of the upper bounds values
|
||||||
inline void Constraint::getAuxUpperBounds(Vector& auxUpperBounds) const {
|
inline const Vector& Constraint::getAuxUpperBounds() const {
|
||||||
auxUpperBounds = this->auxUpperBounds;
|
auxUpperBounds = this->auxUpperBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +138,11 @@ inline double Constraint::getErrorValue() const {
|
||||||
return errorValue;
|
return errorValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the auxiliary error values
|
||||||
|
inline const Vector& Constraint::getAuxErrorValues() const {
|
||||||
|
return auxErrorValues;
|
||||||
|
}
|
||||||
|
|
||||||
} // End of the ReactPhysics3D namespace
|
} // End of the ReactPhysics3D namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,10 +24,9 @@
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ConstraintSolver::ConstraintSolver()
|
ConstraintSolver::ConstraintSolver(PhysicsWorld& physicsWorld)
|
||||||
:bodies(0), nbBodies(0), bodyMapping(0) {
|
:physicsWorld(physicsWorld), bodyMapping(0) , lcpSolver(LCPProjectedGaussSeidel(MAX_LCP_ITERATIONS)) {
|
||||||
// Creation of the LCP Solver
|
|
||||||
lcpSolver = new LCPProjectedGaussSeidel(MAX_LCP_ITERATIONS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
@ -36,72 +35,89 @@ ConstraintSolver::~ConstraintSolver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate all the matrices needed to solve the LCP problem
|
// Allocate all the matrices needed to solve the LCP problem
|
||||||
void ConstraintSolver::allocate(std::vector<Constraint*>& constraints, std::vector<Body*>& bodies) {
|
void ConstraintSolver::allocate() {
|
||||||
unsigned int sizeJacobian = 0;
|
unsigned int nbConstraints = 0;
|
||||||
this->bodies = bodies;
|
nbBodies = physicsWorld.getBodies().size();
|
||||||
this->nbBodies = bodies.size();
|
|
||||||
|
|
||||||
// TODO : Now we keep every bodies of the physics world in the "bodies" std:vector of the constraint solver.
|
// TODO : Now we keep every bodies of the physics world in the "bodies" std:vector of the constraint solver.
|
||||||
// but maybe we could only keep track of the body that are part of some constraints.
|
// but maybe we could only keep track of the body that are part of some constraints.
|
||||||
|
|
||||||
// For each constraint
|
// For each constraint
|
||||||
for (unsigned int i=0; i<constraints.size(); ++i) {
|
for (unsigned int i=0; i<physicsWorld.getConstraints().size(); ++i) {
|
||||||
// Evaluate the constraint
|
// Evaluate the constraint
|
||||||
constraints.at(i)->evaluate(dt);
|
physicsWorld.getConstraints().at(i)->evaluate();
|
||||||
|
|
||||||
// If the constraint is active
|
// If the constraint is active
|
||||||
if (constraints.at(i)->isActive()) {
|
if (physicsWorld.getConstraints().at(i)->isActive()) {
|
||||||
activeConstraints.push_back(constraints.at(i));
|
activeConstraints.push_back(physicsWorld.getConstraints().at(i));
|
||||||
|
|
||||||
/Description/ Update the size of the jacobian matrix
|
// Update the size of the jacobian matrix
|
||||||
sizeJacobian += (1 + constraints.at(i)->getNbAuxConstraints());
|
nbConstraints += (1 + physicsWorld.getConstraints().at(i)->getNbAuxConstraints());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate all the vectors and matrices
|
bodyMapping = new Body**[nbConstraints];
|
||||||
J_sp = Matrix(sizeJacobian, 12);
|
for (unsigned int i=0; i<nbConstraints; i++) {
|
||||||
|
bodyMapping[i] = new Body*[2];
|
||||||
bodyMapping = new unsigned int[nbBodies];
|
|
||||||
for (unsigned int i=0; i<nbBodies; i++) {
|
|
||||||
bodyMapping[i] = new unsigned int[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errorVector = Vector(sizeJacobian);
|
J_sp = Matrix(nbConstraints, 12);
|
||||||
B_sp = Matrix(6*nbBodies, 2;
|
errorValues = Vector(nbConstraints);
|
||||||
b = Vector(totalSize);
|
B_sp = Matrix(12, nbConstraints);
|
||||||
lambda = Vector(totalSize);
|
b = Vector(nbConstraints);
|
||||||
lowLimits = Vector(totalSize);
|
lambda = Vector(nbConstraints);
|
||||||
highLimits = Vector(totalSize);
|
lowerBounds = Vector(nbConstraints);
|
||||||
Minv_sp = Matrix(3*nbBodies, 6*nbBodies);
|
upperBounds = Vector(nbConstraints);
|
||||||
|
Minv_sp = Matrix(6*nbBodies, 6);
|
||||||
V = Vector(6*nbBodies);
|
V = Vector(6*nbBodies);
|
||||||
Fc = Vector(6*nbBodies);
|
Fext = Vector(6*nbBodies);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in all the matrices needed to solve the LCP problem
|
// Fill in all the matrices needed to solve the LCP problem
|
||||||
// Notice that all the active constraints should have been evaluated first
|
// Notice that all the active constraints should have been evaluated first
|
||||||
void ConstraintSolver::fillInMatrices() {
|
void ConstraintSolver::fillInMatrices() {
|
||||||
int i,j;
|
|
||||||
|
|
||||||
// For each active constraint
|
// For each active constraint
|
||||||
for (unsigned int c=0; c<activeConstraints.size(); ++c) {
|
for (unsigned int c=0; c<activeConstraints.size(); c++) {
|
||||||
i = activeConstraints.at(c)->getJacobianIndex();
|
Constraint* constraint = activeConstraints.at(c);
|
||||||
//j = i + activeConstraint.at(c)->getNbJacobianRows();
|
|
||||||
J.fillInSubMatrix(i, 0, activeConstraints.at(c)->getBody1LinearJacobian());
|
// Fill in the J_sp matrix
|
||||||
J.fillInSubMatrix(i, 3, activeConstraints.at(c)->getBody2LinearJacobian());
|
J_sp.fillInSubMatrix(c, 0, constraint->getBody1Jacobian());
|
||||||
J.fillInSubMatrix(i, 6, activeConstraints.at(c)->getBody1AngularJacobian());
|
J_sp.fillInSubMatrix(c, 6, constraint->getBody2Jacobian());
|
||||||
J.fillInSubMatrix(i, 9, activeConstraints.at(c)->getBody2AngularJacobian());
|
|
||||||
errorVector.fillInSubVector(i, activeConstraints.at(c)->getErrorVector());
|
// Fill in the body mapping matrix
|
||||||
|
bodyMapping[c][0] = constraint->getBody1();
|
||||||
|
bodyMapping[c][1] = constraint->getBody2();
|
||||||
|
|
||||||
|
// Fill in the limit vectors for the constraint
|
||||||
|
lowerBounds.fillInSubVector(c, constraint->getLowerBound());
|
||||||
|
upperBounds.fillInSubVector(c, constraint->getUpperBound());
|
||||||
|
|
||||||
|
// Fill in the error vector
|
||||||
|
errorValues.fillInSubVector(c, constraint->getErrorValue());
|
||||||
|
|
||||||
|
unsigned int nbAuxConstraints = constraint->getNbAuxConstraints();
|
||||||
|
|
||||||
|
// If the current constraint has auxiliary constraints
|
||||||
|
if (nbAuxConstraints > 0) {
|
||||||
|
// Fill in the J_sp matrix
|
||||||
|
J_sp.fillInSubMatrix(c+1, 0, constraint->getAuxJacobian());
|
||||||
|
|
||||||
|
// For each auxiliary constraints
|
||||||
|
for (unsigned int i=1; i<nbAuxConstraints; i++) {
|
||||||
|
// Fill in the body mapping matrix
|
||||||
|
bodyMapping[c+i][0] = constraint->getBody1();
|
||||||
|
bodyMapping[c+i][1] = constraint->getBody2();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in the limit vectors for the auxilirary constraints
|
||||||
|
lowerBounds.fillInSubVector(c+1, constraint->getAuxLowerBounds());
|
||||||
|
upperBounds.fillInSubVector(c+1, constraint->getAuxUpperBounds());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each active constraint
|
// For each current body of the physics world
|
||||||
for (unsigned int c=0; c<activeConstraints.size(); ++c) {
|
for (unsigned int b=0; b<physicsWorld->getBodies().size(); b++) {
|
||||||
i = activeConstraints.at(c)->getNbAuxiliaryVars();
|
|
||||||
// TODO : add activeConstraints.at(c)->getAuxiliaryRowsAndCols(..., ...)
|
|
||||||
b.fillInSubVector(i, activeConstraints.at(c)->getRightHandSideVector());
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each current body of the simulation
|
|
||||||
for (unsigned int b=0; b<nbBodies; ++b) {
|
|
||||||
i = 6*b;
|
i = 6*b;
|
||||||
Minv.fillInSubMatrix(i, 0, bodies.at(b)->getCurrentBodyState().getMassInverse().getValue() * Matrix::identity(3));
|
Minv.fillInSubMatrix(i, 0, bodies.at(b)->getCurrentBodyState().getMassInverse().getValue() * Matrix::identity(3));
|
||||||
Minv.fillInSubMatrix(i+3, 3, bodies.at(b)->getCurrentBodyState().getInertiaTensorInverse());
|
Minv.fillInSubMatrix(i+3, 3, bodies.at(b)->getCurrentBodyState().getInertiaTensorInverse());
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "../constraint/Constraint.h"
|
#include "../constraint/Constraint.h"
|
||||||
|
#include "PhysicsWorld.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
// ReactPhysics3D namespace
|
// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
@ -37,11 +39,12 @@ const unsigned int MAX_LCP_ITERATIONS = 10; // Maximum number of iterations
|
||||||
*/
|
*/
|
||||||
class ConstraintSolver {
|
class ConstraintSolver {
|
||||||
protected:
|
protected:
|
||||||
LCPSolver* lcpSolver; // LCP Solver
|
LCPSolver& lcpSolver; // LCP Solver
|
||||||
|
PhysicsWorld& physicsWorld; // Reference to the physics world
|
||||||
std::vector<Constraint*> activeConstraints; // Current active constraints in the physics world
|
std::vector<Constraint*> activeConstraints; // Current active constraints in the physics world
|
||||||
std::vector<Body*> bodies; // Set of bodies in the physics world
|
unsigned int nbBodies; // Current number of bodies in the physics world
|
||||||
unsigned int nbBodies; // Number of bodies in the physics world
|
std::map<Body*, unsigned int> bodyNumberMapping; // Map a body pointer with its index number
|
||||||
unsigned int** bodyMapping // 2-dimensional array that contains the mapping of body index
|
Body** bodyMapping; // 2-dimensional array that contains the mapping of body reference
|
||||||
// in the J_sp and B_sp matrices. For instance the cell bodyMapping[i][j] contains
|
// in the J_sp and B_sp matrices. For instance the cell bodyMapping[i][j] contains
|
||||||
// the integer index of the body that correspond to the 1x6 J_ij matrix in the
|
// the integer index of the body that correspond to the 1x6 J_ij matrix in the
|
||||||
// J_sp matrix. A integer body index refers to its index in the "bodies" std::vector
|
// J_sp matrix. A integer body index refers to its index in the "bodies" std::vector
|
||||||
|
@ -49,13 +52,13 @@ class ConstraintSolver {
|
||||||
Matrix B_sp; // Useful matrix in sparse representation
|
Matrix B_sp; // Useful matrix in sparse representation
|
||||||
Vector b; // Vector "b" of the LCP problem
|
Vector b; // Vector "b" of the LCP problem
|
||||||
Vector lambda; // Lambda vector of the LCP problem
|
Vector lambda; // Lambda vector of the LCP problem
|
||||||
Vector errorVector; // Error vector of all constraints
|
Vector errorValues; // Error vector of all constraints
|
||||||
Vector lowLimits; // Vector that contains the low limits of the LCP problem
|
Vector lowerBounds; // Vector that contains the low limits for the variables of the LCP problem
|
||||||
Vector highLimits; // Vector that contains the high limits of the LCP problem
|
Vector upperBounds; // Vector that contains the high limits for the variables of the LCP problem
|
||||||
Matrix Minv_sp; // Sparse representation of the Matrix that contains information about mass and inertia of each body
|
Matrix Minv_sp; // Sparse representation of the Matrix that contains information about mass and inertia of each body
|
||||||
Vector V; // Vector that contains internal linear and angular velocities of each body
|
Vector V; // Vector that contains linear and angular velocities of each body
|
||||||
Vector Fc; // Vector that contains internal forces and torques of each body due to constraints
|
Vector Fext; // Vector that contains external forces and torques of each body
|
||||||
void allocate(std::vector<Constraint*>& constraints); // Allocate all the matrices needed to solve the LCP problem
|
void allocate(); // Allocate all the matrices needed to solve the LCP problem
|
||||||
void fillInMatrices(); // Fill in all the matrices needed to solve the LCP problem
|
void fillInMatrices(); // Fill in all the matrices needed to solve the LCP problem
|
||||||
void freeMemory(); // Free the memory that was allocated in the allocate() method
|
void freeMemory(); // Free the memory that was allocated in the allocate() method
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
PhysicsEngine::PhysicsEngine(PhysicsWorld* world, const Time& timeStep) throw (std::invalid_argument)
|
PhysicsEngine::PhysicsEngine(PhysicsWorld* world, const Time& timeStep) throw (std::invalid_argument)
|
||||||
: world(world), timer(Time(0.0), timeStep) {
|
: world(world), timer(Time(0.0), timeStep), collisionDetection(world) {
|
||||||
// Check if the pointer to the world is not NULL
|
// Check if the pointer to the world is not NULL
|
||||||
if (world == 0) {
|
if (world == 0) {
|
||||||
// Throw an exception
|
// Throw an exception
|
||||||
|
@ -87,11 +87,8 @@ void PhysicsEngine::updateCollision() {
|
||||||
// While the time accumulator is not empty
|
// While the time accumulator is not empty
|
||||||
while(timer.getAccumulator() >= timer.getTimeStep().getValue()) {
|
while(timer.getAccumulator() >= timer.getTimeStep().getValue()) {
|
||||||
|
|
||||||
// Remove all old collision contact constraints
|
|
||||||
world->removeAllContactConstraints();
|
|
||||||
|
|
||||||
// Compute the collision detection
|
// Compute the collision detection
|
||||||
if (collisionDetection.computeCollisionDetection(world)) {
|
if (collisionDetection.computeCollisionDetection()) {
|
||||||
|
|
||||||
// TODO : Delete this ----------------------------------------------------------
|
// TODO : Delete this ----------------------------------------------------------
|
||||||
for (std::vector<Constraint*>::const_iterator it = world->getConstraintListStartIterator(); it != world->getConstraintListEndIterator(); ++it) {
|
for (std::vector<Constraint*>::const_iterator it = world->getConstraintListStartIterator(); it != world->getConstraintListEndIterator(); ++it) {
|
||||||
|
|
|
@ -40,8 +40,8 @@ namespace reactphysics3d {
|
||||||
*/
|
*/
|
||||||
class PhysicsWorld {
|
class PhysicsWorld {
|
||||||
protected :
|
protected :
|
||||||
std::vector<Body*> bodyList; // list that contains all bodies of the physics world
|
std::vector<Body*> bodies; // list that contains all bodies of the physics world
|
||||||
std::vector<Constraint*> constraintList; // List that contains all the current constraints
|
std::vector<Constraint*> constraints; // List that contains all the current constraints
|
||||||
Vector3D gravity; // Gravity vector of the world
|
Vector3D gravity; // Gravity vector of the world
|
||||||
bool isGravityOn; // True if the gravity force is on
|
bool isGravityOn; // True if the gravity force is on
|
||||||
|
|
||||||
|
@ -61,6 +61,8 @@ class PhysicsWorld {
|
||||||
void removeAllContactConstraints(); // Remove all collision contacts constraints
|
void removeAllContactConstraints(); // Remove all collision contacts constraints
|
||||||
std::vector<Constraint*>::const_iterator getConstraintListStartIterator() const; // Return a start iterator on the constraint list
|
std::vector<Constraint*>::const_iterator getConstraintListStartIterator() const; // Return a start iterator on the constraint list
|
||||||
std::vector<Constraint*>::const_iterator getConstraintListEndIterator() const; // Return a end iterator on the constraint list
|
std::vector<Constraint*>::const_iterator getConstraintListEndIterator() const; // Return a end iterator on the constraint list
|
||||||
|
std::vector<Body*>& getBodies() const; // Return a reference to the bodies of the physics world
|
||||||
|
std::vector<Constraint*>& getConstraints() const; // Return a reference to the constraints of the physics world
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Inline functions --- //
|
// --- Inline functions --- //
|
||||||
|
@ -73,13 +75,13 @@ inline Vector3D PhysicsWorld::getGravity() const {
|
||||||
// Return a start iterator on the body list
|
// Return a start iterator on the body list
|
||||||
inline std::vector<Body*>::const_iterator PhysicsWorld::getBodyListStartIterator() const {
|
inline std::vector<Body*>::const_iterator PhysicsWorld::getBodyListStartIterator() const {
|
||||||
// Return an iterator on the start of the body list
|
// Return an iterator on the start of the body list
|
||||||
return bodyList.begin();
|
return bodies.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a end iterator on the body list
|
// Return a end iterator on the body list
|
||||||
inline std::vector<Body*>::const_iterator PhysicsWorld::getBodyListEndIterator() const {
|
inline std::vector<Body*>::const_iterator PhysicsWorld::getBodyListEndIterator() const {
|
||||||
// Return an iterator on the end of the body list
|
// Return an iterator on the end of the body list
|
||||||
return bodyList.end();
|
return bodies.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return if the gravity is on
|
// Return if the gravity is on
|
||||||
|
@ -94,12 +96,22 @@ inline void PhysicsWorld::setIsGratityOn(bool isGravityOn) {
|
||||||
|
|
||||||
// Return a start iterator on the constraint list
|
// Return a start iterator on the constraint list
|
||||||
inline std::vector<Constraint*>::const_iterator PhysicsWorld::getConstraintListStartIterator() const {
|
inline std::vector<Constraint*>::const_iterator PhysicsWorld::getConstraintListStartIterator() const {
|
||||||
return constraintList.begin();
|
return constraints.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a end iterator on the constraint list
|
// Return a end iterator on the constraint list
|
||||||
inline std::vector<Constraint*>::const_iterator PhysicsWorld::getConstraintListEndIterator() const {
|
inline std::vector<Constraint*>::const_iterator PhysicsWorld::getConstraintListEndIterator() const {
|
||||||
return constraintList.end();
|
return constraints.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a reference to the bodies of the physics world
|
||||||
|
std::vector<Body*>& PhysicsWorld::getBodies() const {
|
||||||
|
return bodies;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a reference to the constraints of the physics world
|
||||||
|
std::vector<Constraint*>& PhysicsWorld::getConstraints() const {
|
||||||
|
return constraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of the ReactPhysics3D namespace
|
} // End of the ReactPhysics3D namespace
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
// Namespace ReactPhysics3D
|
// Namespace ReactPhysics3D
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
|
// TODO : Now we are using the "Time" class in this class but we should a
|
||||||
|
// time class from the standard library
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
/* -------------------------------------------------------------------
|
||||||
Class Timer :
|
Class Timer :
|
||||||
This class will take care of the time in the physics engine.
|
This class will take care of the time in the physics engine.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user