Changes and optimizations in the Vector3 and Matrix3x3 classes

git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@437 92aac97c-a6ce-11dd-a772-7fcde58d38e6
This commit is contained in:
chappuis.daniel 2011-08-18 21:02:48 +00:00
parent 03557bbff6
commit 40ec21b398
52 changed files with 826 additions and 814 deletions

View File

@ -43,10 +43,10 @@ namespace reactphysics3d {
*/ */
class RigidBody : public Body { class RigidBody : public Body {
protected : protected :
Vector3D linearVelocity; // Linear velocity of the body Vector3 linearVelocity; // Linear velocity of the body
Vector3D angularVelocity; // Angular velocity of the body Vector3 angularVelocity; // Angular velocity of the body
Vector3D externalForce; // Current external force on the body Vector3 externalForce; // Current external force on the body
Vector3D externalTorque; // Current external torque on the body Vector3 externalTorque; // Current external torque on the body
Matrix3x3 inertiaTensorLocal; // Local inertia tensor of the body (in body coordinates) Matrix3x3 inertiaTensorLocal; // Local inertia tensor of the body (in body coordinates)
Matrix3x3 inertiaTensorLocalInverse; // Inverse of the inertia tensor of the body (in body coordinates) Matrix3x3 inertiaTensorLocalInverse; // Inverse of the inertia tensor of the body (in body coordinates)
double massInverse; // Inverse of the mass of the body double massInverse; // Inverse of the mass of the body
@ -57,15 +57,15 @@ class RigidBody : public Body {
const Matrix3x3& inertiaTensorLocal, Shape* shape); // Constructor // Copy-constructor const Matrix3x3& inertiaTensorLocal, Shape* shape); // Constructor // Copy-constructor
virtual ~RigidBody(); // Destructor virtual ~RigidBody(); // Destructor
Vector3D getLinearVelocity() const; // Return the linear velocity Vector3 getLinearVelocity() const; // Return the linear velocity
void setLinearVelocity(const Vector3D& linearVelocity); // Set the linear velocity of the body void setLinearVelocity(const Vector3& linearVelocity); // Set the linear velocity of the body
Vector3D getAngularVelocity() const; // Return the angular velocity Vector3 getAngularVelocity() const; // Return the angular velocity
void setAngularVelocity(const Vector3D& angularVelocity); // Set the angular velocity void setAngularVelocity(const Vector3& angularVelocity); // Set the angular velocity
void setMassInverse(double massInverse); // Set the inverse of the mass void setMassInverse(double massInverse); // Set the inverse of the mass
Vector3D getExternalForce() const; // Return the current external force of the body Vector3 getExternalForce() const; // Return the current external force of the body
void setExternalForce(const Vector3D& force); // Set the current external force on the body void setExternalForce(const Vector3& force); // Set the current external force on the body
Vector3D getExternalTorque() const; // Return the current external torque of the body Vector3 getExternalTorque() const; // Return the current external torque of the body
void setExternalTorque(const Vector3D& torque); // Set the current external torque of the body void setExternalTorque(const Vector3& torque); // Set the current external torque of the body
double getMassInverse() const; // Return the inverse of the mass of the body double getMassInverse() const; // Return the inverse of the mass of the body
Matrix3x3 getInertiaTensorLocal() const; // Return the local inertia tensor of the body (in body coordinates) Matrix3x3 getInertiaTensorLocal() const; // Return the local inertia tensor of the body (in body coordinates)
void setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal); // Set the local inertia tensor of the body (in body coordinates) void setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal); // Set the local inertia tensor of the body (in body coordinates)
@ -78,16 +78,16 @@ class RigidBody : public Body {
}; };
// Return the linear velocity // Return the linear velocity
inline Vector3D RigidBody::getLinearVelocity() const { inline Vector3 RigidBody::getLinearVelocity() const {
return linearVelocity; return linearVelocity;
} }
// Return the angular velocity of the body // Return the angular velocity of the body
inline Vector3D RigidBody::getAngularVelocity() const { inline Vector3 RigidBody::getAngularVelocity() const {
return angularVelocity; return angularVelocity;
} }
inline void RigidBody::setAngularVelocity(const Vector3D& angularVelocity) { inline void RigidBody::setAngularVelocity(const Vector3& angularVelocity) {
this->angularVelocity = angularVelocity; this->angularVelocity = angularVelocity;
} }
@ -102,22 +102,22 @@ inline Matrix3x3 RigidBody::getInertiaTensorLocalInverse() const {
} }
// Return the external force on the body // Return the external force on the body
inline Vector3D RigidBody::getExternalForce() const { inline Vector3 RigidBody::getExternalForce() const {
return externalForce; return externalForce;
} }
// Set the external force on the body // Set the external force on the body
inline void RigidBody::setExternalForce(const Vector3D& force) { inline void RigidBody::setExternalForce(const Vector3& force) {
this->externalForce = force; this->externalForce = force;
} }
// Return the current external torque on the body // Return the current external torque on the body
inline Vector3D RigidBody::getExternalTorque() const { inline Vector3 RigidBody::getExternalTorque() const {
return externalTorque; return externalTorque;
} }
// Set the current external torque on the body // Set the current external torque on the body
inline void RigidBody::setExternalTorque(const Vector3D& torque) { inline void RigidBody::setExternalTorque(const Vector3& torque) {
this->externalTorque = torque; this->externalTorque = torque;
} }
@ -155,7 +155,7 @@ inline Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const {
} }
// Set the linear velocity of the rigid body // Set the linear velocity of the rigid body
inline void RigidBody::setLinearVelocity(const Vector3D& linearVelocity) { inline void RigidBody::setLinearVelocity(const Vector3& linearVelocity) {
// If the body is able to move // If the body is able to move
if (isMotionEnabled) { if (isMotionEnabled) {
// Update the linear velocity of the current body state // Update the linear velocity of the current body state

View File

@ -29,14 +29,14 @@ using namespace reactphysics3d;
// Constructor for SAT // Constructor for SAT
// TODO : DELETE THIS // TODO : DELETE THIS
ContactInfo::ContactInfo(Body* body1, Body* body2, const Vector3D& normal, double penetrationDepth) ContactInfo::ContactInfo(Body* body1, Body* body2, const Vector3& normal, double penetrationDepth)
: body1(body1), body2(body2), normal(normal), penetrationDepth(penetrationDepth), point1(0.0, 0.0, 0.0), point2(0.0, 0.0, 0.0) { : body1(body1), body2(body2), normal(normal), penetrationDepth(penetrationDepth), point1(0.0, 0.0, 0.0), point2(0.0, 0.0, 0.0) {
} }
// Constructor for GJK // Constructor for GJK
ContactInfo::ContactInfo(Body* body1, Body* body2, const Vector3D& normal, ContactInfo::ContactInfo(Body* body1, Body* body2, const Vector3& normal,
double penetrationDepth, const Vector3D& point1, const Vector3D& point2) double penetrationDepth, const Vector3& point1, const Vector3& point2)
: body1(body1), body2(body2), normal(normal), penetrationDepth(penetrationDepth), point1(point1), point2(point2) { : body1(body1), body2(body2), normal(normal), penetrationDepth(penetrationDepth), point1(point1), point2(point2) {
} }

View File

@ -44,15 +44,15 @@ struct ContactInfo {
public: public:
Body* const body1; // Pointer to the first body of the contact Body* const body1; // Pointer to the first body of the contact
Body* const body2; // Pointer to the second body of the contact Body* const body2; // Pointer to the second body of the contact
const Vector3D point1; // Contact point of body 1 const Vector3 point1; // Contact point of body 1
const Vector3D point2; // Contact point of body 2 const Vector3 point2; // Contact point of body 2
const Vector3D normal; // Normal vector the the collision contact const Vector3 normal; // Normal vector the the collision contact
const double penetrationDepth; // Penetration depth of the contact const double penetrationDepth; // Penetration depth of the contact
ContactInfo(Body* body1, Body* body2, const Vector3D& normal, ContactInfo(Body* body1, Body* body2, const Vector3& normal,
double penetrationDepth); // Constructor for SAT double penetrationDepth); // Constructor for SAT
ContactInfo(Body* body1, Body* body2, const Vector3D& normal, ContactInfo(Body* body1, Body* body2, const Vector3& normal,
double penetrationDepth, const Vector3D& point1, const Vector3D& point2); // Constructor for GJK double penetrationDepth, const Vector3& point1, const Vector3& point2); // Constructor for GJK
}; };
} // End of the ReactPhysics3D namespace } // End of the ReactPhysics3D namespace

View File

@ -43,28 +43,28 @@ 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 Vector3D& p1, const Vector3D& p2, const Vector3D& p3, const Vector3D& p4) const { int EPAAlgorithm::isOriginInTetrahedron(const Vector3& p1, const Vector3& p2, const Vector3& p3, const Vector3& p4) const {
// Check vertex 1 // Check vertex 1
Vector3D normal1 = (p2-p1).cross(p3-p1); Vector3 normal1 = (p2-p1).cross(p3-p1);
if (normal1.dot(p1) > 0.0 == normal1.dot(p4) > 0.0) { if (normal1.dot(p1) > 0.0 == normal1.dot(p4) > 0.0) {
return 4; return 4;
} }
// Check vertex 2 // Check vertex 2
Vector3D normal2 = (p4-p2).cross(p3-p2); Vector3 normal2 = (p4-p2).cross(p3-p2);
if (normal2.dot(p2) > 0.0 == normal2.dot(p1) > 0.0) { if (normal2.dot(p2) > 0.0 == normal2.dot(p1) > 0.0) {
return 1; return 1;
} }
// Check vertex 3 // Check vertex 3
Vector3D normal3 = (p4-p3).cross(p1-p3); Vector3 normal3 = (p4-p3).cross(p1-p3);
if (normal3.dot(p3) > 0.0 == normal3.dot(p2) > 0.0) { if (normal3.dot(p3) > 0.0 == normal3.dot(p2) > 0.0) {
return 2; return 2;
} }
// Check vertex 4 // Check vertex 4
Vector3D normal4 = (p2-p4).cross(p1-p4); Vector3 normal4 = (p2-p4).cross(p1-p4);
if (normal4.dot(p4) > 0.0 == normal4.dot(p3) > 0.0) { if (normal4.dot(p4) > 0.0 == normal4.dot(p3) > 0.0) {
return 3; return 3;
} }
@ -81,10 +81,10 @@ int EPAAlgorithm::isOriginInTetrahedron(const Vector3D& p1, const Vector3D& p2,
// the correct penetration depth // the correct penetration depth
bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, const Shape* shape1, const Transform& transform1, bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, const Shape* shape1, const Transform& transform1,
const Shape* shape2, const Transform& transform2, const Shape* shape2, const Transform& transform2,
Vector3D& v, ContactInfo*& contactInfo) { Vector3& v, ContactInfo*& contactInfo) {
Vector3D suppPointsA[MAX_SUPPORT_POINTS]; // Support points of object A in local coordinates Vector3 suppPointsA[MAX_SUPPORT_POINTS]; // Support points of object A in local coordinates
Vector3D suppPointsB[MAX_SUPPORT_POINTS]; // Support points of object B in local coordinates Vector3 suppPointsB[MAX_SUPPORT_POINTS]; // Support points of object B in local coordinates
Vector3D points[MAX_SUPPORT_POINTS]; // Current points Vector3 points[MAX_SUPPORT_POINTS]; // Current points
TrianglesStore triangleStore; // Store the triangles TrianglesStore triangleStore; // Store the triangles
TriangleEPA* triangleHeap[MAX_FACETS]; // Heap that contains the face candidate of the EPA algorithm TriangleEPA* triangleHeap[MAX_FACETS]; // Heap that contains the face candidate of the EPA algorithm
@ -125,7 +125,7 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
// v1, v2 and v3. // v1, v2 and v3.
// Direction of the segment // Direction of the segment
Vector3D d = (points[1] - points[0]).getUnit(); Vector3 d = (points[1] - points[0]).getUnit();
// Choose the coordinate axis from the minimal absolute component of the vector d // Choose the coordinate axis from the minimal absolute component of the vector d
int minAxis = d.getAbsoluteVector().getMinAxis(); int minAxis = d.getAbsoluteVector().getMinAxis();
@ -141,23 +141,23 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
Matrix3x3 rotationMat = rotationQuat.getMatrix(); Matrix3x3 rotationMat = rotationQuat.getMatrix();
// Compute the vector v1, v2, v3 // Compute the vector v1, v2, v3
Vector3D v1 = d.cross(Vector3D(minAxis == 0, minAxis == 1, minAxis == 2)); Vector3 v1 = d.cross(Vector3(minAxis == 0, minAxis == 1, minAxis == 2));
Vector3D v2 = rotationMat * v1; Vector3 v2 = rotationMat * v1;
Vector3D v3 = rotationMat * v2; Vector3 v3 = rotationMat * v2;
// Compute the support point in the direction of v1 // Compute the support point in the direction of v1
suppPointsA[2] = shape1->getLocalSupportPoint(v1, OBJECT_MARGIN); suppPointsA[2] = shape1->getLocalSupportPoint(v1, OBJECT_MARGIN);
suppPointsB[2] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v1.getOpposite(), OBJECT_MARGIN); suppPointsB[2] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * (-v1), OBJECT_MARGIN);
points[2] = suppPointsA[2] - suppPointsB[2]; points[2] = suppPointsA[2] - suppPointsB[2];
// Compute the support point in the direction of v2 // Compute the support point in the direction of v2
suppPointsA[3] = shape1->getLocalSupportPoint(v2, OBJECT_MARGIN); suppPointsA[3] = shape1->getLocalSupportPoint(v2, OBJECT_MARGIN);
suppPointsB[3] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v2.getOpposite(), OBJECT_MARGIN); suppPointsB[3] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * (-v2), OBJECT_MARGIN);
points[3] = suppPointsA[3] - suppPointsB[3]; points[3] = suppPointsA[3] - suppPointsB[3];
// Compute the support point in the direction of v3 // Compute the support point in the direction of v3
suppPointsA[4] = shape1->getLocalSupportPoint(v3, OBJECT_MARGIN); suppPointsA[4] = shape1->getLocalSupportPoint(v3, OBJECT_MARGIN);
suppPointsB[4] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v3.getOpposite(), OBJECT_MARGIN); suppPointsB[4] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * (-v3), OBJECT_MARGIN);
points[4] = suppPointsA[4] - suppPointsB[4]; points[4] = suppPointsA[4] - suppPointsB[4];
// Now we have an hexahedron (two tetrahedron glued together). We can simply keep the // Now we have an hexahedron (two tetrahedron glued together). We can simply keep the
@ -246,15 +246,15 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
// normal of the triangle. // normal of the triangle.
// Compute the normal of the triangle // Compute the normal of the triangle
Vector3D v1 = points[1] - points[0]; Vector3 v1 = points[1] - points[0];
Vector3D v2 = points[2] - points[0]; Vector3 v2 = points[2] - points[0];
Vector3D n = v1.cross(v2); Vector3 n = v1.cross(v2);
// Compute the two new vertices to obtain a hexahedron // Compute the two new vertices to obtain a hexahedron
suppPointsA[3] = shape1->getLocalSupportPoint(n, OBJECT_MARGIN); suppPointsA[3] = shape1->getLocalSupportPoint(n, OBJECT_MARGIN);
suppPointsB[3] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * n.getOpposite(), OBJECT_MARGIN); suppPointsB[3] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * (-n), OBJECT_MARGIN);
points[3] = suppPointsA[3] - suppPointsB[3]; points[3] = suppPointsA[3] - suppPointsB[3];
suppPointsA[4] = shape1->getLocalSupportPoint(n.getOpposite(), OBJECT_MARGIN); suppPointsA[4] = shape1->getLocalSupportPoint(-n, OBJECT_MARGIN);
suppPointsB[4] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * n, OBJECT_MARGIN); suppPointsB[4] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * n, OBJECT_MARGIN);
points[4] = suppPointsA[4] - suppPointsB[4]; points[4] = suppPointsA[4] - suppPointsB[4];
@ -325,7 +325,7 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
// Compute the support point of the Minkowski difference (A-B) in the closest point direction // Compute the support point of the Minkowski difference (A-B) in the closest point direction
suppPointsA[nbVertices] = shape1->getLocalSupportPoint(triangle->getClosestPoint(), OBJECT_MARGIN); suppPointsA[nbVertices] = shape1->getLocalSupportPoint(triangle->getClosestPoint(), OBJECT_MARGIN);
suppPointsB[nbVertices] = shape2ToShape1 *shape2->getLocalSupportPoint(rotateToShape2 * triangle->getClosestPoint().getOpposite(), OBJECT_MARGIN); suppPointsB[nbVertices] = shape2ToShape1 *shape2->getLocalSupportPoint(rotateToShape2 * (-triangle->getClosestPoint()), OBJECT_MARGIN);
points[nbVertices] = suppPointsA[nbVertices] - suppPointsB[nbVertices]; points[nbVertices] = suppPointsA[nbVertices] - suppPointsB[nbVertices];
int indexNewVertex = nbVertices; int indexNewVertex = nbVertices;
@ -368,9 +368,9 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
// Compute the contact info (in world-space) // Compute the contact info (in world-space)
v = transform1.getOrientation().getMatrix() * triangle->getClosestPoint(); v = transform1.getOrientation().getMatrix() * triangle->getClosestPoint();
Vector3D pA = transform1 * triangle->computeClosestPointOfObject(suppPointsA); Vector3 pA = transform1 * triangle->computeClosestPointOfObject(suppPointsA);
Vector3D pB = transform1 * triangle->computeClosestPointOfObject(suppPointsB); Vector3 pB = transform1 * triangle->computeClosestPointOfObject(suppPointsB);
Vector3D normal = v.getUnit(); Vector3 normal = v.getUnit();
double penetrationDepth = v.length(); double penetrationDepth = v.length();
assert(penetrationDepth > 0.0); assert(penetrationDepth > 0.0);
contactInfo = new ContactInfo(shape1->getBodyPointer(), shape2->getBodyPointer(), normal, penetrationDepth, pA, pB); contactInfo = new ContactInfo(shape1->getBodyPointer(), shape2->getBodyPointer(), normal, penetrationDepth, pA, pB);

View File

@ -75,8 +75,8 @@ class EPAAlgorithm {
void addFaceCandidate(TriangleEPA* triangle, TriangleEPA** heap, void addFaceCandidate(TriangleEPA* triangle, TriangleEPA** heap,
uint& nbTriangles, double upperBoundSquarePenDepth); // Add a triangle face in the candidate triangle heap uint& nbTriangles, double upperBoundSquarePenDepth); // Add a triangle face in the candidate triangle heap
int isOriginInTetrahedron(const Vector3D& p1, const Vector3D& p2, int isOriginInTetrahedron(const Vector3& p1, const Vector3& p2,
const Vector3D& p3, const Vector3D& p4) const; // Decide if the origin is in the tetrahedron const Vector3& p3, const Vector3& p4) const; // Decide if the origin is in the tetrahedron
public: public:
EPAAlgorithm(); // Constructor EPAAlgorithm(); // Constructor
@ -84,7 +84,7 @@ class EPAAlgorithm {
bool computePenetrationDepthAndContactPoints(Simplex simplex, const Shape* shape1, const Transform& transform1, bool computePenetrationDepthAndContactPoints(Simplex simplex, const Shape* shape1, const Transform& transform1,
const Shape* shape2, const Transform& transform2, const Shape* shape2, const Transform& transform2,
Vector3D& v, ContactInfo*& contactInfo); // Compute the penetration depth with EPA algorithm Vector3& v, ContactInfo*& contactInfo); // Compute the penetration depth with EPA algorithm
}; };
// Add a triangle face in the candidate triangle heap in the EPA algorithm // Add a triangle face in the candidate triangle heap in the EPA algorithm

View File

@ -59,7 +59,7 @@ uint EdgeEPA::getTargetVertexIndex() const {
} }
// Execute the recursive silhouette algorithm from this edge // Execute the recursive silhouette algorithm from this edge
bool EdgeEPA::computeSilhouette(const Vector3D* vertices, uint indexNewVertex, TrianglesStore& triangleStore) { bool EdgeEPA::computeSilhouette(const Vector3* vertices, uint indexNewVertex, TrianglesStore& triangleStore) {
// If the edge has not already been visited // If the edge has not already been visited
if (!ownerTriangle->getIsObsolete()) { if (!ownerTriangle->getIsObsolete()) {
// If the triangle of this edge is not visible from the given point // If the triangle of this edge is not visible from the given point

View File

@ -56,7 +56,7 @@ class EdgeEPA {
int getIndex() const; // Return the index of the edge in the triangle int getIndex() const; // Return the index of the edge in the triangle
uint getSourceVertexIndex() const; // Return index of the source vertex of the edge uint getSourceVertexIndex() const; // Return index of the source vertex of the edge
uint getTargetVertexIndex() const; // Return the index of the target vertex of the edge uint getTargetVertexIndex() const; // Return the index of the target vertex of the edge
bool computeSilhouette(const Vector3D* vertices, uint index, bool computeSilhouette(const Vector3* vertices, uint index,
TrianglesStore& triangleStore); // Execute the recursive silhouette algorithm from this edge TrianglesStore& triangleStore); // Execute the recursive silhouette algorithm from this edge
}; };

View File

@ -50,11 +50,11 @@ TriangleEPA::~TriangleEPA() {
} }
// Compute the point v closest to the origin of this triangle // Compute the point v closest to the origin of this triangle
bool TriangleEPA::computeClosestPoint(const Vector3D* vertices) { bool TriangleEPA::computeClosestPoint(const Vector3* vertices) {
const Vector3D& p0 = vertices[indicesVertices[0]]; const Vector3& p0 = vertices[indicesVertices[0]];
Vector3D v1 = vertices[indicesVertices[1]] - p0; Vector3 v1 = vertices[indicesVertices[1]] - p0;
Vector3D v2 = vertices[indicesVertices[2]] - p0; Vector3 v2 = vertices[indicesVertices[2]] - p0;
double v1Dotv1 = v1.dot(v1); double v1Dotv1 = v1.dot(v1);
double v1Dotv2 = v1.dot(v2); double v1Dotv2 = v1.dot(v2);
double v2Dotv2 = v2.dot(v2); double v2Dotv2 = v2.dot(v2);
@ -118,7 +118,7 @@ void reactphysics3d::halfLink(const EdgeEPA& edge0, const EdgeEPA& edge1) {
// are seen and faces that are not seen from the new vertex. This method starts from the nearest face from the new vertex, // 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 order that we always have a convex polytope. The // 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 obselete and will not be considered as being a candidate face in the future. // faces visible from the new vertex are set obselete and will not be considered as being a candidate face in the future.
bool TriangleEPA::computeSilhouette(const Vector3D* vertices, uint indexNewVertex, TrianglesStore& triangleStore) { bool TriangleEPA::computeSilhouette(const Vector3* vertices, uint indexNewVertex, TrianglesStore& triangleStore) {
uint first = triangleStore.getNbTriangles(); uint first = triangleStore.getNbTriangles();

View File

@ -51,7 +51,7 @@ class TriangleEPA {
EdgeEPA adjacentEdges[3]; // Three adjacent edges of the triangle (edges of other triangles) EdgeEPA adjacentEdges[3]; // Three adjacent edges of the triangle (edges of other triangles)
bool isObsolete; // True if the triangle face is visible from the new support point bool isObsolete; // True if the triangle face is visible from the new support point
double det; // Determinant double det; // Determinant
Vector3D closestPoint; // Point v closest to the origin on the affine hull of the triangle Vector3 closestPoint; // Point v closest to the origin on the affine hull of the triangle
double lambda1; // Lambda1 value such that v = lambda0 * y_0 + lambda1 * y_1 + lambda2 * y_2 double lambda1; // Lambda1 value such that v = lambda0 * y_0 + lambda1 * y_1 + lambda2 * y_2
double lambda2; // Lambda1 value such that v = lambda0 * y_0 + lambda1 * y_1 + lambda2 * y_2 double lambda2; // Lambda1 value such that v = lambda0 * y_0 + lambda1 * y_1 + lambda2 * y_2
double distSquare; // Square distance of the point closest point v to the origin double distSquare; // Square distance of the point closest point v to the origin
@ -66,12 +66,12 @@ class TriangleEPA {
double getDistSquare() const; // Return the square distance of the closest point to origin double getDistSquare() const; // Return the square distance of the closest point to origin
void setIsObsolete(bool isObsolete); // Set the isObsolete value void setIsObsolete(bool isObsolete); // Set the isObsolete value
bool getIsObsolete() const; // Return true if the triangle face is obsolete bool getIsObsolete() const; // Return true if the triangle face is obsolete
const Vector3D& getClosestPoint() const; // Return the point closest to the origin const Vector3& getClosestPoint() const; // Return the point closest to the origin
bool isClosestPointInternalToTriangle() const; // Return true if the closest point on affine hull is inside the triangle bool isClosestPointInternalToTriangle() const; // Return true if the closest point on affine hull is inside the triangle
bool isVisibleFromVertex(const Vector3D* vertices, uint index) const; // Return true if the triangle is visible from a given vertex bool isVisibleFromVertex(const Vector3* vertices, uint index) const; // Return true if the triangle is visible from a given vertex
bool computeClosestPoint(const Vector3D* vertices); // Compute the point v closest to the origin of this triangle bool computeClosestPoint(const Vector3* vertices); // Compute the point v closest to the origin of this triangle
Vector3D computeClosestPointOfObject(const Vector3D* supportPointsOfObject) const; // Compute the point of an object closest to the origin Vector3 computeClosestPointOfObject(const Vector3* supportPointsOfObject) const; // Compute the point of an object closest to the origin
bool computeSilhouette(const Vector3D* vertices, uint index, bool computeSilhouette(const Vector3* vertices, uint index,
TrianglesStore& triangleStore); // Execute the recursive silhouette algorithm from this triangle face TrianglesStore& triangleStore); // Execute the recursive silhouette algorithm from this triangle face
uint operator[](int i) const; // Access operator uint operator[](int i) const; // Access operator
@ -107,7 +107,7 @@ inline bool TriangleEPA::getIsObsolete() const {
} }
// Return the point closest to the origin // Return the point closest to the origin
inline const Vector3D& TriangleEPA::getClosestPoint() const { inline const Vector3& TriangleEPA::getClosestPoint() const {
return closestPoint; return closestPoint;
} }
@ -117,14 +117,14 @@ inline bool TriangleEPA::isClosestPointInternalToTriangle() const {
} }
// Return true if the triangle is visible from a given vertex // Return true if the triangle is visible from a given vertex
inline bool TriangleEPA::isVisibleFromVertex(const Vector3D* vertices, uint index) const { inline bool TriangleEPA::isVisibleFromVertex(const Vector3* vertices, uint index) const {
Vector3D closestToVert = vertices[index] - closestPoint; Vector3 closestToVert = vertices[index] - closestPoint;
return (closestPoint.dot(closestToVert) > 0.0); return (closestPoint.dot(closestToVert) > 0.0);
} }
// Compute the point of an object closest to the origin // Compute the point of an object closest to the origin
inline Vector3D TriangleEPA::computeClosestPointOfObject(const Vector3D* supportPointsOfObject) const { inline Vector3 TriangleEPA::computeClosestPointOfObject(const Vector3* supportPointsOfObject) const {
const Vector3D& p0 = supportPointsOfObject[indicesVertices[0]]; const Vector3& p0 = supportPointsOfObject[indicesVertices[0]];
return p0 + 1.0/det * (lambda1 * (supportPointsOfObject[indicesVertices[1]] - p0) + return p0 + 1.0/det * (lambda1 * (supportPointsOfObject[indicesVertices[1]] - p0) +
lambda2 * (supportPointsOfObject[indicesVertices[2]] - p0)); lambda2 * (supportPointsOfObject[indicesVertices[2]] - p0));
} }

View File

@ -58,7 +58,7 @@ class TrianglesStore {
void setNbTriangles(int backup); // Set the number of triangles void setNbTriangles(int backup); // Set the number of triangles
TriangleEPA& last(); // Return the last triangle TriangleEPA& last(); // Return the last triangle
TriangleEPA* newTriangle(const Vector3D* vertices, uint v0, uint v1, uint v2); // Create a new triangle TriangleEPA* newTriangle(const Vector3* vertices, uint v0, uint v1, uint v2); // Create a new triangle
TriangleEPA& operator[](int i); // Access operator TriangleEPA& operator[](int i); // Access operator
}; };
@ -85,7 +85,7 @@ inline TriangleEPA& TrianglesStore::last() {
} }
// Create a new triangle // Create a new triangle
inline TriangleEPA* TrianglesStore::newTriangle(const Vector3D* vertices, uint v0, uint v1, uint v2) { inline TriangleEPA* TrianglesStore::newTriangle(const Vector3* vertices, uint v0, uint v1, uint v2) {
TriangleEPA* newTriangle = 0; TriangleEPA* newTriangle = 0;
// If we have not reach the maximum number of triangles // If we have not reach the maximum number of triangles

View File

@ -62,11 +62,11 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
assert(shape1 != shape2); assert(shape1 != shape2);
Vector3D suppA; // Support point of object A Vector3 suppA; // Support point of object A
Vector3D suppB; // Support point of object B Vector3 suppB; // Support point of object B
Vector3D w; // Support point of Minkowski difference A-B Vector3 w; // Support point of Minkowski difference A-B
Vector3D pA; // Closest point of object A Vector3 pA; // Closest point of object A
Vector3D pB; // Closest point of object B Vector3 pB; // Closest point of object B
double vDotw; double vDotw;
double prevDistSquare; double prevDistSquare;
Body* const body1 = shape1->getBodyPointer(); Body* const body1 = shape1->getBodyPointer();
@ -89,14 +89,14 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
// Get the last point V (last separating axis) // Get the last point V (last separating axis)
// TODO : Implement frame coherence. For each pair of body, store // TODO : Implement frame coherence. For each pair of body, store
// the last separating axis and use it to initialize the v vector // the last separating axis and use it to initialize the v vector
Vector3D v(1.0, 1.0, 1.0); Vector3 v(1.0, 1.0, 1.0);
// Initialize the upper bound for the square distance // Initialize the upper bound for the square distance
double distSquare = DBL_MAX; double distSquare = DBL_MAX;
do { do {
// Compute the support points for original objects (without margins) A and B // Compute the support points for original objects (without margins) A and B
suppA = shape1->getLocalSupportPoint(v.getOpposite()); suppA = shape1->getLocalSupportPoint(-v);
suppB = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v); suppB = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v);
// Compute the support point for the Minkowski difference A-B // Compute the support point for the Minkowski difference A-B
@ -123,7 +123,7 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
pB = transform1 * (pB + (OBJECT_MARGIN / dist) * v); pB = transform1 * (pB + (OBJECT_MARGIN / dist) * v);
// Compute the contact info // Compute the contact info
Vector3D normal = transform1.getOrientation().getMatrix() * v.getOpposite().getUnit(); Vector3 normal = transform1.getOrientation().getMatrix() * (-v.getUnit());
double penetrationDepth = margin - dist; double penetrationDepth = margin - dist;
contactInfo = new ContactInfo(body1, body2, normal, penetrationDepth, pA, pB); contactInfo = new ContactInfo(body1, body2, normal, penetrationDepth, pA, pB);
@ -147,7 +147,7 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
pB = transform1 * (pB + (OBJECT_MARGIN / dist) * v); pB = transform1 * (pB + (OBJECT_MARGIN / dist) * v);
// Compute the contact info // Compute the contact info
Vector3D normal = transform1.getOrientation().getMatrix() * v.getOpposite().getUnit(); Vector3 normal = transform1.getOrientation().getMatrix() * (-v.getUnit());
double penetrationDepth = margin - dist; double penetrationDepth = margin - dist;
contactInfo = new ContactInfo(body1, body2, normal, penetrationDepth, pA, pB); contactInfo = new ContactInfo(body1, body2, normal, penetrationDepth, pA, pB);
@ -169,7 +169,7 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
pB = transform1 * (pB + (OBJECT_MARGIN / dist) * v); pB = transform1 * (pB + (OBJECT_MARGIN / dist) * v);
// Compute the contact info // Compute the contact info
Vector3D normal = transform1.getOrientation().getMatrix() * v.getOpposite().getUnit(); Vector3 normal = transform1.getOrientation().getMatrix() * (-v.getUnit());
double penetrationDepth = margin - dist; double penetrationDepth = margin - dist;
contactInfo = new ContactInfo(body1, body2, normal, penetrationDepth, pA, pB); contactInfo = new ContactInfo(body1, body2, normal, penetrationDepth, pA, pB);
@ -179,14 +179,14 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
// Store and update the squared distance of the closest point // Store and update the squared distance of the closest point
prevDistSquare = distSquare; prevDistSquare = distSquare;
distSquare = v.dot(v); distSquare = v.lengthSquare();
// If the distance to the closest point doesn't improve a lot // If the distance to the closest point doesn't improve a lot
if (prevDistSquare - distSquare <= MACHINE_EPSILON * prevDistSquare) { if (prevDistSquare - distSquare <= MACHINE_EPSILON * prevDistSquare) {
simplex.backupClosestPointInSimplex(v); simplex.backupClosestPointInSimplex(v);
// Get the new squared distance // Get the new squared distance
distSquare = v.dot(v); distSquare = v.lengthSquare();
// Compute the closet points of both objects (without the margins) // Compute the closet points of both objects (without the margins)
simplex.computeClosestPointsOfAandB(pA, pB); simplex.computeClosestPointsOfAandB(pA, pB);
@ -199,7 +199,7 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
pB = transform1 * (pB + (OBJECT_MARGIN / dist) * v); pB = transform1 * (pB + (OBJECT_MARGIN / dist) * v);
// Compute the contact info // Compute the contact info
Vector3D normal = transform1.getOrientation().getMatrix() * v.getOpposite().getUnit(); Vector3 normal = transform1.getOrientation().getMatrix() * (-v.getUnit());
double penetrationDepth = margin - dist; double penetrationDepth = margin - dist;
contactInfo = new ContactInfo(body1, body2, normal, penetrationDepth, pA, pB); contactInfo = new ContactInfo(body1, body2, normal, penetrationDepth, pA, pB);
@ -222,11 +222,11 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
// 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 Shape* const shape1, const Transform& transform1, bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(const Shape* const shape1, const Transform& transform1,
const Shape* const shape2, const Transform& transform2, const Shape* const shape2, const Transform& transform2,
ContactInfo*& contactInfo, Vector3D& v) { ContactInfo*& contactInfo, Vector3& v) {
Simplex simplex; Simplex simplex;
Vector3D suppA; Vector3 suppA;
Vector3D suppB; Vector3 suppB;
Vector3D w; Vector3 w;
double vDotw; double vDotw;
double distSquare = DBL_MAX; double distSquare = DBL_MAX;
double prevDistSquare; double prevDistSquare;
@ -239,7 +239,7 @@ bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(const Shape* const
do { do {
// Compute the support points for the enlarged object A and B // Compute the support points for the enlarged object A and B
suppA = shape1->getLocalSupportPoint(v.getOpposite(), OBJECT_MARGIN); suppA = shape1->getLocalSupportPoint(-v, OBJECT_MARGIN);
suppB = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v, OBJECT_MARGIN); suppB = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v, OBJECT_MARGIN);
// Compute the support point for the Minkowski difference A-B // Compute the support point for the Minkowski difference A-B
@ -266,7 +266,7 @@ bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(const Shape* const
// Store and update the square distance // Store and update the square distance
prevDistSquare = distSquare; prevDistSquare = distSquare;
distSquare = v.dot(v); distSquare = v.lengthSquare();
if (prevDistSquare - distSquare <= MACHINE_EPSILON * prevDistSquare) { if (prevDistSquare - distSquare <= MACHINE_EPSILON * prevDistSquare) {
return false; return false;

View File

@ -63,7 +63,7 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm {
bool computePenetrationDepthForEnlargedObjects(const Shape* shape1, const Transform& transform1, bool computePenetrationDepthForEnlargedObjects(const Shape* shape1, const Transform& transform1,
const Shape* shape2, const Transform& transform2, const Shape* shape2, const Transform& transform2,
ContactInfo*& contactInfo, Vector3D& v); // Compute the penetration depth for enlarged objects ContactInfo*& contactInfo, Vector3& v); // Compute the penetration depth for enlarged objects
public : public :
GJKAlgorithm(); // Constructor GJKAlgorithm(); // Constructor

View File

@ -43,7 +43,7 @@ Simplex::~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 Vector3D& point, const Vector3D& suppPointA, const Vector3D& suppPointB) { void Simplex::addPoint(const Vector3& point, const Vector3& suppPointA, const Vector3& suppPointB) {
assert(!isFull()); assert(!isFull());
lastFound = 0; lastFound = 0;
@ -75,7 +75,7 @@ void Simplex::addPoint(const Vector3D& point, const Vector3D& suppPointA, const
} }
// Return true if the point is in the simplex // Return true if the point is in the simplex
bool Simplex::isPointInSimplex(const Vector3D& point) const { bool Simplex::isPointInSimplex(const Vector3& point) const {
int i; int i;
Bits bit; Bits bit;
@ -100,7 +100,7 @@ void Simplex::updateCache() {
// Compute the distance between two points in the possible simplex set // Compute the distance between two points in the possible simplex set
diffLength[i][lastFound] = points[i] - points[lastFound]; diffLength[i][lastFound] = points[i] - points[lastFound];
diffLength[lastFound][i] = diffLength[i][lastFound].getOpposite(); diffLength[lastFound][i] = -diffLength[i][lastFound];
// Compute the squared length of the vector distances from points in the possible simplex set // Compute the squared length of the vector distances from points in the possible simplex set
normSquare[i][lastFound] = normSquare[lastFound][i] = diffLength[i][lastFound].dot(diffLength[i][lastFound]); normSquare[i][lastFound] = normSquare[lastFound][i] = diffLength[i][lastFound].dot(diffLength[i][lastFound]);
@ -109,7 +109,7 @@ void Simplex::updateCache() {
} }
// Return the points of the simplex // Return the points of the simplex
unsigned int Simplex::getSimplex(Vector3D* suppPointsA, Vector3D* suppPointsB, Vector3D* points) const { unsigned int Simplex::getSimplex(Vector3* suppPointsA, Vector3* suppPointsB, Vector3* points) const {
unsigned int nbVertices = 0; unsigned int nbVertices = 0;
int i; int i;
Bits bit; Bits bit;
@ -271,7 +271,7 @@ bool Simplex::isValidSubset(Bits subset) const {
// 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(Vector3D& pA, Vector3D& pB) const { void Simplex::computeClosestPointsOfAandB(Vector3& pA, Vector3& pB) const {
double deltaX = 0.0; double deltaX = 0.0;
pA.setAllValues(0.0, 0.0, 0.0); pA.setAllValues(0.0, 0.0, 0.0);
pB.setAllValues(0.0, 0.0, 0.0); pB.setAllValues(0.0, 0.0, 0.0);
@ -283,22 +283,22 @@ void Simplex::computeClosestPointsOfAandB(Vector3D& pA, Vector3D& pB) const {
// If the current point is part of the simplex // If the current point is part of the simplex
if (overlap(bitsCurrentSimplex, bit)) { if (overlap(bitsCurrentSimplex, bit)) {
deltaX += det[bitsCurrentSimplex][i]; deltaX += det[bitsCurrentSimplex][i];
pA = pA + det[bitsCurrentSimplex][i] * suppPointsA[i]; pA += det[bitsCurrentSimplex][i] * suppPointsA[i];
pB = pB + det[bitsCurrentSimplex][i] * suppPointsB[i]; pB += det[bitsCurrentSimplex][i] * suppPointsB[i];
} }
} }
assert(deltaX > 0.0); assert(deltaX > 0.0);
double factor = 1.0 / deltaX; double factor = 1.0 / deltaX;
pA = factor * pA; pA *= factor;
pB = factor * pB; 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(Vector3D& v) { bool Simplex::computeClosestPoint(Vector3& v) {
Bits subset; Bits subset;
// For each possible simplex set // For each possible simplex set
@ -325,13 +325,13 @@ bool Simplex::computeClosestPoint(Vector3D& v) {
} }
// Backup the closest point // Backup the closest point
void Simplex::backupClosestPointInSimplex(Vector3D& v) { void Simplex::backupClosestPointInSimplex(Vector3& v) {
double minDistSquare = DBL_MAX; double minDistSquare = DBL_MAX;
Bits bit; Bits bit;
for (bit = allBits; bit != 0x0; bit--) { for (bit = allBits; bit != 0x0; bit--) {
if (isSubset(bit, allBits) && isProperSubset(bit)) { if (isSubset(bit, allBits) && isProperSubset(bit)) {
Vector3D u = computeClosestPointForSubset(bit); Vector3 u = computeClosestPointForSubset(bit);
double distSquare = u.dot(u); double distSquare = u.dot(u);
if (distSquare < minDistSquare) { if (distSquare < minDistSquare) {
minDistSquare = distSquare; minDistSquare = distSquare;
@ -344,8 +344,8 @@ void Simplex::backupClosestPointInSimplex(Vector3D& v) {
// Return the closest point "v" in the convex hull of the points in the subset // Return the closest point "v" in the convex hull of the points in the subset
// represented by the bits "subset" // represented by the bits "subset"
Vector3D Simplex::computeClosestPointForSubset(Bits subset) { Vector3 Simplex::computeClosestPointForSubset(Bits subset) {
Vector3D v(0.0, 0.0, 0.0); // Closet point v = sum(lambda_i * points[i]) Vector3 v(0.0, 0.0, 0.0); // Closet point v = sum(lambda_i * points[i])
maxLengthSquare = 0.0; maxLengthSquare = 0.0;
double deltaX = 0.0; // deltaX = sum of all det[subset][i] double deltaX = 0.0; // deltaX = sum of all det[subset][i]
int i; int i;
@ -363,7 +363,7 @@ Vector3D Simplex::computeClosestPointForSubset(Bits subset) {
} }
// Closest point v = sum(lambda_i * points[i]) // Closest point v = sum(lambda_i * points[i])
v = v + det[subset][i] * points[i]; v += det[subset][i] * points[i];
} }
} }

View File

@ -47,12 +47,12 @@ typedef unsigned int Bits;
*/ */
class Simplex { class Simplex {
private: private:
Vector3D points[4]; // Current points Vector3 points[4]; // Current points
double pointsLengthSquare[4]; // pointsLengthSquare[i] = (points[i].length)^2 double pointsLengthSquare[4]; // pointsLengthSquare[i] = (points[i].length)^2
double maxLengthSquare; // Maximum length of pointsLengthSquare[i] double maxLengthSquare; // Maximum length of pointsLengthSquare[i]
Vector3D suppPointsA[4]; // Support points of object A in local coordinates Vector3 suppPointsA[4]; // Support points of object A in local coordinates
Vector3D suppPointsB[4]; // Support points of object B in local coordinates Vector3 suppPointsB[4]; // Support points of object B in local coordinates
Vector3D diffLength[4][4]; // diff[i][j] contains points[i] - points[j] Vector3 diffLength[4][4]; // diff[i][j] contains points[i] - points[j]
double det[16][4]; // Cached determinant values double det[16][4]; // Cached determinant values
double normSquare[4][4]; // norm[i][j] = (diff[i][j].length())^2 double normSquare[4][4]; // norm[i][j] = (diff[i][j].length())^2
Bits bitsCurrentSimplex; // 4 bits that identify the current points of the simplex Bits bitsCurrentSimplex; // 4 bits that identify the current points of the simplex
@ -67,7 +67,7 @@ class Simplex {
bool isProperSubset(Bits subset) const; // Return true if the subset is a proper subset bool isProperSubset(Bits subset) const; // Return true if the subset is a proper subset
void updateCache(); // Update the cached values used during the GJK algorithm void updateCache(); // Update the cached values used during the GJK algorithm
void computeDeterminants(); // Compute the cached determinant values void computeDeterminants(); // Compute the cached determinant values
Vector3D computeClosestPointForSubset(Bits subset); // Return the closest point "v" in the convex hull of a subset of points Vector3 computeClosestPointForSubset(Bits subset); // Return the closest point "v" in the convex hull of a subset of points
public: public:
Simplex(); // Constructor Simplex(); // Constructor
@ -75,14 +75,14 @@ class Simplex {
bool isFull() const; // Return true if the simplex contains 4 points bool isFull() const; // Return true if the simplex contains 4 points
bool isEmpty() const; // Return true if the simple is empty bool isEmpty() const; // Return true if the simple is empty
unsigned int getSimplex(Vector3D* suppPointsA, Vector3D* suppPointsB, Vector3D* points) const; // Return the points of the simplex unsigned int getSimplex(Vector3* suppPointsA, Vector3* suppPointsB, Vector3* points) const; // Return the points of the simplex
double getMaxLengthSquareOfAPoint() const; // Return the maximum squared length of a point double getMaxLengthSquareOfAPoint() const; // Return the maximum squared length of a point
void addPoint(const Vector3D& point, const Vector3D& suppPointA, const Vector3D& suppPointB); // Addd a point to the simplex void addPoint(const Vector3& point, const Vector3& suppPointA, const Vector3& suppPointB); // Addd a point to the simplex
bool isPointInSimplex(const Vector3D& point) const; // Return true if the point is in the simplex bool isPointInSimplex(const Vector3& point) const; // Return true if the point is in the simplex
bool isAffinelyDependent() const; // Return true if the set is affinely dependent bool isAffinelyDependent() const; // Return true if the set is affinely dependent
void backupClosestPointInSimplex(Vector3D& point); // Backup the closest point void backupClosestPointInSimplex(Vector3& point); // Backup the closest point
void computeClosestPointsOfAandB(Vector3D& pA, Vector3D& pB) const; // Compute the closest points of object A and B void computeClosestPointsOfAandB(Vector3& pA, Vector3& pB) const; // Compute the closest points of object A and B
bool computeClosestPoint(Vector3D& v); // Compute the closest point to the origin of the current simplex bool computeClosestPoint(Vector3& v); // Compute the closest point to the origin of the current 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"

View File

@ -84,7 +84,7 @@ void SAPAlgorithm::computePossibleCollisionPairs(vector<Body*> addedBodies, vect
double esperanceSquare[] = {0.0, 0.0, 0.0}; // Esperance of the square of the distribution values of the AABBs on the three x, y and z axis double esperanceSquare[] = {0.0, 0.0, 0.0}; // Esperance of the square of the distribution values of the AABBs on the three x, y and z axis
vector<const AABB*>::iterator it; // Iterator on the sortedAABBs set vector<const AABB*>::iterator it; // Iterator on the sortedAABBs set
vector<const AABB*>::iterator it2; // Second iterator vector<const AABB*>::iterator it2; // Second iterator
Vector3D center3D; // Center of the current AABB Vector3 center3D; // Center of the current AABB
double center[3]; // Coordinates of the center of the current AABB double center[3]; // Coordinates of the center of the current AABB
int i; int i;
const Body* body; // Body pointer on the body corresponding to an AABB const Body* body; // Body pointer on the body corresponding to an AABB
@ -123,7 +123,7 @@ void SAPAlgorithm::computePossibleCollisionPairs(vector<Body*> addedBodies, vect
// Test collision against all possible overlapping AABBs following the current one // Test collision against all possible overlapping AABBs following the current one
for (it2 = it + 1; it2 != sortedAABBs.end(); ++it2) { for (it2 = it + 1; it2 != sortedAABBs.end(); ++it2) {
// Stop when the tested AABBs are beyond the end of the current AABB // Stop when the tested AABBs are beyond the end of the current AABB
if ((*it2)->getMinCoordinates().getValue(sortAxis) > (*it)->getMaxCoordinates().getValue(sortAxis)) { if ((*it2)->getMinCoordinates()[sortAxis] > (*it)->getMaxCoordinates()[sortAxis]) {
break; break;
} }

View File

@ -72,7 +72,7 @@ class SAPAlgorithm : public BroadPhaseAlgorithm {
// sorting axis (sortAxis) is smaller than the minimum value of "b" on this same // sorting axis (sortAxis) is smaller than the minimum value of "b" on this same
// axis. // axis.
inline bool SAPAlgorithm::compareAABBs(const AABB* a, const AABB* b) { inline bool SAPAlgorithm::compareAABBs(const AABB* a, const AABB* b) {
return (a->getMinCoordinates().getValue(sortAxis) < b->getMinCoordinates().getValue(sortAxis)); return (a->getMinCoordinates()[sortAxis] < b->getMinCoordinates()[sortAxis]);
} }
} // End of reactphysics3d namespace } // End of reactphysics3d namespace

View File

@ -92,7 +92,7 @@ bool SATAlgorithm::computeCollisionTest(const BoxShape* obb1, const Transform& t
double max1; // Maximum of interval 1 double max1; // Maximum of interval 1
double min2; // Minimm of interval 2 double min2; // Minimm of interval 2
double max2; // Maximum of interval 2 double max2; // Maximum of interval 2
Vector3D normal; // Contact normal (correspond to the separation axis with the smallest positive penetration depth) Vector3 normal; // Contact normal (correspond to the separation axis with the smallest positive penetration depth)
// The contact normal point out of OBB1 toward OBB2 // The contact normal point out of OBB1 toward OBB2
double minPenetrationDepth = DBL_MAX; // Minimum penetration depth detected among all separated axis double minPenetrationDepth = DBL_MAX; // Minimum penetration depth detected among all separated axis
const double cutoff = 0.99; // Cutoff for cosine of angles between box axes const double cutoff = 0.99; // Cutoff for cosine of angles between box axes
@ -109,7 +109,7 @@ bool SATAlgorithm::computeCollisionTest(const BoxShape* obb1, const Transform& t
double udc2[3]; // DotProduct(obb2.Ai, obb2.center - obb1.center) double udc2[3]; // DotProduct(obb2.Ai, obb2.center - obb1.center)
//Vector3D boxDistance = obb2->getCenter() - obb1->getCenter(); // Vector between the centers of the OBBs //Vector3D boxDistance = obb2->getCenter() - obb1->getCenter(); // Vector between the centers of the OBBs
Vector3D boxDistance = transform2.getPosition() - transform1.getPosition(); // Vector between the centers of the OBBs Vector3 boxDistance = transform2.getPosition() - transform1.getPosition(); // Vector between the centers of the OBBs
// Axis A0 // Axis A0
for (int i=0; i<3; ++i) { for (int i=0; i<3; ++i) {

View File

@ -54,7 +54,7 @@ class SATAlgorithm : public NarrowPhaseAlgorithm {
const BoxShape* obb2, const Transform& transform2, const BoxShape* obb2, const Transform& transform2,
ContactInfo*& contactInfo) const; // Return true and compute a contact info if the two OBB collide 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) const; // Compute the penetration depth of two projection intervals double computePenetrationDepth(double min1, double max1, double min2, double max2) const; // Compute the penetration depth of two projection intervals
Vector3D computeContactNormal(const Vector3D& axis, const Vector3D& distanceOfOBBs) const; // Compute a contact normal Vector3 computeContactNormal(const Vector3& axis, const Vector3& distanceOfOBBs) const; // Compute a contact normal
public : public :
SATAlgorithm(); // Constructor SATAlgorithm(); // Constructor
@ -65,12 +65,12 @@ class SATAlgorithm : public NarrowPhaseAlgorithm {
// Return the contact normal with the correct sign (from obb1 toward obb2). "axis" is the axis vector direction where the // Return the contact normal with the correct sign (from obb1 toward obb2). "axis" is the axis vector direction where the
// collision occurs and "distanceOfOBBs" is the vector (obb2.center - obb1.center). // collision occurs and "distanceOfOBBs" is the vector (obb2.center - obb1.center).
inline Vector3D SATAlgorithm::computeContactNormal(const Vector3D& axis, const Vector3D& distanceOfOBBs) const { inline Vector3 SATAlgorithm::computeContactNormal(const Vector3& axis, const Vector3& distanceOfOBBs) const {
if (distanceOfOBBs.dot(axis) >= 0.0) { if (distanceOfOBBs.dot(axis) >= 0.0) {
return axis; return axis;
} }
else { else {
return axis.getOpposite(); return -axis;
} }
} }

View File

@ -56,14 +56,14 @@ void Contact::computeJacobian(int noConstraint, Matrix1x6**& J_sp) const {
assert(body1); assert(body1);
assert(body2); assert(body2);
Vector3D body1Position = body1->getTransform().getPosition(); Vector3 body1Position = body1->getTransform().getPosition();
Vector3D body2Position = body2->getTransform().getPosition(); Vector3 body2Position = body2->getTransform().getPosition();
int currentIndex = noConstraint; // Current constraint index int currentIndex = noConstraint; // Current constraint index
Vector3D r1 = pointOnBody1 - body1Position; Vector3 r1 = pointOnBody1 - body1Position;
Vector3D r2 = pointOnBody2 - body2Position; Vector3 r2 = pointOnBody2 - body2Position;
Vector3D r1CrossN = r1.cross(normal); Vector3 r1CrossN = r1.cross(normal);
Vector3D r2CrossN = r2.cross(normal); Vector3 r2CrossN = r2.cross(normal);
// Compute the jacobian matrix for the body 1 for the contact constraint // Compute the jacobian matrix for the body 1 for the contact constraint
J_sp[currentIndex][0].setValue(0, -normal.getX()); J_sp[currentIndex][0].setValue(0, -normal.getX());
@ -84,10 +84,10 @@ void Contact::computeJacobian(int noConstraint, Matrix1x6**& J_sp) const {
currentIndex++; currentIndex++;
// Compute the jacobian matrix for the body 1 for the first friction constraint // Compute the jacobian matrix for the body 1 for the first friction constraint
Vector3D r1CrossU1 = r1.cross(frictionVectors[0]); Vector3 r1CrossU1 = r1.cross(frictionVectors[0]);
Vector3D r2CrossU1 = r2.cross(frictionVectors[0]); Vector3 r2CrossU1 = r2.cross(frictionVectors[0]);
Vector3D r1CrossU2 = r1.cross(frictionVectors[1]); Vector3 r1CrossU2 = r1.cross(frictionVectors[1]);
Vector3D r2CrossU2 = r2.cross(frictionVectors[1]); Vector3 r2CrossU2 = r2.cross(frictionVectors[1]);
J_sp[currentIndex][0].setValue(0, -frictionVectors[0].getX()); J_sp[currentIndex][0].setValue(0, -frictionVectors[0].getX());
J_sp[currentIndex][0].setValue(1, -frictionVectors[0].getY()); J_sp[currentIndex][0].setValue(1, -frictionVectors[0].getY());
J_sp[currentIndex][0].setValue(2, -frictionVectors[0].getZ()); J_sp[currentIndex][0].setValue(2, -frictionVectors[0].getZ());
@ -157,8 +157,8 @@ void Contact::computeErrorValue(int noConstraint, Vector& errorValues) const {
assert(noConstraint >= 0 && noConstraint + nbConstraints <= errorValues.getNbComponent()); assert(noConstraint >= 0 && noConstraint + nbConstraints <= errorValues.getNbComponent());
// Compute the error value for the contact constraint // Compute the error value for the contact constraint
Vector3D velocity1 = rigidBody1->getLinearVelocity(); Vector3 velocity1 = rigidBody1->getLinearVelocity();
Vector3D velocity2 = rigidBody2->getLinearVelocity(); Vector3 velocity2 = rigidBody2->getLinearVelocity();
double restitutionCoeff = rigidBody1->getRestitution() * rigidBody2->getRestitution(); double restitutionCoeff = rigidBody1->getRestitution() * rigidBody2->getRestitution();
double errorValue = restitutionCoeff * (normal.dot(velocity1) - normal.dot(velocity2)) + PENETRATION_FACTOR * penetrationDepth; double errorValue = restitutionCoeff * (normal.dot(velocity1) - normal.dot(velocity2)) + PENETRATION_FACTOR * penetrationDepth;

View File

@ -51,11 +51,11 @@ namespace reactphysics3d {
*/ */
class Contact : public Constraint { class Contact : public Constraint {
protected : protected :
const Vector3D normal; // Normal vector of the contact (From body1 toward body2) const Vector3 normal; // Normal vector of the contact (From body1 toward body2)
const double penetrationDepth; // Penetration depth const double penetrationDepth; // Penetration depth
const Vector3D pointOnBody1; // Contact point on body 1 const Vector3 pointOnBody1; // Contact point on body 1
const Vector3D pointOnBody2; // Contact point on body 2 const Vector3 pointOnBody2; // Contact point on body 2
std::vector<Vector3D> frictionVectors; // Two orthogonal vectors that span the tangential friction plane std::vector<Vector3> frictionVectors; // Two orthogonal vectors that span the tangential friction plane
double mu_mc_g; double mu_mc_g;
void computeFrictionVectors(); // Compute the two friction vectors that span the tangential friction plane void computeFrictionVectors(); // Compute the two friction vectors that span the tangential friction plane
@ -64,9 +64,9 @@ class Contact : public Constraint {
Contact(const ContactInfo* contactInfo); // Constructor Contact(const ContactInfo* contactInfo); // Constructor
virtual ~Contact(); // Destructor virtual ~Contact(); // Destructor
Vector3D getNormal() const; // Return the normal vector of the contact Vector3 getNormal() const; // Return the normal vector of the contact
Vector3D getPointOnBody1() const; // Return the contact point on body 1 Vector3 getPointOnBody1() const; // Return the contact point on body 1
Vector3D getPointOnBody2() const; // Return the contact point on body 2 Vector3 getPointOnBody2() const; // Return the contact point on body 2
virtual void computeJacobian(int noConstraint, Matrix1x6**& J_SP) const; // Compute the jacobian matrix for all mathematical constraints virtual void computeJacobian(int noConstraint, Matrix1x6**& J_SP) const; // Compute the jacobian matrix for all mathematical constraints
virtual void computeLowerBound(int noConstraint, Vector& lowerBounds) const; // Compute the lowerbounds values for all the mathematical constraints virtual void computeLowerBound(int noConstraint, Vector& lowerBounds) const; // Compute the lowerbounds values for all the mathematical constraints
virtual void computeUpperBound(int noConstraint, Vector& upperBounds) const; // Compute the upperbounds values for all the mathematical constraints virtual void computeUpperBound(int noConstraint, Vector& upperBounds) const; // Compute the upperbounds values for all the mathematical constraints
@ -84,7 +84,7 @@ inline void Contact::computeFrictionVectors() {
frictionVectors.clear(); frictionVectors.clear();
// Compute the first orthogonal vector // Compute the first orthogonal vector
Vector3D vector1 = normal.getOneOrthogonalVector(); Vector3 vector1 = normal.getOneOrthogonalVector();
frictionVectors.push_back(vector1); frictionVectors.push_back(vector1);
// Compute the second orthogonal vector using the cross product // Compute the second orthogonal vector using the cross product
@ -92,17 +92,17 @@ inline void Contact::computeFrictionVectors() {
} }
// Return the normal vector of the contact // Return the normal vector of the contact
inline Vector3D Contact::getNormal() const { inline Vector3 Contact::getNormal() const {
return normal; return normal;
} }
// Return the contact point on body 1 // Return the contact point on body 1
inline Vector3D Contact::getPointOnBody1() const { inline Vector3 Contact::getPointOnBody1() const {
return pointOnBody1; return pointOnBody1;
} }
// Return the contact point on body 2 // Return the contact point on body 2
inline Vector3D Contact::getPointOnBody2() const { inline Vector3 Contact::getPointOnBody2() const {
return pointOnBody2; return pointOnBody2;
} }

View File

@ -241,25 +241,29 @@ void ConstraintSolver::fillInMatrices() {
// TODO : Use polymorphism and remove this downcasting // TODO : Use polymorphism and remove this downcasting
rigidBody = dynamic_cast<RigidBody*>(body); rigidBody = dynamic_cast<RigidBody*>(body);
assert(rigidBody); assert(rigidBody);
// Compute the vector V1 with initial velocities values // Compute the vector V1 with initial velocities values
V1[bodyNumber].setValue(0, rigidBody->getLinearVelocity().getValue(0)); Vector3 linearVelocity = rigidBody->getLinearVelocity();
V1[bodyNumber].setValue(1, rigidBody->getLinearVelocity().getValue(1)); Vector3 angularVelocity = rigidBody->getAngularVelocity();
V1[bodyNumber].setValue(2, rigidBody->getLinearVelocity().getValue(2)); V1[bodyNumber].setValue(0, linearVelocity[0]);
V1[bodyNumber].setValue(3, rigidBody->getAngularVelocity().getValue(0)); V1[bodyNumber].setValue(1, linearVelocity[1]);
V1[bodyNumber].setValue(4, rigidBody->getAngularVelocity().getValue(1)); V1[bodyNumber].setValue(2, linearVelocity[2]);
V1[bodyNumber].setValue(5, rigidBody->getAngularVelocity().getValue(2)); V1[bodyNumber].setValue(3, angularVelocity[0]);
V1[bodyNumber].setValue(4, angularVelocity[1]);
V1[bodyNumber].setValue(5, angularVelocity[2]);
// Compute the vector Vconstraint with final constraint velocities // Compute the vector Vconstraint with final constraint velocities
Vconstraint[bodyNumber].initWithValue(0.0); Vconstraint[bodyNumber].initWithValue(0.0);
// Compute the vector with forces and torques values // Compute the vector with forces and torques values
Fext[bodyNumber].setValue(0, rigidBody->getExternalForce().getValue(0)); Vector3 externalForce = rigidBody->getExternalForce();
Fext[bodyNumber].setValue(1, rigidBody->getExternalForce().getValue(1)); Vector3 externalTorque = rigidBody->getExternalTorque();
Fext[bodyNumber].setValue(2, rigidBody->getExternalForce().getValue(2)); Fext[bodyNumber].setValue(0, externalForce[0]);
Fext[bodyNumber].setValue(3, rigidBody->getExternalTorque().getValue(0)); Fext[bodyNumber].setValue(1, externalForce[1]);
Fext[bodyNumber].setValue(4, rigidBody->getExternalTorque().getValue(1)); Fext[bodyNumber].setValue(2, externalForce[2]);
Fext[bodyNumber].setValue(5, rigidBody->getExternalTorque().getValue(2)); Fext[bodyNumber].setValue(3, externalTorque[0]);
Fext[bodyNumber].setValue(4, externalTorque[1]);
Fext[bodyNumber].setValue(5, externalTorque[2]);
// Compute the inverse sparse mass matrix // Compute the inverse sparse mass matrix
Minv_sp[bodyNumber].initWithValue(0.0); Minv_sp[bodyNumber].initWithValue(0.0);
@ -351,7 +355,7 @@ void ConstraintSolver::updateContactCache() {
if (contact) { if (contact) {
// Get all the contact points of the contact // Get all the contact points of the contact
vector<Vector3D> points; vector<Vector3> points;
vector<double> lambdas; vector<double> lambdas;
points.push_back(contact->getPointOnBody1()); points.push_back(contact->getPointOnBody1());
points.push_back(contact->getPointOnBody2()); points.push_back(contact->getPointOnBody2());

View File

@ -98,8 +98,8 @@ class ConstraintSolver {
virtual ~ConstraintSolver(); // Destructor virtual ~ConstraintSolver(); // Destructor
void solve(double dt); // Solve the current LCP problem void solve(double dt); // Solve the current LCP problem
bool isConstrainedBody(Body* body) const; // Return true if the body is in at least one constraint bool isConstrainedBody(Body* body) const; // Return true if the body is in at least one constraint
Vector3D getConstrainedLinearVelocityOfBody(Body* body); // Return the constrained linear velocity of a body after solving the LCP problem Vector3 getConstrainedLinearVelocityOfBody(Body* body); // Return the constrained linear velocity of a body after solving the LCP problem
Vector3D getConstrainedAngularVelocityOfBody(Body* body); // Return the constrained angular velocity of a body after solving the LCP problem Vector3 getConstrainedAngularVelocityOfBody(Body* body); // Return the constrained angular velocity of a body after solving the LCP problem
void cleanup(); void cleanup();
}; };
@ -112,18 +112,18 @@ inline bool ConstraintSolver::isConstrainedBody(Body* body) const {
} }
// Return the constrained linear velocity of a body after solving the LCP problem // Return the constrained linear velocity of a body after solving the LCP problem
inline Vector3D ConstraintSolver::getConstrainedLinearVelocityOfBody(Body* body) { inline Vector3 ConstraintSolver::getConstrainedLinearVelocityOfBody(Body* body) {
assert(isConstrainedBody(body)); assert(isConstrainedBody(body));
const Vector6D& vec = Vconstraint[bodyNumberMapping[body]]; const Vector6D& vec = Vconstraint[bodyNumberMapping[body]];
return Vector3D(vec.getValue(0), vec.getValue(1), vec.getValue(2)); return Vector3(vec.getValue(0), vec.getValue(1), vec.getValue(2));
} }
// Return the constrained angular velocity of a body after solving the LCP problem // Return the constrained angular velocity of a body after solving the LCP problem
inline Vector3D ConstraintSolver::getConstrainedAngularVelocityOfBody(Body* body) { inline Vector3 ConstraintSolver::getConstrainedAngularVelocityOfBody(Body* body) {
assert(isConstrainedBody(body)); assert(isConstrainedBody(body));
const Vector6D& vec = Vconstraint[bodyNumberMapping[body]]; const Vector6D& vec = Vconstraint[bodyNumberMapping[body]];
return Vector3D(vec.getValue(3), vec.getValue(4), vec.getValue(5)); return Vector3(vec.getValue(3), vec.getValue(4), vec.getValue(5));
} }
// Cleanup of the constraint solver // Cleanup of the constraint solver

View File

@ -71,7 +71,7 @@ ContactCachingInfo* ContactCache::getContactCachingInfo(Contact* contact) const
posZ = contact->getPointOnBody1().getZ(); posZ = contact->getPointOnBody1().getZ();
// Get the position of the old contact // Get the position of the old contact
Vector3D& contactPos1 = contactInfo->positions[0]; Vector3& contactPos1 = contactInfo->positions[0];
// If the old contact point doesn't match the current one // If the old contact point doesn't match the current one
if (posX > contactPos1.getX() + POSITION_TOLERANCE || posX < contactPos1.getX() - POSITION_TOLERANCE || if (posX > contactPos1.getX() + POSITION_TOLERANCE || posX < contactPos1.getX() - POSITION_TOLERANCE ||
@ -88,7 +88,7 @@ ContactCachingInfo* ContactCache::getContactCachingInfo(Contact* contact) const
posZ = contact->getPointOnBody2().getZ(); posZ = contact->getPointOnBody2().getZ();
// Get the position of the old contact // Get the position of the old contact
Vector3D& contactPos2 = contactInfo->positions[1]; Vector3& contactPos2 = contactInfo->positions[1];
// If the old contact point doesn't match the current one // If the old contact point doesn't match the current one
if (posX > contactPos2.getX() + POSITION_TOLERANCE || posX < contactPos2.getX() - POSITION_TOLERANCE || if (posX > contactPos2.getX() + POSITION_TOLERANCE || posX < contactPos2.getX() - POSITION_TOLERANCE ||

View File

@ -29,7 +29,7 @@ using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
ContactCachingInfo::ContactCachingInfo(Body* body1, Body* body2, const vector<Vector3D>& positions, const vector<double>& lambdas) ContactCachingInfo::ContactCachingInfo(Body* body1, Body* body2, const vector<Vector3>& positions, const vector<double>& lambdas)
: body1(body1), body2(body2), positions(positions), lambdas(lambdas) { : body1(body1), body2(body2), positions(positions), lambdas(lambdas) {
} }

View File

@ -43,10 +43,10 @@ struct ContactCachingInfo {
public: public:
Body* body1; // Body pointer of the first bounding volume Body* body1; // Body pointer of the first bounding volume
Body* body2; // Body pointer of the second bounding volume Body* body2; // Body pointer of the second bounding volume
std::vector<Vector3D> positions; // Positions of the contact points std::vector<Vector3> positions; // Positions of the contact points
std::vector<double> lambdas; // Last lambdas value for the constraint std::vector<double> lambdas; // Last lambdas value for the constraint
ContactCachingInfo(Body* body1, Body* body2, const std::vector<Vector3D>& positions, const std::vector<double>& lambdas); // Constructor ContactCachingInfo(Body* body1, Body* body2, const std::vector<Vector3>& positions, const std::vector<double>& lambdas); // Constructor
}; };
} // End of the ReactPhysics3D namespace } // End of the ReactPhysics3D namespace

View File

@ -30,19 +30,10 @@ using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
PhysicsEngine::PhysicsEngine(PhysicsWorld* world, double timeStep = DEFAULT_TIMESTEP) throw (invalid_argument) PhysicsEngine::PhysicsEngine(PhysicsWorld* world, double timeStep = DEFAULT_TIMESTEP)
: world(world), timer(timeStep), collisionDetection(world), constraintSolver(world) { : world(world), timer(timeStep), collisionDetection(world), constraintSolver(world) {
// Check if the pointer to the world is not NULL assert(world);
if (world == 0) { assert(timeStep > 0.0);
// Throw an exception
throw invalid_argument("Error : The argument world to the PhysicsEngine constructor cannot be NULL");
}
// Check if the timeStep is positive
if (timeStep <= 0.0) {
// Throw an exception
throw invalid_argument("Error : The timeStep argument to the PhysicsEngine constructor have to be greater than zero");
}
} }
// Destructor // Destructor
@ -51,52 +42,46 @@ PhysicsEngine::~PhysicsEngine() {
} }
// Update the physics simulation // Update the physics simulation
void PhysicsEngine::update() throw (logic_error) { void PhysicsEngine::update() {
bool existCollision = false; bool existCollision = false;
// Check that the timer is running assert(timer.getIsRunning());
if (timer.getIsRunning()) {
// Compute the time since the last update() call and update the timer // Compute the time since the last update() call and update the timer
timer.update(); timer.update();
// Apply the gravity force to all bodies // Apply the gravity force to all bodies
applyGravity(); applyGravity();
// While the time accumulator is not empty // While the time accumulator is not empty
while(timer.isPossibleToTakeStep()) { while(timer.isPossibleToTakeStep()) {
existCollision = false; existCollision = false;
// Compute the collision detection
if (collisionDetection.computeCollisionDetection()) {
existCollision = true;
// Solve constraints // Compute the collision detection
constraintSolver.solve(timer.getTimeStep()); if (collisionDetection.computeCollisionDetection()) {
} existCollision = true;
// Update the timer // Solve constraints
timer.nextStep(); constraintSolver.solve(timer.getTimeStep());
// Update the position and orientation of each body
updateAllBodiesMotion();
// Cleanup of the constraint solver
if (existCollision) {
constraintSolver.cleanup();
}
// Clear the added and removed bodies from last update() method call
world->clearAddedAndRemovedBodies();
} }
// Compute and set the interpolation factor to all the bodies // Update the timer
setInterpolationFactorToAllBodies(); timer.nextStep();
}
else { // Call to update() but the timer is not running // Update the position and orientation of each body
// Throw an exception updateAllBodiesMotion();
throw logic_error("Error : The PhysicsEngine::start() method have to be called before calling PhysicsEngine::update()");
// Cleanup of the constraint solver
if (existCollision) {
constraintSolver.cleanup();
}
// Clear the added and removed bodies from last update() method call
world->clearAddedAndRemovedBodies();
} }
// Compute and set the interpolation factor to all the bodies
setInterpolationFactorToAllBodies();
} }
// Compute the motion of all bodies and update their positions and orientations // Compute the motion of all bodies and update their positions and orientations
@ -110,8 +95,8 @@ void PhysicsEngine::update() throw (logic_error) {
// orientation of the body // orientation of the body
void PhysicsEngine::updateAllBodiesMotion() { void PhysicsEngine::updateAllBodiesMotion() {
double dt = timer.getTimeStep(); double dt = timer.getTimeStep();
Vector3D newLinearVelocity; Vector3 newLinearVelocity;
Vector3D newAngularVelocity; Vector3 newAngularVelocity;
// For each body of thephysics world // For each body of thephysics world
for (vector<Body*>::iterator it=world->getBodiesBeginIterator(); it != world->getBodiesEndIterator(); ++it) { for (vector<Body*>::iterator it=world->getBodiesBeginIterator(); it != world->getBodiesEndIterator(); ++it) {
@ -133,12 +118,12 @@ void PhysicsEngine::updateAllBodiesMotion() {
// Compute V_forces = dt * (M^-1 * F_ext) which is the velocity of the body due to the // Compute V_forces = dt * (M^-1 * F_ext) which is the velocity of the body due to the
// external forces and torques. // external forces and torques.
newLinearVelocity = newLinearVelocity + dt * rigidBody->getMassInverse() * rigidBody->getExternalForce(); newLinearVelocity += dt * rigidBody->getMassInverse() * rigidBody->getExternalForce();
newAngularVelocity = newAngularVelocity + dt * rigidBody->getInertiaTensorInverseWorld() * rigidBody->getExternalTorque(); newAngularVelocity += dt * rigidBody->getInertiaTensorInverseWorld() * rigidBody->getExternalTorque();
// Add the velocity V1 to the new velocity // Add the velocity V1 to the new velocity
newLinearVelocity = newLinearVelocity + rigidBody->getLinearVelocity(); newLinearVelocity += rigidBody->getLinearVelocity();
newAngularVelocity = newAngularVelocity + rigidBody->getAngularVelocity(); newAngularVelocity += rigidBody->getAngularVelocity();
// Update the position and the orientation of the body according to the new velocity // Update the position and the orientation of the body according to the new velocity
updatePositionAndOrientationOfBody(*it, newLinearVelocity, newAngularVelocity); updatePositionAndOrientationOfBody(*it, newLinearVelocity, newAngularVelocity);
@ -152,7 +137,7 @@ void PhysicsEngine::updateAllBodiesMotion() {
// Update the position and orientation of a body // Update the position and orientation of a body
// Use the Semi-Implicit Euler (Sympletic Euler) method to compute the new position and the new // Use the Semi-Implicit Euler (Sympletic Euler) method to compute the new position and the new
// orientation of the body // orientation of the body
void PhysicsEngine::updatePositionAndOrientationOfBody(Body* body, const Vector3D& newLinVelocity, const Vector3D& newAngVelocity) { void PhysicsEngine::updatePositionAndOrientationOfBody(Body* body, const Vector3& newLinVelocity, const Vector3& newAngVelocity) {
double dt = timer.getTimeStep(); double dt = timer.getTimeStep();
RigidBody* rigidBody = dynamic_cast<RigidBody*>(body); RigidBody* rigidBody = dynamic_cast<RigidBody*>(body);
@ -166,10 +151,10 @@ void PhysicsEngine::updatePositionAndOrientationOfBody(Body* body, const Vector3
rigidBody->setAngularVelocity(newAngVelocity); rigidBody->setAngularVelocity(newAngVelocity);
// Get current position and orientation of the body // Get current position and orientation of the body
const Vector3D& currentPosition = rigidBody->getTransform().getPosition(); const Vector3& currentPosition = rigidBody->getTransform().getPosition();
const Quaternion& currentOrientation = rigidBody->getTransform().getOrientation(); const Quaternion& currentOrientation = rigidBody->getTransform().getOrientation();
Vector3D newPosition = currentPosition + newLinVelocity * dt; Vector3 newPosition = currentPosition + newLinVelocity * dt;
Quaternion newOrientation = currentOrientation + Quaternion(newAngVelocity.getX(), newAngVelocity.getY(), newAngVelocity.getZ(), 0) * currentOrientation * 0.5 * dt; Quaternion newOrientation = currentOrientation + Quaternion(newAngVelocity.getX(), newAngVelocity.getY(), newAngVelocity.getZ(), 0) * currentOrientation * 0.5 * dt;
Transform newTransform(newPosition, newOrientation.getUnit()); Transform newTransform(newPosition, newOrientation.getUnit());
rigidBody->setTransform(newTransform); rigidBody->setTransform(newTransform);

View File

@ -50,17 +50,17 @@ class PhysicsEngine {
ConstraintSolver constraintSolver; // Constraint solver ConstraintSolver constraintSolver; // Constraint solver
void updateAllBodiesMotion(); // Compute the motion of all bodies and update their positions and orientations void updateAllBodiesMotion(); // Compute the motion of all bodies and update their positions and orientations
void updatePositionAndOrientationOfBody(Body* body, const Vector3D& newLinVelocity, const Vector3D& newAngVelocity); // Update the position and orientation of a body void updatePositionAndOrientationOfBody(Body* body, const Vector3& newLinVelocity, const Vector3& newAngVelocity); // Update the position and orientation of a body
void setInterpolationFactorToAllBodies(); // Compute and set the interpolation factor to all bodies void setInterpolationFactorToAllBodies(); // Compute and set the interpolation factor to all bodies
void applyGravity(); // Apply the gravity force to all bodies void applyGravity(); // Apply the gravity force to all bodies
public : public :
PhysicsEngine(PhysicsWorld* world, double timeStep) throw (std::invalid_argument); // Constructor PhysicsEngine(PhysicsWorld* world, double timeStep); // Constructor
~PhysicsEngine(); // Destructor ~PhysicsEngine(); // Destructor
void start(); // Start the physics simulation void start(); // Start the physics simulation
void stop(); // Stop the physics simulation void stop(); // Stop the physics simulation
void update() throw (std::logic_error); // Update the physics simulation void update(); // Update the physics simulation
}; };
// --- Inline functions --- // // --- Inline functions --- //

View File

@ -31,7 +31,7 @@ using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
PhysicsWorld::PhysicsWorld(const Vector3D& gravity) PhysicsWorld::PhysicsWorld(const Vector3& gravity)
: gravity(gravity), isGravityOn(true) { : gravity(gravity), isGravityOn(true) {
} }

View File

@ -49,17 +49,17 @@ class PhysicsWorld {
std::vector<Body*> addedBodies; // Added bodies since last update std::vector<Body*> addedBodies; // Added bodies since last update
std::vector<Body*> removedBodies; // Removed bodies since last update std::vector<Body*> removedBodies; // Removed bodies since last update
std::vector<Constraint*> constraints; // 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 Vector3 gravity; // Gravity vector of the world
bool isGravityOn; // True if the gravity force is on bool isGravityOn; // True if the gravity force is on
public : public :
PhysicsWorld(const Vector3D& gravity); // Constructor PhysicsWorld(const Vector3& gravity); // Constructor
virtual ~PhysicsWorld(); // Destructor virtual ~PhysicsWorld(); // Destructor
void addBody(Body* body); // Add a body to the physics world void addBody(Body* body); // Add a body to the physics world
void removeBody(Body const* const body); // Remove a body from the physics world void removeBody(Body const* const body); // Remove a body from the physics world
void clearAddedAndRemovedBodies(); // Clear the addedBodies and removedBodies sets void clearAddedAndRemovedBodies(); // Clear the addedBodies and removedBodies sets
Vector3D getGravity() const; // Return the gravity vector of the world Vector3 getGravity() const; // Return the gravity vector of the world
bool getIsGravityOn() const; // Return if the gravity is on bool getIsGravityOn() const; // Return if the gravity is on
void setIsGratityOn(bool isGravityOn); // Set the isGravityOn attribute void setIsGratityOn(bool isGravityOn); // Set the isGravityOn attribute
void addConstraint(Constraint* constraint); // Add a constraint void addConstraint(Constraint* constraint); // Add a constraint
@ -129,7 +129,7 @@ inline void PhysicsWorld::clearAddedAndRemovedBodies() {
} }
// Return the gravity vector of the world // Return the gravity vector of the world
inline Vector3D PhysicsWorld::getGravity() const { inline Vector3 PhysicsWorld::getGravity() const {
return gravity; return gravity;
} }

View File

@ -70,18 +70,5 @@ Matrix3x3 Matrix3x3::getInverse() const {
return (invDeterminant * tempMatrix.getTranspose()); return (invDeterminant * tempMatrix.getTranspose());
} }
// Overloaded operator for assignment
Matrix3x3& Matrix3x3::operator=(const Matrix3x3& matrix2) {
// Check for self-assignment
if (this != &matrix2) {
setAllValues(matrix2.array[0][0], matrix2.array[0][1], matrix2.array[0][2],
matrix2.array[1][0], matrix2.array[1][1], matrix2.array[1][2],
matrix2.array[2][0], matrix2.array[2][1], matrix2.array[2][2]);
}
// Return a reference to the matrix
return *this;
}

View File

@ -28,7 +28,7 @@
// Libraries // Libraries
#include <cassert> #include <cassert>
#include "Vector3D.h" #include "Vector3.h"
// ReactPhysics3D namespace // ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -54,7 +54,7 @@ class Matrix3x3 {
void setValue(int i, int j, double value); // Set a value in the matrix void setValue(int i, int j, double value); // Set a value in the matrix
void setAllValues(double a1, double a2, double a3, double b1, double b2, double b3, void setAllValues(double a1, double a2, double a3, double b1, double b2, double b3,
double c1, double c2, double c3); // Set all the values in the matrix double c1, double c2, double c3); // Set all the values in the matrix
Vector3D getColumn(int i) const; // Return a column Vector3 getColumn(int i) const; // Return a column
Matrix3x3 getTranspose() const; // Return the transpose matrix Matrix3x3 getTranspose() const; // Return the transpose matrix
double getDeterminant() const; // Return the determinant of the matrix double getDeterminant() const; // Return the determinant of the matrix
double getTrace() const; // Return the trace of the matrix double getTrace() const; // Return the trace of the matrix
@ -64,13 +64,19 @@ class Matrix3x3 {
static Matrix3x3 identity(); // Return the 3x3 identity matrix static Matrix3x3 identity(); // Return the 3x3 identity matrix
// --- Overloaded operators --- // // --- Overloaded operators --- //
Matrix3x3 operator+(const Matrix3x3& matrix2) const; // Overloaded operator for addition friend Matrix3x3 operator+(const Matrix3x3& matrix1, const Matrix3x3& matrix2); // Overloaded operator for addition
Matrix3x3 operator-(const Matrix3x3& matrix2) const ; // Overloaded operator for substraction friend Matrix3x3 operator-(const Matrix3x3& matrix1, const Matrix3x3& matrix2); // Overloaded operator for substraction
Matrix3x3 operator*(double nb) const; // Overloaded operator for multiplication with a number friend Matrix3x3 operator-(const Matrix3x3& matrix); // Overloaded operator for the negative of the matrix
Matrix3x3 operator*(const Matrix3x3& matrix2) const; // Overloaded operator for multiplication with a matrix friend Matrix3x3 operator*(double nb, const Matrix3x3& matrix); // Overloaded operator for multiplication with a number
Vector3D operator*(const Vector3D& vector3d) const; // Overloaded operator for multiplication with a vector friend Matrix3x3 operator*(const Matrix3x3& matrix, double nb); // Overloaded operator for multiplication with a matrix
Matrix3x3& operator=(const Matrix3x3& matrix2); // Overloaded operator for assignment friend Matrix3x3 operator*(const Matrix3x3& matrix1, const Matrix3x3& matrix2); // Overloaded operator for matrix multiplication
bool operator==(const Matrix3x3& matrix2) const; // Overloaded operator for equality condition friend Vector3 operator*(const Matrix3x3& matrix, const Vector3& vector); // Overloaded operator for multiplication with a vector
bool operator==(const Matrix3x3& matrix) const; // Overloaded operator for equality condition
bool operator!= (const Matrix3x3& matrix) const; // Overloaded operator for the is different condition
Matrix3x3& operator+=(const Matrix3x3& matrix); // Overloaded operator for addition with assignment
Matrix3x3& operator-=(const Matrix3x3& matrix); // Overloaded operator for substraction with assignment
Matrix3x3& operator*=(double nb); // Overloaded operator for multiplication with a number with assignment
}; };
@ -88,16 +94,16 @@ inline void Matrix3x3::setValue(int i, int j, double value) {
// Method to set all the values in the matrix // Method to set all the values in the matrix
inline void Matrix3x3::setAllValues(double a1, double a2, double a3, double b1, double b2, double b3, inline void Matrix3x3::setAllValues(double a1, double a2, double a3, double b1, double b2, double b3,
double c1, double c2, double c3) { double c1, double c2, double c3) {
array[0][0] = a1; array[0][1] = a2; array[0][2] = a3; array[0][0] = a1; array[0][1] = a2; array[0][2] = a3;
array[1][0] = b1; array[1][1] = b2; array[1][2] = b3; array[1][0] = b1; array[1][1] = b2; array[1][2] = b3;
array[2][0] = c1; array[2][1] = c2; array[2][2] = c3; array[2][0] = c1; array[2][1] = c2; array[2][2] = c3;
} }
// Return a column // Return a column
inline Vector3D Matrix3x3::getColumn(int i) const { inline Vector3 Matrix3x3::getColumn(int i) const {
assert(i>= 0 && i<3); assert(i>= 0 && i<3);
return Vector3D(array[0][i], array[1][i], array[2][i]); return Vector3(array[0][i], array[1][i], array[2][i]);
} }
// Return the transpose matrix // Return the transpose matrix
@ -121,27 +127,6 @@ inline double Matrix3x3::getTrace() const {
return (array[0][0] + array[1][1] + array[2][2]); return (array[0][0] + array[1][1] + array[2][2]);
} }
// Overloaded operator for multiplication between a number and a Matrix3x3 (inline)
inline Matrix3x3 operator*(double number, const Matrix3x3& matrix) {
// Return the multiplied matrix
return matrix * number;
}
// Overloaded operator for multiplication with a vector
inline Vector3D Matrix3x3::operator*(const Vector3D& vector3d) const {
// Compute and return the result
return Vector3D(array[0][0]*vector3d.getX() + array[0][1]*vector3d.getY() + array[0][2]*vector3d.getZ(),
array[1][0]*vector3d.getX() + array[1][1]*vector3d.getY() + array[1][2]*vector3d.getZ(),
array[2][0]*vector3d.getX() + array[2][1]*vector3d.getY() + array[2][2]*vector3d.getZ());
}
// Overloaded operator for equality condition
inline bool Matrix3x3::operator==(const Matrix3x3& matrix2) const {
return (array[0][0] == matrix2.array[0][0] && array[0][1] == matrix2.array[0][1] && array[0][2] == matrix2.array[0][2] &&
array[1][0] == matrix2.array[1][0] && array[1][1] == matrix2.array[1][1] && array[1][2] == matrix2.array[1][2] &&
array[2][0] == matrix2.array[2][0] && array[2][1] == matrix2.array[2][1] && array[2][2] == matrix2.array[2][2]);
}
// Set the matrix to the identity matrix // Set the matrix to the identity matrix
inline void Matrix3x3::setToIdentity() { inline void Matrix3x3::setToIdentity() {
array[0][0] = 1.0; array[0][1] = 0.0; array[0][2] = 0.0; array[0][0] = 1.0; array[0][1] = 0.0; array[0][2] = 0.0;
@ -162,42 +147,93 @@ inline Matrix3x3 Matrix3x3::getAbsoluteMatrix() const {
fabs(array[2][0]), fabs(array[2][1]), fabs(array[2][2])); fabs(array[2][0]), fabs(array[2][1]), fabs(array[2][2]));
} }
// Overloaded operator for multiplication with a matrix
inline Matrix3x3 Matrix3x3::operator*(const Matrix3x3& matrix2) const {
// Compute and return the multiplication of the matrices
return Matrix3x3(array[0][0]*matrix2.array[0][0] + array[0][1]*matrix2.array[1][0] + array[0][2]*matrix2.array[2][0],
array[0][0]*matrix2.array[0][1] + array[0][1]*matrix2.array[1][1] + array[0][2]*matrix2.array[2][1],
array[0][0]*matrix2.array[0][2] + array[0][1]*matrix2.array[1][2] + array[0][2]*matrix2.array[2][2],
array[1][0]*matrix2.array[0][0] + array[1][1]*matrix2.array[1][0] + array[1][2]*matrix2.array[2][0],
array[1][0]*matrix2.array[0][1] + array[1][1]*matrix2.array[1][1] + array[1][2]*matrix2.array[2][1],
array[1][0]*matrix2.array[0][2] + array[1][1]*matrix2.array[1][2] + array[1][2]*matrix2.array[2][2],
array[2][0]*matrix2.array[0][0] + array[2][1]*matrix2.array[1][0] + array[2][2]*matrix2.array[2][0],
array[2][0]*matrix2.array[0][1] + array[2][1]*matrix2.array[1][1] + array[2][2]*matrix2.array[2][1],
array[2][0]*matrix2.array[0][2] + array[2][1]*matrix2.array[1][2] + array[2][2]*matrix2.array[2][2]);
}
// Overloaded operator for addition // Overloaded operator for addition
inline Matrix3x3 Matrix3x3::operator+(const Matrix3x3& matrix2) const { inline Matrix3x3 operator+(const Matrix3x3& matrix1, const Matrix3x3& matrix2) {
// Return the sum matrix return Matrix3x3(matrix1.array[0][0] + matrix2.array[0][0], matrix1.array[0][1] + matrix2.array[0][1], matrix1.array[0][2] + matrix2.array[0][2],
return Matrix3x3(array[0][0] + matrix2.array[0][0], array[0][1] + matrix2.array[0][1], array[0][2] + matrix2.array[0][2], matrix1.array[1][0] + matrix2.array[1][0], matrix1.array[1][1] + matrix2.array[1][1], matrix1.array[1][2] + matrix2.array[1][2],
array[1][0] + matrix2.array[1][0], array[1][1] + matrix2.array[1][1], array[1][2] + matrix2.array[1][2], matrix1.array[2][0] + matrix2.array[2][0], matrix1.array[2][1] + matrix2.array[2][1], matrix1.array[2][2] + matrix2.array[2][2]);
array[2][0] + matrix2.array[2][0], array[2][1] + matrix2.array[2][1], array[2][2] + matrix2.array[2][2]);
} }
// Overloaded operator for substraction // Overloaded operator for substraction
inline Matrix3x3 Matrix3x3::operator-(const Matrix3x3& matrix2) const { inline Matrix3x3 operator-(const Matrix3x3& matrix1, const Matrix3x3& matrix2) {
// Return the substraction matrix return Matrix3x3(matrix1.array[0][0] - matrix2.array[0][0], matrix1.array[0][1] - matrix2.array[0][1], matrix1.array[0][2] - matrix2.array[0][2],
return Matrix3x3(array[0][0] - matrix2.array[0][0], array[0][1] - matrix2.array[0][1], array[0][2] - matrix2.array[0][2], matrix1.array[1][0] - matrix2.array[1][0], matrix1.array[1][1] - matrix2.array[1][1], matrix1.array[1][2] - matrix2.array[1][2],
array[1][0] - matrix2.array[1][0], array[1][1] - matrix2.array[1][1], array[1][2] - matrix2.array[1][2], matrix1.array[2][0] - matrix2.array[2][0], matrix1.array[2][1] - matrix2.array[2][1], matrix1.array[2][2] - matrix2.array[2][2]);
array[2][0] - matrix2.array[2][0], array[2][1] - matrix2.array[2][1], array[2][2] - matrix2.array[2][2]); }
// Overloaded operator for the negative of the matrix
inline Matrix3x3 operator-(const Matrix3x3& matrix) {
return Matrix3x3(-matrix.array[0][0], -matrix.array[0][1], -matrix.array[0][2],
-matrix.array[1][0], -matrix.array[1][1], -matrix.array[1][2],
-matrix.array[2][0], -matrix.array[2][1], -matrix.array[2][2]);
} }
// Overloaded operator for multiplication with a number // Overloaded operator for multiplication with a number
inline Matrix3x3 Matrix3x3::operator*(double nb) const { inline Matrix3x3 operator*(double nb, const Matrix3x3& matrix) {
// Return multiplied matrix return Matrix3x3(matrix.array[0][0] * nb, matrix.array[0][1] * nb, matrix.array[0][2] * nb,
return Matrix3x3(array[0][0] * nb, array[0][1] * nb, array[0][2] * nb, matrix.array[1][0] * nb, matrix.array[1][1] * nb, matrix.array[1][2] * nb,
array[1][0] * nb, array[1][1] * nb, array[1][2] * nb, matrix.array[2][0] * nb, matrix.array[2][1] * nb, matrix.array[2][2] * nb);
array[2][0] * nb, array[2][1] * nb, array[2][2] * nb); }
// Overloaded operator for multiplication with a matrix
inline Matrix3x3 operator*(const Matrix3x3& matrix, double nb) {
return nb * matrix;
}
// Overloaded operator for matrix multiplication
inline Matrix3x3 operator*(const Matrix3x3& matrix1, const Matrix3x3& matrix2) {
return Matrix3x3(matrix1.array[0][0]*matrix2.array[0][0] + matrix1.array[0][1]*matrix2.array[1][0] + matrix1.array[0][2]*matrix2.array[2][0],
matrix1.array[0][0]*matrix2.array[0][1] + matrix1.array[0][1]*matrix2.array[1][1] + matrix1.array[0][2]*matrix2.array[2][1],
matrix1.array[0][0]*matrix2.array[0][2] + matrix1.array[0][1]*matrix2.array[1][2] + matrix1.array[0][2]*matrix2.array[2][2],
matrix1.array[1][0]*matrix2.array[0][0] + matrix1.array[1][1]*matrix2.array[1][0] + matrix1.array[1][2]*matrix2.array[2][0],
matrix1.array[1][0]*matrix2.array[0][1] + matrix1.array[1][1]*matrix2.array[1][1] + matrix1.array[1][2]*matrix2.array[2][1],
matrix1.array[1][0]*matrix2.array[0][2] + matrix1.array[1][1]*matrix2.array[1][2] + matrix1.array[1][2]*matrix2.array[2][2],
matrix1.array[2][0]*matrix2.array[0][0] + matrix1.array[2][1]*matrix2.array[1][0] + matrix1.array[2][2]*matrix2.array[2][0],
matrix1.array[2][0]*matrix2.array[0][1] + matrix1.array[2][1]*matrix2.array[1][1] + matrix1.array[2][2]*matrix2.array[2][1],
matrix1.array[2][0]*matrix2.array[0][2] + matrix1.array[2][1]*matrix2.array[1][2] + matrix1.array[2][2]*matrix2.array[2][2]);
}
// Overloaded operator for multiplication with a vector
inline Vector3 operator*(const Matrix3x3& matrix, const Vector3& vector) {
return Vector3(matrix.array[0][0]*vector.getX() + matrix.array[0][1]*vector.getY() + matrix.array[0][2]*vector.getZ(),
matrix.array[1][0]*vector.getX() + matrix.array[1][1]*vector.getY() + matrix.array[1][2]*vector.getZ(),
matrix.array[2][0]*vector.getX() + matrix.array[2][1]*vector.getY() + matrix.array[2][2]*vector.getZ());
}
// Overloaded operator for equality condition
inline bool Matrix3x3::operator==(const Matrix3x3& matrix) const {
return (array[0][0] == matrix.array[0][0] && array[0][1] == matrix.array[0][1] && array[0][2] == matrix.array[0][2] &&
array[1][0] == matrix.array[1][0] && array[1][1] == matrix.array[1][1] && array[1][2] == matrix.array[1][2] &&
array[2][0] == matrix.array[2][0] && array[2][1] == matrix.array[2][1] && array[2][2] == matrix.array[2][2]);
}
// Overloaded operator for the is different condition
inline bool Matrix3x3::operator!= (const Matrix3x3& matrix) const {
return !(*this == matrix);
}
// Overloaded operator for addition with assignment
inline Matrix3x3& Matrix3x3::operator+=(const Matrix3x3& matrix) {
array[0][0] += matrix.array[0][0]; array[0][1] += matrix.array[0][1]; array[0][2] += matrix.array[0][2];
array[1][0] += matrix.array[1][0]; array[1][1] += matrix.array[1][1]; array[1][2] += matrix.array[1][2];
array[2][0] += matrix.array[2][0]; array[2][1] += matrix.array[2][1]; array[2][2] += matrix.array[2][2];
return *this;
}
// Overloaded operator for substraction with assignment
inline Matrix3x3& Matrix3x3::operator-=(const Matrix3x3& matrix) {
array[0][0] -= matrix.array[0][0]; array[0][1] -= matrix.array[0][1]; array[0][2] -= matrix.array[0][2];
array[1][0] -= matrix.array[1][0]; array[1][1] -= matrix.array[1][1]; array[1][2] -= matrix.array[1][2];
array[2][0] -= matrix.array[2][0]; array[2][1] -= matrix.array[2][1]; array[2][2] -= matrix.array[2][2];
return *this;
}
// Overloaded operator for multiplication with a number with assignment
inline Matrix3x3& Matrix3x3::operator*=(double nb) {
array[0][0] *= nb; array[0][1] *= nb; array[0][2] *= nb;
array[1][0] *= nb; array[1][1] *= nb; array[1][2] *= nb;
array[2][0] *= nb; array[2][1] *= nb; array[2][2] *= nb;
return *this;
} }
} // End of the ReactPhysics3D namespace } // End of the ReactPhysics3D namespace

View File

@ -24,7 +24,7 @@
// Libraries // Libraries
#include "Quaternion.h" #include "Quaternion.h"
#include "Vector3D.h" #include "Vector3.h"
#include <cassert> #include <cassert>
// Namespace // Namespace
@ -43,7 +43,7 @@ Quaternion::Quaternion(double x, double y, double z, double w)
} }
// 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::Quaternion(double w, const Vector3D& v) Quaternion::Quaternion(double w, const Vector3& v)
:x(v.getX()), y(v.getY()), z(v.getZ()), w(w) { :x(v.getX()), y(v.getY()), z(v.getZ()), w(w) {
} }
@ -134,7 +134,7 @@ Quaternion::~Quaternion() {
// Compute the rotation angle (in radians) and the 3D rotation axis // Compute the rotation angle (in radians) and the 3D 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(double& angle, Vector3D& axis) const { void Quaternion::getRotationAngleAxis(double& angle, Vector3& axis) const {
Quaternion quaternion; Quaternion quaternion;
// If the quaternion is unit // If the quaternion is unit
@ -150,7 +150,7 @@ void Quaternion::getRotationAngleAxis(double& angle, Vector3D& axis) const {
angle = acos(quaternion.w) * 2.0; angle = acos(quaternion.w) * 2.0;
// Compute the 3D rotation axis // Compute the 3D rotation axis
Vector3D rotationAxis(quaternion.x, quaternion.y, quaternion.z); Vector3 rotationAxis(quaternion.x, quaternion.y, quaternion.z);
// Normalize the rotation axis // Normalize the rotation axis
rotationAxis = rotationAxis.getUnit(); rotationAxis = rotationAxis.getUnit();

View File

@ -27,7 +27,7 @@
// Libraries // Libraries
#include <cmath> #include <cmath>
#include "Vector3D.h" #include "Vector3.h"
#include "Matrix3x3.h" #include "Matrix3x3.h"
#include "exceptions.h" #include "exceptions.h"
@ -50,7 +50,7 @@ class Quaternion {
public : public :
Quaternion(); // Constructor Quaternion(); // Constructor
Quaternion(double x, double y, double z, double w); // Constructor with arguments Quaternion(double x, double y, double z, double w); // Constructor with arguments
Quaternion(double w, const Vector3D& v); // Constructor with the component w and the vector v=(x y z) Quaternion(double w, const Vector3& v); // Constructor with the component w and the vector v=(x y z)
Quaternion(const Quaternion& quaternion); // Copy-constructor Quaternion(const Quaternion& quaternion); // Copy-constructor
Quaternion(const Matrix3x3& matrix); // Create a unit quaternion from a rotation matrix Quaternion(const Matrix3x3& matrix); // Create a unit quaternion from a rotation matrix
~Quaternion(); // Destructor ~Quaternion(); // Destructor
@ -62,7 +62,7 @@ class Quaternion {
void setY(double y); // Set the value y void setY(double y); // Set the value y
void setZ(double z); // Set the value z void setZ(double z); // Set the value z
void setW(double w); // Set the value w void setW(double w); // Set the value w
Vector3D vectorV() const; // Return the vector v=(x y z) of the quaternion Vector3 vectorV() const; // Return the vector v=(x y z) of the quaternion
double length() const; // Return the length of the quaternion double length() const; // Return the length of the quaternion
Quaternion getUnit() const; // Return the unit quaternion Quaternion getUnit() const; // Return the unit quaternion
Quaternion getConjugate() const; // Return the conjugate quaternion Quaternion getConjugate() const; // Return the conjugate quaternion
@ -70,7 +70,7 @@ class Quaternion {
Matrix3x3 getMatrix() const; // Return the orientation matrix corresponding to this quaternion Matrix3x3 getMatrix() const; // Return the orientation matrix corresponding to this quaternion
static Quaternion identity(); // Return the identity quaternion static Quaternion identity(); // Return the identity quaternion
double dot(const Quaternion& quaternion) const; // Dot product between two quaternions double dot(const Quaternion& quaternion) const; // Dot product between two quaternions
void getRotationAngleAxis(double& angle, Vector3D& axis) const; // Compute the rotation angle (in radians) and the axis void getRotationAngleAxis(double& angle, Vector3& axis) const; // Compute the rotation angle (in radians) and the axis
static Quaternion slerp(const Quaternion& quaternion1, static Quaternion slerp(const Quaternion& quaternion1,
const Quaternion& quaternion2, double t); // Compute the spherical linear interpolation between two quaternions const Quaternion& quaternion2, double t); // Compute the spherical linear interpolation between two quaternions
@ -126,9 +126,9 @@ inline void Quaternion::setW(double w) {
} }
// Return the vector v=(x y z) of the quaternion // Return the vector v=(x y z) of the quaternion
inline Vector3D Quaternion::vectorV() const { inline Vector3 Quaternion::vectorV() const {
// Return the vector v // Return the vector v
return Vector3D(x, y, z); return Vector3(x, y, z);
} }
// Return the length of the quaternion (inline) // Return the length of the quaternion (inline)

View File

@ -30,18 +30,18 @@ using namespace reactphysics3d;
// Constructor // Constructor
Transform::Transform() { Transform::Transform() {
position = Vector3D(0.0, 0.0, 0.0); position = Vector3(0.0, 0.0, 0.0);
orientation = Quaternion::identity(); orientation = Quaternion::identity();
} }
// Constructor // Constructor
Transform::Transform(const Vector3D& position, const Matrix3x3& orientation) { Transform::Transform(const Vector3& position, const Matrix3x3& orientation) {
this->position = position; this->position = position;
this->orientation = Quaternion(orientation); this->orientation = Quaternion(orientation);
} }
// Constructor // Constructor
Transform::Transform(const Vector3D& position, const Quaternion& orientation) { Transform::Transform(const Vector3& position, const Quaternion& orientation) {
this->position = position; this->position = position;
this->orientation = orientation; this->orientation = orientation;
} }

View File

@ -27,7 +27,7 @@
// Libraries // Libraries
#include "Matrix3x3.h" #include "Matrix3x3.h"
#include "Vector3D.h" #include "Vector3.h"
#include "Quaternion.h" #include "Quaternion.h"
// ReactPhysiscs3D namespace // ReactPhysiscs3D namespace
@ -41,17 +41,17 @@ namespace reactphysics3d {
*/ */
class Transform { class Transform {
private : private :
Vector3D position; // Position Vector3 position; // Position
Quaternion orientation; // Orientation Quaternion orientation; // Orientation
public : public :
Transform(); // Constructor Transform(); // Constructor
Transform(const Vector3D& position, const Matrix3x3& orientation); // Constructor Transform(const Vector3& position, const Matrix3x3& orientation); // Constructor
Transform(const Vector3D& position, const Quaternion& orientation); // Constructor Transform(const Vector3& position, const Quaternion& orientation); // Constructor
~Transform(); // Destructor ~Transform(); // Destructor
const Vector3D& getPosition() const; // Return the origin of the transform const Vector3& getPosition() const; // Return the origin of the transform
void setPosition(const Vector3D& position); // Set the origin of the transform void setPosition(const Vector3& position); // Set the origin of the transform
const Quaternion& getOrientation() const; // Return the orientation quaternion const Quaternion& getOrientation() const; // Return the orientation quaternion
void setOrientation(const Quaternion& orientation); // Set the rotation quaternion void setOrientation(const Quaternion& orientation); // Set the rotation quaternion
void setToIdentity(); // Set the transform to the identity transform void setToIdentity(); // Set the transform to the identity transform
@ -62,17 +62,17 @@ class Transform {
const Transform& newTransform, const Transform& newTransform,
double interpolationFactor); // Return an interpolated transform double interpolationFactor); // Return an interpolated transform
Vector3D operator*(const Vector3D& vector) const; // Return the transformed vector Vector3 operator*(const Vector3& vector) const; // Return the transformed vector
Transform operator*(const Transform& transform2) const; // Operator of multiplication of a transform with another one Transform operator*(const Transform& transform2) const; // Operator of multiplication of a transform with another one
}; };
// Return the position of the transform // Return the position of the transform
inline const Vector3D& Transform::getPosition() const { inline const Vector3& Transform::getPosition() const {
return position; return position;
} }
// Set the origin of the transform // Set the origin of the transform
inline void Transform::setPosition(const Vector3D& position) { inline void Transform::setPosition(const Vector3& position) {
this->position = position; this->position = position;
} }
@ -88,7 +88,7 @@ inline void Transform::setOrientation(const Quaternion& orientation) {
// Set the transform to the identity transform // Set the transform to the identity transform
inline void Transform::setToIdentity() { inline void Transform::setToIdentity() {
position = Vector3D(0.0, 0.0, 0.0); position = Vector3(0.0, 0.0, 0.0);
orientation = Quaternion::identity(); orientation = Quaternion::identity();
} }
@ -114,18 +114,18 @@ inline void Transform::getOpenGLMatrix(double* openglMatrix) const {
inline Transform Transform::inverse() const { inline Transform Transform::inverse() const {
const Quaternion& invQuaternion = orientation.getInverse(); const Quaternion& invQuaternion = orientation.getInverse();
Matrix3x3 invMatrix = invQuaternion.getMatrix(); Matrix3x3 invMatrix = invQuaternion.getMatrix();
return Transform(invMatrix * position.getOpposite(), invQuaternion); return Transform(invMatrix * (-position), invQuaternion);
} }
// Return an interpolated transform // Return an interpolated transform
inline Transform Transform::interpolateTransforms(const Transform& oldTransform, const Transform& newTransform, double interpolationFactor) { inline Transform Transform::interpolateTransforms(const Transform& oldTransform, const Transform& newTransform, double interpolationFactor) {
Vector3D interPosition = oldTransform.position * (1.0 - interpolationFactor) + newTransform.position * interpolationFactor; Vector3 interPosition = oldTransform.position * (1.0 - interpolationFactor) + newTransform.position * interpolationFactor;
Quaternion interOrientation = Quaternion::slerp(oldTransform.orientation, newTransform.orientation, interpolationFactor); Quaternion interOrientation = Quaternion::slerp(oldTransform.orientation, newTransform.orientation, interpolationFactor);
return Transform(interPosition, interOrientation); return Transform(interPosition, interOrientation);
} }
// Return the transformed vector // Return the transformed vector
inline Vector3D Transform::operator*(const Vector3D& vector) const { inline Vector3 Transform::operator*(const Vector3& vector) const {
return (orientation.getMatrix() * vector) + position; return (orientation.getMatrix() * vector) + position;
} }

View File

@ -66,7 +66,7 @@ Vector::Vector(const Vector& vector) {
} }
// Conversion from Vector3D to Vector // Conversion from Vector3D to Vector
Vector::Vector(const Vector3D& vector3d) { Vector::Vector(const Vector3& vector3d) {
nbComponent = 3; nbComponent = 3;
tab = new double[3]; tab = new double[3];

View File

@ -26,7 +26,7 @@
#define VECTOR_H #define VECTOR_H
// Libraries // Libraries
#include "Vector3D.h" #include "Vector3.h"
#include "../constants.h" #include "../constants.h"
#include "mathematics_functions.h" #include "mathematics_functions.h"
#include "exceptions.h" #include "exceptions.h"
@ -52,7 +52,7 @@ class Vector {
Vector(); // Constructor without argument Vector(); // Constructor without argument
Vector(int n) throw(std::invalid_argument); // Constructor of the class Vector Vector(int n) throw(std::invalid_argument); // Constructor of the class Vector
Vector(const Vector& vector); // Copy-constructor of the class Vector Vector(const Vector& vector); // Copy-constructor of the class Vector
Vector(const Vector3D& vector3d); // Conversion from Vector3D to Vector Vector(const Vector3& vector3d); // Conversion from Vector3D to Vector
virtual ~Vector(); // Destructor of the class Vector virtual ~Vector(); // Destructor of the class Vector
double getValue(int n) const throw(std::invalid_argument); // Get a component of the vector double getValue(int n) const throw(std::invalid_argument); // Get a component of the vector
void setValue(int n, double value) throw(std::invalid_argument); // Set the value of a component of the vector void setValue(int n, double value) throw(std::invalid_argument); // Set the value of a component of the vector

View File

@ -0,0 +1,95 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010 Daniel Chappuis *
*********************************************************************************
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN *
* THE SOFTWARE. *
********************************************************************************/
// Libraries
#include "Vector3.h"
#include <iostream>
#include <cassert>
#include <vector>
// Namespaces
using namespace reactphysics3d;
// Constructor of the class Vector3D
Vector3::Vector3() {
values[0] = 0.0;
values[1] = 0.0;
values[2] = 0.0;
}
// Constructor with arguments
Vector3::Vector3(double x, double y, double z) {
values[0] = x;
values[1] = y;
values[2] = z;
}
// Copy-constructor
Vector3::Vector3(const Vector3& vector) {
values[0] = vector.values[0];
values[1] = vector.values[1];
values[2] = vector.values[2];
}
// Destructor
Vector3::~Vector3() {
}
// Return the corresponding unit vector
Vector3 Vector3::getUnit() const {
double lengthVector = length();
assert(lengthVector != 0.0);
// Compute and return the unit vector
double lengthInv = 1.0 / lengthVector;
return Vector3(values[0] * lengthInv, values[1] * lengthInv, values[2] * lengthInv);
}
// Return two unit orthogonal vectors of the current vector
Vector3 Vector3::getOneOrthogonalVector() const {
assert(!this->isZero());
// Compute a first orthogonal vector
Vector3 vector1;
if (!approxEqual(values[0], 0.0)) { // If x != 0
vector1.setY(values[0]);
vector1.setZ((-2*values[0]*values[1]*values[2] + 2*values[0]*values[2])/(2*(values[2]*values[2] + values[0]*values[0])));
vector1.setX((-values[0]*values[1]-values[2]*vector1.getZ())/values[0]);
}
else if (!approxEqual(values[1], 0.0)) { // If y != 0
vector1.setZ(values[1]);
vector1.setX((-2*values[0]*values[1]*values[2] + 2*values[0]*values[1])/(2*(values[1]*values[1] + values[0]*values[0])));
vector1.setY((-values[2]*values[1]-values[0]*vector1.getX())/values[1]);
}
else if (!approxEqual(values[2], 0.0)) { // If z != 0
vector1.setX(values[2]);
vector1.setY((-2*values[0]*values[1]*values[2] + 2*values[1]*values[2])/(2*(values[2]*values[2] + values[1]*values[1])));
vector1.setZ((-values[0]*values[2]-values[1]*vector1.getY())/values[2]);
}
assert(vector1.isUnit());
return vector1;
}

256
src/mathematics/Vector3.h Normal file
View File

@ -0,0 +1,256 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010 Daniel Chappuis *
*********************************************************************************
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN *
* THE SOFTWARE. *
********************************************************************************/
#ifndef VECTOR3_H
#define VECTOR3_H
// Libraries
#include <cmath>
#include "exceptions.h"
#include "mathematics_functions.h"
// TODO : Remove the methods getX(), getY(), getZ(), setX(), setY(), setZ() and replace the attributes
// x, y and z by an array values[3]
// ReactPhysics3D namespace
namespace reactphysics3d {
/* -------------------------------------------------------------------
Class Vector3 :
This classrepresents 3 dimensionnal vector in space.
-------------------------------------------------------------------
*/
class Vector3 {
private :
double values[3]; // Values of the 3D vector
public :
Vector3(); // Constructor of the class Vector3D
Vector3(double x, double y, double z); // Constructor with arguments
Vector3(const Vector3& vector); // Copy-constructor
virtual ~Vector3(); // Destructor
void setValue(int index, double value) throw(std::invalid_argument); // Set a component of the vector
double getX() const; // Get the x component of the vector
double getY() const; // Get the y component of the vector
double getZ() const; // Get the z component of the vector
void setX(double x); // Set the x component of the vector
void setY(double y); // Set the y component of the vector
void setZ(double z); // Set the z component of the vector
void setAllValues(double x, double y, double z); // Set all the values of the vector
double length() const; // Return the lenght of the vector
double lengthSquare() const; // Return the square of the length of the vector
Vector3 getUnit() const; // Return the corresponding unit vector
bool isUnit() const; // Return true if the vector is unit and false otherwise
bool isZero() const; // Return true if the current vector is the zero vector
Vector3 getOneOrthogonalVector() const; // Return one unit orthogonal vectors of the current vector
double dot(const Vector3& vector) const; // Dot product of two vectors
Vector3 cross(const Vector3& vector) const; // Cross product of two vectors
Vector3 getAbsoluteVector() const; // Return the corresponding absolute value vector
int getMinAxis() const; // Return the axis with the minimal value
int getMaxAxis() const; // Return the axis with the maximal value
bool isParallelWith(const Vector3& vector) const; // Return true if two vectors are parallel
// --- Overloaded operators --- //
bool operator== (const Vector3& vector) const; // Overloaded operator for the equality condition
bool operator!= (const Vector3& vector) const; // Overloaded operator for the is different condition
Vector3& operator+=(const Vector3& vector); // Overloaded operator for addition with assignment
Vector3& operator-=(const Vector3& vector); // Overloaded operator for substraction with assignment
Vector3& operator*=(double number); // Overloaded operator for multiplication with a number with assignment
double& operator[] (int index); // Overloaded operator for value access
const double& operator[] (int index) const; // Overloaded operator for value access
// Friend functions
friend Vector3 operator+(const Vector3& vector1, const Vector3& vector2);
friend Vector3 operator-(const Vector3& vector1, const Vector3& vector2);
friend Vector3 operator-(const Vector3& vector);
friend Vector3 operator*(const Vector3& vector, double number);
friend Vector3 operator*(double number, const Vector3& vector);
};
// Get the x component of the vector
inline double Vector3::getX() const {
return values[0];
}
// Get the y component of the vector
inline double Vector3::getY() const {
return values[1];
}
// Get the z component of the vector
inline double Vector3::getZ() const {
return values[2];
}
// Set the x component of the vector
inline void Vector3::setX(double x) {
this->values[0] = x;
}
// Set the y component of the vector
inline void Vector3::setY(double y) {
this->values[1] = y;
}
// Set the z component of the vector
inline void Vector3::setZ(double z) {
this->values[2] = z;
}
// Set all the values of the vector (inline)
inline void Vector3::setAllValues(double x, double y, double z) {
values[0]= x;
values[1] = y;
values[2] = z;
}
// Return the length of the vector (inline)
inline double Vector3::length() const {
// Compute and return the length of the vector
return sqrt(values[0]*values[0] + values[1]*values[1] + values[2]*values[2]);
}
// Return the square of the length of the vector
inline double Vector3::lengthSquare() const {
return values[0]*values[0] + values[1]*values[1] + values[2]*values[2];
}
// Scalar product of two vectors (inline)
inline double Vector3::dot(const Vector3& vector) const {
// Compute and return the result of the scalar product
return (values[0] * vector.values[0] + values[1] * vector.values[1] + values[2] * vector.values[2]);
}
// Cross product of two vectors (inline)
inline Vector3 Vector3::cross(const Vector3& vector) const {
// Compute and return the cross product
return Vector3(values[1] * vector.values[2] - values[2] * vector.values[1],
values[2] * vector.values[0] - values[0] * vector.values[2],
values[0] * vector.values[1] - values[1] * vector.values[0]);
}
// Return the corresponding absolute value vector
inline Vector3 Vector3::getAbsoluteVector() const {
return Vector3(std::abs(values[0]), std::abs(values[1]), std::abs(values[2]));
}
// Return true if two vectors are parallel
inline bool Vector3::isParallelWith(const Vector3& vector) const {
double scalarProd = this->dot(vector);
return approxEqual(std::abs(scalarProd), length() * vector.length());
}
// Return the axis with the minimal value
inline int Vector3::getMinAxis() const {
return (values[0] < values[1] ? (values[0] < values[2] ? 0 : 2) : (values[1] < values[2] ? 1 : 2));
}
// Return the axis with the maximal value
inline int Vector3::getMaxAxis() const {
return (values[0] < values[1] ? (values[1] < values[2] ? 2 : 1) : (values[0] < values[2] ? 2 : 0));
}
// Return true if the vector is unit and false otherwise
inline bool Vector3::isUnit() const {
return approxEqual(values[0] * values[0] + values[1] * values[1] + values[2] * values[2], 1.0);
}
// Return true if the vector is the zero vector
inline bool Vector3::isZero() const {
return approxEqual(values[0] * values[0] + values[1] * values[1] + values[2] * values[2], 0.0);
}
// Overloaded operator for the equality condition
inline bool Vector3::operator== (const Vector3& vector) const {
return (values[0] == vector.values[0] && values[1] == vector.values[1] && values[2] == vector.values[2]);
}
// Overloaded operator for the is different condition
inline bool Vector3::operator!= (const Vector3& vector) const {
return !(*this == vector);
}
// Overloaded operator for addition with assignment
inline Vector3& Vector3::operator+=(const Vector3& vector) {
values[0] += vector.values[0];
values[1] += vector.values[1];
values[2] += vector.values[2];
return *this;
}
// Overloaded operator for substraction with assignment
inline Vector3& Vector3::operator-=(const Vector3& vector) {
values[0] -= vector.values[0];
values[1] -= vector.values[1];
values[2] -= vector.values[2];
return *this;
}
// Overloaded operator for multiplication with a number with assignment
inline Vector3& Vector3::operator*=(double number) {
values[0] *= number;
values[1] *= number;
values[2] *= number;
return *this;
}
// Overloaded operator for value access
inline double& Vector3::operator[] (int index) {
return values[index];
}
// Overloaded operator for value access
inline const double& Vector3::operator[] (int index) const {
return values[index];
}
// Overloaded operator for addition
inline Vector3 operator+(const Vector3& vector1, const Vector3& vector2) {
return Vector3(vector1.values[0] + vector2.values[0], vector1.values[1] + vector2.values[1], vector1.values[2] + vector2.values[2]);
}
// Overloaded operator for substraction
inline Vector3 operator-(const Vector3& vector1, const Vector3& vector2) {
return Vector3(vector1.values[0] - vector2.values[0], vector1.values[1] - vector2.values[1], vector1.values[2] - vector2.values[2]);
}
// Overloaded operator for the negative of a vector
inline Vector3 operator-(const Vector3& vector) {
return Vector3(-vector.values[0], -vector.values[1], -vector.values[2]);
}
// Overloaded operator for multiplication with a number
inline Vector3 operator*(const Vector3& vector, double number) {
return Vector3(number * vector.values[0], number * vector.values[1], number * vector.values[2]);
}
// Overloaded operator for multiplication with a number
inline Vector3 operator*(double number, const Vector3& vector) {
return vector * number;
}
} // End of the ReactPhysics3D namespace
#endif

View File

@ -1,130 +0,0 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010 Daniel Chappuis *
*********************************************************************************
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN *
* THE SOFTWARE. *
********************************************************************************/
// Libraries
#include "Vector3D.h"
#include <iostream>
#include <cassert>
#include <vector>
// Namespaces
using namespace reactphysics3d;
// Constructor of the class Vector3D
Vector3D::Vector3D()
:x(0.0), y(0.0), z(0.0) {
}
// Constructor with arguments
Vector3D::Vector3D(double x, double y, double z)
:x(x), y(y), z(z) {
}
// Copy-constructor
Vector3D::Vector3D(const Vector3D& vector)
:x(vector.x), y(vector.y), z(vector.z) {
}
// Destructor
Vector3D::~Vector3D() {
}
// Return the corresponding unit vector
Vector3D Vector3D::getUnit() const throw(MathematicsException) {
double lengthVector = length();
// Check if the length is equal to zero
if (lengthVector != 0) {
// Compute and return the unit vector
double lengthInv = 1.0 / lengthVector;
return Vector3D(x * lengthInv, y * lengthInv, z*lengthInv);
}
else {
// Throw an exception because the length of the vector is zero
throw MathematicsException("MathematicsException : Impossible to compute the unit vector because the length of the vector is zero");
}
}
// Return two unit orthogonal vectors of the current vector
Vector3D Vector3D::getOneOrthogonalVector() const {
assert(!this->isZero());
Vector3D unitVector = this->getUnit();
// Compute a first orthogonal vector
Vector3D vector1;
if (!approxEqual(x, 0.0)) { // If x != 0
vector1.setY(x);
vector1.setZ((-2*x*y*z + 2*x*z)/(2*(z*z + x*x)));
vector1.setX((-x*y-z*vector1.getZ())/x);
}
else if (!approxEqual(y, 0.0)) { // If y != 0
vector1.setZ(y);
vector1.setX((-2*x*y*z + 2*x*y)/(2*(y*y + x*x)));
vector1.setY((-z*y-x*vector1.getX())/y);
}
else if (!approxEqual(z, 0.0)) { // If z != 0
vector1.setX(z);
vector1.setY((-2*x*y*z + 2*y*z)/(2*(z*z + y*y)));
vector1.setZ((-x*z-y*vector1.getY())/z);
}
assert(vector1.isUnit());
return vector1;
}
// Overloaded operator for addition
Vector3D Vector3D::operator+(const Vector3D& vector) const {
// Compute and return the sum of the two vectors
return Vector3D(x + vector.x, y + vector.y, z + vector.z);
}
// Overloaded operator for substraction
Vector3D Vector3D::operator-(const Vector3D& vector) const {
// Compute and return the substraction of the two vectors
return Vector3D(x - vector.x, y - vector.y, z - vector.z);
}
// Overloaded operator for multiplication with a number
Vector3D Vector3D::operator*(double number) const {
// Compute and return the result
return Vector3D(x * number, y * number, z * number);
}
// Overloaded operator for the assignement to a Vector
Vector3D& Vector3D::operator=(const Vector3D& vector) {
// Check for self-assignment
if (this != &vector) {
// Copy the vector
x = vector.x;
y = vector.y;
z = vector.z;
}
// Return a reference to the vector
return *this;
}

View File

@ -1,218 +0,0 @@
/********************************************************************************
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
* Copyright (c) 2010 Daniel Chappuis *
*********************************************************************************
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN *
* THE SOFTWARE. *
********************************************************************************/
#ifndef VECTOR3D_H
#define VECTOR3D_H
// Libraries
#include <cmath>
#include "exceptions.h"
#include "mathematics_functions.h"
// TODO : Remove the methods getX(), getY(), getZ(), setX(), setY(), setZ() and replace the attributes
// x, y and z by an array values[3]
// ReactPhysics3D namespace
namespace reactphysics3d {
/* -------------------------------------------------------------------
Class Vector3D :
This classrepresents 3 dimensionnal vector in space.
-------------------------------------------------------------------
*/
class Vector3D {
private :
double x; // X component of the vector
double y; // Y component of the vector
double z; // Z component of the vector
public :
Vector3D(); // Constructor of the class Vector3D
Vector3D(double x, double y, double z); // Constructor with arguments
Vector3D(const Vector3D& vector); // Copy-constructor
virtual ~Vector3D(); // Destructor
double getValue(int index) const throw(std::invalid_argument); // Get a component of the vector
void setValue(int index, double value) throw(std::invalid_argument); // Set a component of the vector
double getX() const; // Get the x component of the vector
double getY() const; // Get the y component of the vector
double getZ() const; // Get the z component of the vector
void setX(double x); // Set the x component of the vector
void setY(double y); // Set the y component of the vector
void setZ(double z); // Set the z component of the vector
void setAllValues(double x, double y, double z); // Set all the values of the vector
double length() const; // Return the lenght of the vector
double lengthSquare() const; // Return the square of the length of the vector
Vector3D getUnit() const throw(MathematicsException); // Return the corresponding unit vector
bool isUnit() const; // Return true if the vector is unit and false otherwise
bool isZero() const; // Return true if the current vector is the zero vector
Vector3D getOpposite() const; // Return the vector in the opposite direction
Vector3D getOneOrthogonalVector() const; // Return one unit orthogonal vectors of the current vector
double dot(const Vector3D& vector) const; // Dot product of two vectors
Vector3D cross(const Vector3D& vector) const; // Cross product of two vectors
Vector3D getAbsoluteVector() const; // Return the corresponding absolute value vector
int getMinAxis() const; // Return the axis with the minimal value
int getMaxAxis() const; // Return the axis with the maximal value
bool isParallelWith(const Vector3D& vector) const; // Return true if two vectors are parallel
// --- Overloaded operators --- //
Vector3D operator+(const Vector3D& vector) const; // Overloaded operator for addition
Vector3D operator-(const Vector3D& vector) const ; // Overloaded operator for substraction
Vector3D operator*(double number) const; // Overloaded operator for multiplication with a number
Vector3D& operator=(const Vector3D& vector); // Overloaded operator for the assignement to a Vector
bool operator==(const Vector3D& vector) const; // Overloaded operator for the equality condition
};
// Get the x component of the vector (inline)
inline double Vector3D::getX() const {
return x;
}
// Get the y component of the vector (inline)
inline double Vector3D::getY() const {
return y;
}
// Get the z component of the vector (inline)
inline double Vector3D::getZ() const {
return z;
}
// Set the x component of the vector (inline)
inline void Vector3D::setX(double x) {
this->x = x;
}
// Set the y component of the vector (inline)
inline void Vector3D::setY(double y) {
this->y = y;
}
// Set the z component of the vector (inline)
inline void Vector3D::setZ(double z) {
this->z = z;
}
// Get a component of the vector
inline double Vector3D::getValue(int index) const throw(std::invalid_argument) {
switch(index) {
case 0: return x;
case 1: return y;
case 2: return z;
default: // Throw an exception because of the wrong argument
throw std::invalid_argument("The argument is outside the bounds of the Vector3D");
}
}
// Set a component of the vector
inline void Vector3D::setValue(int index, double value) throw(std::invalid_argument) {
switch(index) {
case 0: x = value;
case 1: y = value;
case 2: z = value;
default: // Throw an exception because of the wrong argument
throw std::invalid_argument("The argument is outside the bounds of the Vector3D");
}
}
// Set all the values of the vector (inline)
inline void Vector3D::setAllValues(double x, double y, double z) {
this->x = x;
this->y = y;
this->z = z;
}
// Return the length of the vector (inline)
inline double Vector3D::length() const {
// Compute and return the length of the vector
return sqrt(x*x + y*y + z*z);
}
// Return the square of the length of the vector
inline double Vector3D::lengthSquare() const {
return x*x + y*y + z*z;
}
// Return the vector in the opposite direction
inline Vector3D Vector3D::getOpposite() const {
return (Vector3D(0.0, 0.0, 0.0) - *this);
}
// Scalar product of two vectors (inline)
inline double Vector3D::dot(const Vector3D& vector) const {
// Compute and return the result of the scalar product
return (x * vector.x + y * vector.y + z * vector.z);
}
// Cross product of two vectors (inline)
inline Vector3D Vector3D::cross(const Vector3D& vector) const {
// Compute and return the cross product
return Vector3D(y * vector.z - z * vector.y, z * vector.x - x * vector.z , x * vector.y - y * vector.x);
}
// Return the corresponding absolute value vector
inline Vector3D Vector3D::getAbsoluteVector() const {
return Vector3D(std::abs(x), std::abs(y), std::abs(z));
}
// Return true if two vectors are parallel
inline bool Vector3D::isParallelWith(const Vector3D& vector) const {
double scalarProd = this->dot(vector);
return approxEqual(std::abs(scalarProd), length() * vector.length());
}
// Return the axis with the minimal value
inline int Vector3D::getMinAxis() const {
return (x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2));
}
// Return the axis with the maximal value
inline int Vector3D::getMaxAxis() const {
return (x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0));
}
// Return true if the vector is unit and false otherwise
inline bool Vector3D::isUnit() const {
return approxEqual(x*x+y*y+z*z, 1.0);
}
// Return true if the vector is the zero vector
inline bool Vector3D::isZero() const {
return approxEqual(x*x+y*y+z*z, 0.0);
}
// Overloaded operator for multiplication between a number and a Vector3D (inline)
inline Vector3D operator * (double number, const Vector3D& vector) {
// Compute and return the result vector
return vector * number;
}
// Overloaded operator for the equality condition
inline bool Vector3D::operator == (const Vector3D& vector) const {
return (x == vector.x && y == vector.y && z == vector.z);
}
} // End of the ReactPhysics3D namespace
#endif

View File

@ -30,7 +30,7 @@
#include "Matrix3x3.h" #include "Matrix3x3.h"
#include "Quaternion.h" #include "Quaternion.h"
#include "Vector.h" #include "Vector.h"
#include "Vector3D.h" #include "Vector3.h"
#include "Transform.h" #include "Transform.h"
#include "../constants.h" #include "../constants.h"
#include "exceptions.h" #include "exceptions.h"
@ -47,7 +47,7 @@ namespace reactphysics3d {
// Rotate a vector according to a rotation quaternion. // Rotate a vector according to a rotation quaternion.
// The function returns the vector rotated according to the quaternion in argument // The function returns the vector rotated according to the quaternion in argument
inline reactphysics3d::Vector3D rotateVectorWithQuaternion(const reactphysics3d::Vector3D& vector, const reactphysics3d::Quaternion& quaternion) { inline reactphysics3d::Vector3 rotateVectorWithQuaternion(const reactphysics3d::Vector3& vector, const reactphysics3d::Quaternion& quaternion) {
// Convert the vector into a quaternion // Convert the vector into a quaternion
reactphysics3d::Quaternion vectorQuaternion(0, vector); reactphysics3d::Quaternion vectorQuaternion(0, vector);
@ -62,10 +62,10 @@ inline reactphysics3d::Vector3D rotateVectorWithQuaternion(const reactphysics3d:
// "alpha" and "beta" such that the two points P1 and P2 are the two closest point between the two lines and such that // "alpha" and "beta" such that the two points P1 and P2 are the two closest point between the two lines and such that
// P1 = point1 + alpha * d1 // P1 = point1 + alpha * d1
// P2 = point2 + beta * d2 // P2 = point2 + beta * d2
inline void closestPointsBetweenTwoLines(const reactphysics3d::Vector3D& point1, const reactphysics3d::Vector3D& d1, const reactphysics3d::Vector3D& point2, inline void closestPointsBetweenTwoLines(const reactphysics3d::Vector3& point1, const reactphysics3d::Vector3& d1, const reactphysics3d::Vector3& point2,
const reactphysics3d::Vector3D& d2, double* alpha, double* beta) { const reactphysics3d::Vector3& d2, double* alpha, double* beta) {
reactphysics3d::Vector3D r = point1 - point2; reactphysics3d::Vector3 r = point1 - point2;
double a = d1.dot(d1); double a = d1.dot(d1);
double b = d1.dot(d2); double b = d1.dot(d2);
double c = d1.dot(r); double c = d1.dot(r);
@ -82,11 +82,11 @@ inline void closestPointsBetweenTwoLines(const reactphysics3d::Vector3D& point1,
} }
// This method returns true if the point "P" is on the segment between "segPointA" and "segPointB" and return false otherwise // This method returns true if the point "P" is on the segment between "segPointA" and "segPointB" and return false otherwise
inline bool isPointOnSegment(const reactphysics3d::Vector3D& segPointA, const reactphysics3d::Vector3D& segPointB, const reactphysics3d::Vector3D& P) { inline bool isPointOnSegment(const reactphysics3d::Vector3& segPointA, const reactphysics3d::Vector3& segPointB, const reactphysics3d::Vector3& P) {
// Check if the point P is on the line between "segPointA" and "segPointB" // Check if the point P is on the line between "segPointA" and "segPointB"
reactphysics3d::Vector3D d = segPointB - segPointA; reactphysics3d::Vector3 d = segPointB - segPointA;
reactphysics3d::Vector3D dP = P - segPointA; reactphysics3d::Vector3 dP = P - segPointA;
if (!d.isParallelWith(dP)) { if (!d.isParallelWith(dP)) {
return false; return false;
} }
@ -110,13 +110,13 @@ inline bool isPointOnSegment(const reactphysics3d::Vector3D& segPointA, const re
// Given two lines in 3D that intersect, this method returns the intersection point between the two lines. // Given two lines in 3D that intersect, this method returns the intersection point between the two lines.
// The first line is given by the point "p1" and the vector "d1", the second line is given by the point "p2" and the vector "d2". // The first line is given by the point "p1" and the vector "d1", the second line is given by the point "p2" and the vector "d2".
inline reactphysics3d::Vector3D computeLinesIntersection(const reactphysics3d::Vector3D& p1, const reactphysics3d::Vector3D& d1, inline reactphysics3d::Vector3 computeLinesIntersection(const reactphysics3d::Vector3& p1, const reactphysics3d::Vector3& d1,
const reactphysics3d::Vector3D& p2, const reactphysics3d::Vector3D& d2) { const reactphysics3d::Vector3& p2, const reactphysics3d::Vector3& d2) {
// Computes the two closest points on the lines // Computes the two closest points on the lines
double alpha, beta; double alpha, beta;
closestPointsBetweenTwoLines(p1, d1, p2, d2, &alpha, &beta); closestPointsBetweenTwoLines(p1, d1, p2, d2, &alpha, &beta);
reactphysics3d::Vector3D point1 = p1 + alpha * d1; reactphysics3d::Vector3 point1 = p1 + alpha * d1;
reactphysics3d::Vector3D point2 = p2 + beta * d2; reactphysics3d::Vector3 point2 = p2 + beta * d2;
// The two points must be very close // The two points must be very close
//assert((point1-point2).length() <= 0.1); //assert((point1-point2).length() <= 0.1);
@ -128,11 +128,11 @@ inline reactphysics3d::Vector3D computeLinesIntersection(const reactphysics3d::V
// Given two segments in 3D that are not parallel and that intersect, this method computes the intersection point between the two segments. // Given two segments in 3D that are not parallel and that intersect, this method computes the intersection point between the two segments.
// This method returns the intersection point. // This method returns the intersection point.
inline reactphysics3d::Vector3D computeNonParallelSegmentsIntersection(const reactphysics3d::Vector3D& seg1PointA, const reactphysics3d::Vector3D& seg1PointB, inline reactphysics3d::Vector3 computeNonParallelSegmentsIntersection(const reactphysics3d::Vector3& seg1PointA, const reactphysics3d::Vector3& seg1PointB,
const reactphysics3d::Vector3D& seg2PointA, const reactphysics3d::Vector3D& seg2PointB) { const reactphysics3d::Vector3& seg2PointA, const reactphysics3d::Vector3& seg2PointB) {
// Determine the lines of both segments // Determine the lines of both segments
reactphysics3d::Vector3D d1 = seg1PointB - seg1PointA; reactphysics3d::Vector3 d1 = seg1PointB - seg1PointA;
reactphysics3d::Vector3D d2 = seg2PointB - seg2PointA; reactphysics3d::Vector3 d2 = seg2PointB - seg2PointA;
// The segments must not be parallel // The segments must not be parallel
assert(!d1.isParallelWith(d2)); assert(!d1.isParallelWith(d2));
@ -140,15 +140,15 @@ inline reactphysics3d::Vector3D computeNonParallelSegmentsIntersection(const rea
// Compute the closet points between the two lines // Compute the closet points between the two lines
double alpha, beta; double alpha, beta;
closestPointsBetweenTwoLines(seg1PointA, d1, seg2PointA, d2, &alpha, &beta); closestPointsBetweenTwoLines(seg1PointA, d1, seg2PointA, d2, &alpha, &beta);
reactphysics3d::Vector3D point1 = seg1PointA + alpha * d1; reactphysics3d::Vector3 point1 = seg1PointA + alpha * d1;
reactphysics3d::Vector3D point2 = seg2PointA + beta * d2; reactphysics3d::Vector3 point2 = seg2PointA + beta * d2;
// The closest points have to be on the segments, otherwise there is no intersection between the segments // The closest points have to be on the segments, otherwise there is no intersection between the segments
assert(isPointOnSegment(seg1PointA, seg1PointB, point1)); assert(isPointOnSegment(seg1PointA, seg1PointB, point1));
assert(isPointOnSegment(seg2PointA, seg2PointB, point2)); assert(isPointOnSegment(seg2PointA, seg2PointB, point2));
// If the two closest point aren't very close, there is no intersection between the segments // If the two closest point aren't very close, there is no intersection between the segments
reactphysics3d::Vector3D d = point2 - point1; reactphysics3d::Vector3 d = point2 - point1;
assert(d.length() <= EPSILON_TEST); assert(d.length() <= EPSILON_TEST);
// They are very close so we return the intersection point (halfway between "point1" and "point2" // They are very close so we return the intersection point (halfway between "point1" and "point2"
@ -158,8 +158,8 @@ inline reactphysics3d::Vector3D computeNonParallelSegmentsIntersection(const rea
// Move a set of points by a given vector. // Move a set of points by a given vector.
// The method returns a set of points moved by the given vector. // The method returns a set of points moved by the given vector.
inline std::vector<reactphysics3d::Vector3D> movePoints(const std::vector<reactphysics3d::Vector3D>& points, const reactphysics3d::Vector3D& vector) { inline std::vector<reactphysics3d::Vector3> movePoints(const std::vector<reactphysics3d::Vector3>& points, const reactphysics3d::Vector3& vector) {
std::vector<reactphysics3d::Vector3D> result; std::vector<reactphysics3d::Vector3> result;
// For each point of the set // For each point of the set
for (unsigned int i=0; i<points.size(); ++i) { for (unsigned int i=0; i<points.size(); ++i) {
@ -174,12 +174,12 @@ inline std::vector<reactphysics3d::Vector3D> movePoints(const std::vector<reactp
// Compute the projection of a set of 3D points onto a 3D plane. The set of points is given by "points" and the plane is given by // Compute the projection of a set of 3D points onto a 3D plane. The set of points is given by "points" and the plane is given by
// a point "A" and a normal vector "normal". This method returns the initial set of points projected onto the plane. // a point "A" and a normal vector "normal". This method returns the initial set of points projected onto the plane.
inline std::vector<reactphysics3d::Vector3D> projectPointsOntoPlane(const std::vector<reactphysics3d::Vector3D>& points, const reactphysics3d::Vector3D& A, inline std::vector<reactphysics3d::Vector3> projectPointsOntoPlane(const std::vector<reactphysics3d::Vector3>& points, const reactphysics3d::Vector3& A,
const reactphysics3d::Vector3D& normal) { const reactphysics3d::Vector3& normal) {
assert(normal.length() != 0.0); assert(normal.length() != 0.0);
std::vector<Vector3D> projectedPoints; std::vector<Vector3> projectedPoints;
reactphysics3d::Vector3D n = normal.getUnit(); reactphysics3d::Vector3 n = normal.getUnit();
// For each point of the set // For each point of the set
for (unsigned int i=0; i<points.size(); ++i) { for (unsigned int i=0; i<points.size(); ++i) {
@ -194,21 +194,21 @@ inline std::vector<reactphysics3d::Vector3D> projectPointsOntoPlane(const std::v
// Compute the distance between a point "P" and a line (given by a point "A" and a vector "v") // Compute the distance between a point "P" and a line (given by a point "A" and a vector "v")
inline double computeDistanceBetweenPointAndLine(const reactphysics3d::Vector3D& P, const reactphysics3d::Vector3D& A, const reactphysics3d::Vector3D& v) { inline double computeDistanceBetweenPointAndLine(const reactphysics3d::Vector3& P, const reactphysics3d::Vector3& A, const reactphysics3d::Vector3& v) {
assert(v.length() != 0); assert(v.length() != 0);
return ((P-A).cross(v).length() / (v.length())); return ((P-A).cross(v).length() / (v.length()));
} }
// Compute the orthogonal projection of a point "P" on a line (given by a point "A" and a vector "v") // Compute the orthogonal projection of a point "P" on a line (given by a point "A" and a vector "v")
inline reactphysics3d::Vector3D computeOrthogonalProjectionOfPointOntoALine(const reactphysics3d::Vector3D& P, const reactphysics3d::Vector3D& A, const reactphysics3d::Vector3D& v) { inline reactphysics3d::Vector3 computeOrthogonalProjectionOfPointOntoALine(const reactphysics3d::Vector3& P, const reactphysics3d::Vector3& A, const reactphysics3d::Vector3& v) {
return (A + ((P-A).dot(v) / (v.dot(v))) * v); return (A + ((P-A).dot(v) / (v.dot(v))) * v);
} }
// Given a point P and 4 points that form a rectangle (point P and the 4 points have to be on the same plane) this method computes // Given a point P and 4 points that form a rectangle (point P and the 4 points have to be on the same plane) this method computes
// the point Q that is the nearest point to P that is inside (on a border of) the rectangle. The point P should be outside the rectangle. // the point Q that is the nearest point to P that is inside (on a border of) the rectangle. The point P should be outside the rectangle.
// The result point Q will be in a segment of the rectangle // The result point Q will be in a segment of the rectangle
inline reactphysics3d::Vector3D computeNearestPointOnRectangle(const reactphysics3d::Vector3D& P, const std::vector<reactphysics3d::Vector3D> rectangle) { inline reactphysics3d::Vector3 computeNearestPointOnRectangle(const reactphysics3d::Vector3& P, const std::vector<reactphysics3d::Vector3> rectangle) {
assert(rectangle.size() == 4); assert(rectangle.size() == 4);
double distPSegment1 = computeDistanceBetweenPointAndLine(P, rectangle[0], rectangle[1] - rectangle[0]); double distPSegment1 = computeDistanceBetweenPointAndLine(P, rectangle[0], rectangle[1] - rectangle[0]);
double distPSegment2 = computeDistanceBetweenPointAndLine(P, rectangle[1], rectangle[2] - rectangle[1]); double distPSegment2 = computeDistanceBetweenPointAndLine(P, rectangle[1], rectangle[2] - rectangle[1]);
@ -216,7 +216,7 @@ inline reactphysics3d::Vector3D computeNearestPointOnRectangle(const reactphysic
double distPSegment4 = computeDistanceBetweenPointAndLine(P, rectangle[3], rectangle[0] - rectangle[3]); double distPSegment4 = computeDistanceBetweenPointAndLine(P, rectangle[3], rectangle[0] - rectangle[3]);
double distSegment1Segment3 = computeDistanceBetweenPointAndLine(rectangle[0], rectangle[3], rectangle[3] - rectangle[2]); double distSegment1Segment3 = computeDistanceBetweenPointAndLine(rectangle[0], rectangle[3], rectangle[3] - rectangle[2]);
double distSegment2Segment4 = computeDistanceBetweenPointAndLine(rectangle[1], rectangle[3], rectangle[0] - rectangle[3]); double distSegment2Segment4 = computeDistanceBetweenPointAndLine(rectangle[1], rectangle[3], rectangle[0] - rectangle[3]);
Vector3D resultPoint; Vector3 resultPoint;
// Check if P is between the lines of the first pair of parallel segments of the rectangle // Check if P is between the lines of the first pair of parallel segments of the rectangle
if (distPSegment1 <= distSegment1Segment3 && distPSegment3 <= distSegment1Segment3) { if (distPSegment1 <= distSegment1Segment3 && distPSegment3 <= distSegment1Segment3) {
@ -271,12 +271,12 @@ inline reactphysics3d::Vector3D computeNearestPointOnRectangle(const reactphysic
// segment is between the points "seg2PointA" and "seg2PointB"). The result is the segment intersection (represented by the points "resultPointA" // segment is between the points "seg2PointA" and "seg2PointB"). The result is the segment intersection (represented by the points "resultPointA"
// and "resultPointB". Because the two given segments don't have to be on the same exact line, the result intersection segment will a segment // and "resultPointB". Because the two given segments don't have to be on the same exact line, the result intersection segment will a segment
// halway between the first and the second given segments. // halway between the first and the second given segments.
inline void computeParallelSegmentsIntersection(const reactphysics3d::Vector3D& seg1PointA, const reactphysics3d::Vector3D& seg1PointB, inline void computeParallelSegmentsIntersection(const reactphysics3d::Vector3& seg1PointA, const reactphysics3d::Vector3& seg1PointB,
const reactphysics3d::Vector3D& seg2PointA, const reactphysics3d::Vector3D& seg2PointB, const reactphysics3d::Vector3& seg2PointA, const reactphysics3d::Vector3& seg2PointB,
reactphysics3d::Vector3D& resultPointA, reactphysics3d::Vector3D& resultPointB) { reactphysics3d::Vector3& resultPointA, reactphysics3d::Vector3& resultPointB) {
// Compute the segment vectors // Compute the segment vectors
reactphysics3d::Vector3D d1 = seg1PointB - seg1PointA; reactphysics3d::Vector3 d1 = seg1PointB - seg1PointA;
reactphysics3d::Vector3D d2 = seg2PointB - seg2PointA; reactphysics3d::Vector3 d2 = seg2PointB - seg2PointA;
// The two segments should be parallel // The two segments should be parallel
assert(d1.isParallelWith(d2)); assert(d1.isParallelWith(d2));
@ -290,8 +290,8 @@ inline void computeParallelSegmentsIntersection(const reactphysics3d::Vector3D&
assert(!(projSeg2PointA > d1.length() && projSeg2PointB > d1.length())); assert(!(projSeg2PointA > d1.length() && projSeg2PointB > d1.length()));
// Compute the vector "v" from a point on the line 1 to the orthogonal point of the line 2 // Compute the vector "v" from a point on the line 1 to the orthogonal point of the line 2
reactphysics3d::Vector3D point = computeOrthogonalProjectionOfPointOntoALine(seg2PointA, seg1PointA, d1); reactphysics3d::Vector3 point = computeOrthogonalProjectionOfPointOntoALine(seg2PointA, seg1PointA, d1);
reactphysics3d::Vector3D v = seg2PointA - point; reactphysics3d::Vector3 v = seg2PointA - point;
// Return the segment intersection according to the configuration of two projection intervals // Return the segment intersection according to the configuration of two projection intervals
if (projSeg2PointA >= 0 && projSeg2PointA <= d1.length() && projSeg2PointB >= d1.length()) { if (projSeg2PointA >= 0 && projSeg2PointA <= d1.length() && projSeg2PointB >= d1.length()) {
@ -320,14 +320,14 @@ inline void computeParallelSegmentsIntersection(const reactphysics3d::Vector3D&
// also assume that the segment is not completely outside the clipping rectangle. // also assume that the segment is not completely outside the clipping rectangle.
// The segment is given by the two vertices in "segment" and the rectangle is given by the ordered vertices in "clipRectangle". // The segment is given by the two vertices in "segment" and the rectangle is given by the ordered vertices in "clipRectangle".
// This method returns the clipped segment. // This method returns the clipped segment.
inline std::vector<reactphysics3d::Vector3D> clipSegmentWithRectangleInPlane(const std::vector<reactphysics3d::Vector3D>& segment, const std::vector<reactphysics3d::Vector3D> clipRectangle) { inline std::vector<reactphysics3d::Vector3> clipSegmentWithRectangleInPlane(const std::vector<reactphysics3d::Vector3>& segment, const std::vector<reactphysics3d::Vector3> clipRectangle) {
double const epsilon = 0.01; double const epsilon = 0.01;
assert(segment.size() == 2); assert(segment.size() == 2);
assert(clipRectangle.size() == 4); assert(clipRectangle.size() == 4);
std::vector<reactphysics3d::Vector3D> inputSegment = segment; std::vector<reactphysics3d::Vector3> inputSegment = segment;
std::vector<reactphysics3d::Vector3D> outputSegment; std::vector<reactphysics3d::Vector3> outputSegment;
// For each edge of the clip rectangle // For each edge of the clip rectangle
for (unsigned int i=0; i<4; ++i) { for (unsigned int i=0; i<4; ++i) {
@ -335,13 +335,13 @@ inline std::vector<reactphysics3d::Vector3D> clipSegmentWithRectangleInPlane(con
// Current clipped segment // Current clipped segment
//assert(inputSegment.size() == 2); //assert(inputSegment.size() == 2);
reactphysics3d::Vector3D S = inputSegment[0]; reactphysics3d::Vector3 S = inputSegment[0];
reactphysics3d::Vector3D P = inputSegment[1]; reactphysics3d::Vector3 P = inputSegment[1];
// Edge of the clip rectangle // Edge of the clip rectangle
reactphysics3d::Vector3D A = clipRectangle[i]; reactphysics3d::Vector3 A = clipRectangle[i];
reactphysics3d::Vector3D B = clipRectangle[ (i+1) % 4]; reactphysics3d::Vector3 B = clipRectangle[ (i+1) % 4];
reactphysics3d::Vector3D planeNormal = clipRectangle[(i+2) % 4] - clipRectangle[(i+1) % 4]; reactphysics3d::Vector3 planeNormal = clipRectangle[(i+2) % 4] - clipRectangle[(i+1) % 4];
// If the point P is inside the clip plane // If the point P is inside the clip plane
if (planeNormal.dot(P-A) >= 0.0 - epsilon) { if (planeNormal.dot(P-A) >= 0.0 - epsilon) {
@ -352,7 +352,7 @@ inline std::vector<reactphysics3d::Vector3D> clipSegmentWithRectangleInPlane(con
} }
else { // P is inside and S is outside the clip plane else { // P is inside and S is outside the clip plane
// Compute the intersection point between the segment SP and the clip plane // Compute the intersection point between the segment SP and the clip plane
reactphysics3d::Vector3D intersectPoint = computeLinesIntersection(S, P-S, A, B-A); reactphysics3d::Vector3 intersectPoint = computeLinesIntersection(S, P-S, A, B-A);
outputSegment.push_back(P); outputSegment.push_back(P);
outputSegment.push_back(intersectPoint); outputSegment.push_back(intersectPoint);
@ -360,7 +360,7 @@ inline std::vector<reactphysics3d::Vector3D> clipSegmentWithRectangleInPlane(con
} }
else if (planeNormal.dot(S-A) > 0.0 - epsilon) { // P is outside and S is inside the clip plane else if (planeNormal.dot(S-A) > 0.0 - epsilon) { // P is outside and S is inside the clip plane
// Compute the intersection point between the segment SP and the clip plane // Compute the intersection point between the segment SP and the clip plane
reactphysics3d::Vector3D intersectPoint = computeLinesIntersection(S, P-S, A, B-A); reactphysics3d::Vector3 intersectPoint = computeLinesIntersection(S, P-S, A, B-A);
outputSegment.push_back(S); outputSegment.push_back(S);
outputSegment.push_back(intersectPoint); outputSegment.push_back(intersectPoint);
@ -376,12 +376,12 @@ inline std::vector<reactphysics3d::Vector3D> clipSegmentWithRectangleInPlane(con
// This method uses the Sutherland-Hodgman clipping algorithm to clip a subject polygon (given by the ordered 3D vertices in "subjectPolygon") using // This method uses the Sutherland-Hodgman clipping algorithm to clip a subject polygon (given by the ordered 3D vertices in "subjectPolygon") using
// a rectangle polygon (given by the ordered 3D vertices in "clipRectangle"). The subject polygon and the clip rectangle are in 3D but we assumed that // a rectangle polygon (given by the ordered 3D vertices in "clipRectangle"). The subject polygon and the clip rectangle are in 3D but we assumed that
// they are on a same plane in 3D. The method returns the ordered 3D vertices of the subject polygon clipped using the rectangle polygon. // they are on a same plane in 3D. The method returns the ordered 3D vertices of the subject polygon clipped using the rectangle polygon.
inline std::vector<reactphysics3d::Vector3D> clipPolygonWithRectangleInPlane(const std::vector<reactphysics3d::Vector3D>& subjectPolygon, const std::vector<reactphysics3d::Vector3D>& clipRectangle) { inline std::vector<reactphysics3d::Vector3> clipPolygonWithRectangleInPlane(const std::vector<reactphysics3d::Vector3>& subjectPolygon, const std::vector<reactphysics3d::Vector3>& clipRectangle) {
double const epsilon = 0.1; double const epsilon = 0.1;
assert(clipRectangle.size() == 4); assert(clipRectangle.size() == 4);
std::vector<reactphysics3d::Vector3D> outputPolygon; std::vector<reactphysics3d::Vector3> outputPolygon;
std::vector<reactphysics3d::Vector3D> inputPolygon = subjectPolygon; std::vector<reactphysics3d::Vector3> inputPolygon = subjectPolygon;
// For each edge of the clip rectangle // For each edge of the clip rectangle
for (unsigned int i=0; i<4; ++i) { for (unsigned int i=0; i<4; ++i) {
@ -389,14 +389,14 @@ inline std::vector<reactphysics3d::Vector3D> clipPolygonWithRectangleInPlane(con
// Each edge defines a clip plane. The clip plane is define by a point on this plane (a vertice of the current edge) and // Each edge defines a clip plane. The clip plane is define by a point on this plane (a vertice of the current edge) and
// a plane normal (because we are using a clip rectangle, the plane normal is the next edge of the clip rectangle). // a plane normal (because we are using a clip rectangle, the plane normal is the next edge of the clip rectangle).
reactphysics3d::Vector3D planeNormal = clipRectangle[(i+2) % 4] - clipRectangle[(i+1) % 4]; reactphysics3d::Vector3 planeNormal = clipRectangle[(i+2) % 4] - clipRectangle[(i+1) % 4];
reactphysics3d::Vector3D A = clipRectangle[i]; // Segment AB is the current segment of the "clipRectangle" reactphysics3d::Vector3 A = clipRectangle[i]; // Segment AB is the current segment of the "clipRectangle"
reactphysics3d::Vector3D B = clipRectangle[(i+1) % 4]; reactphysics3d::Vector3 B = clipRectangle[(i+1) % 4];
reactphysics3d::Vector3D S = inputPolygon[0]; reactphysics3d::Vector3 S = inputPolygon[0];
// For each vertex of the subject polygon // For each vertex of the subject polygon
for (unsigned int j=0; j<inputPolygon.size(); ++j) { for (unsigned int j=0; j<inputPolygon.size(); ++j) {
reactphysics3d::Vector3D P = inputPolygon[(j+1) % inputPolygon.size()]; reactphysics3d::Vector3 P = inputPolygon[(j+1) % inputPolygon.size()];
// If the point P is inside the clip plane // If the point P is inside the clip plane
double test = planeNormal.dot(P-A); double test = planeNormal.dot(P-A);
@ -407,7 +407,7 @@ inline std::vector<reactphysics3d::Vector3D> clipPolygonWithRectangleInPlane(con
} }
else { // If the point S is outside the clip plane else { // If the point S is outside the clip plane
// Compute the intersection point between the segment SP and the clip plane // Compute the intersection point between the segment SP and the clip plane
reactphysics3d::Vector3D intersectPoint = computeLinesIntersection(S, P-S, A, B-A); reactphysics3d::Vector3 intersectPoint = computeLinesIntersection(S, P-S, A, B-A);
outputPolygon.push_back(intersectPoint); outputPolygon.push_back(intersectPoint);
outputPolygon.push_back(P); outputPolygon.push_back(P);
@ -415,7 +415,7 @@ inline std::vector<reactphysics3d::Vector3D> clipPolygonWithRectangleInPlane(con
} }
else if (planeNormal.dot(S-A) > 0.0) { else if (planeNormal.dot(S-A) > 0.0) {
// Compute the intersection point between the segment SP and the clip plane // Compute the intersection point between the segment SP and the clip plane
reactphysics3d::Vector3D intersectPoint = computeLinesIntersection(S, P-S, A, B-A); reactphysics3d::Vector3 intersectPoint = computeLinesIntersection(S, P-S, A, B-A);
outputPolygon.push_back(intersectPoint); outputPolygon.push_back(intersectPoint);
} }
@ -430,8 +430,8 @@ inline std::vector<reactphysics3d::Vector3D> clipPolygonWithRectangleInPlane(con
// Compute the intersection point between a line and a plane in 3D space. There must be an intersection, therefore the // Compute the intersection point between a line and a plane in 3D space. There must be an intersection, therefore the
// the lineVector must not be orthogonal to the planeNormal. // the lineVector must not be orthogonal to the planeNormal.
inline reactphysics3d::Vector3D intersectLineWithPlane(const reactphysics3d::Vector3D& linePoint, const reactphysics3d::Vector3D& lineVector, inline reactphysics3d::Vector3 intersectLineWithPlane(const reactphysics3d::Vector3& linePoint, const reactphysics3d::Vector3& lineVector,
const reactphysics3d::Vector3D& planePoint, const reactphysics3d::Vector3D& planeNormal) { const reactphysics3d::Vector3& planePoint, const reactphysics3d::Vector3& planeNormal) {
assert(!approxEqual(lineVector.dot(planeNormal), 0.0)); assert(!approxEqual(lineVector.dot(planeNormal), 0.0));
// The plane is represented by the equation planeNormal dot X = d where X is a point of the plane // The plane is represented by the equation planeNormal dot X = d where X is a point of the plane

View File

@ -39,7 +39,7 @@ AABB::AABB() : bodyPointer(0) {
} }
// Constructor // Constructor
AABB::AABB(const Transform& transform, const Vector3D& extents) : bodyPointer(0) { AABB::AABB(const Transform& transform, const Vector3& extents) : bodyPointer(0) {
update(transform, extents); update(transform, extents);
} }

View File

@ -44,39 +44,39 @@ class Body;
*/ */
class AABB { class AABB {
private : private :
Vector3D minCoordinates; // Minimum world coordinates of the AABB on the x,y and z axis Vector3 minCoordinates; // Minimum world coordinates of the AABB on the x,y and z axis
Vector3D maxCoordinates; // Maximum world coordinates of the AABB on the x,y and z axis Vector3 maxCoordinates; // Maximum world coordinates of the AABB on the x,y and z axis
Body* bodyPointer; // Pointer to the owner body (not the abstract class Body but its derivative which is instanciable) Body* bodyPointer; // Pointer to the owner body (not the abstract class Body but its derivative which is instanciable)
public : public :
AABB(); // Constructor AABB(); // Constructor
AABB(const Transform& transform, const Vector3D& extents); // Constructor AABB(const Transform& transform, const Vector3& extents); // Constructor
virtual ~AABB(); // Destructor virtual ~AABB(); // Destructor
Vector3D getCenter() const; // Return the center point Vector3 getCenter() const; // Return the center point
const Vector3D& getMinCoordinates() const; // Return the minimum coordinates of the AABB const Vector3& getMinCoordinates() const; // Return the minimum coordinates of the AABB
const Vector3D& getMaxCoordinates() const; // Return the maximum coordinates of the AABB const Vector3& getMaxCoordinates() const; // Return the maximum coordinates of the AABB
Body* getBodyPointer() const; // Return a pointer to the owner body Body* getBodyPointer() const; // Return a pointer to the owner body
void setBodyPointer(Body* bodyPointer); // Set the body pointer void setBodyPointer(Body* bodyPointer); // Set the body pointer
bool testCollision(const AABB& aabb) const; // Return true if the current AABB is overlapping is the AABB in argument bool testCollision(const AABB& aabb) const; // Return true if the current AABB is overlapping is the AABB in argument
virtual void update(const Transform& newTransform, const Vector3D& extents); // Update the oriented bounding box orientation according to a new orientation of the rigid body virtual void update(const Transform& newTransform, const Vector3& extents); // Update the oriented bounding box orientation according to a new orientation of the rigid body
#ifdef VISUAL_DEBUG #ifdef VISUAL_DEBUG
virtual void draw() const; // Draw the AABB (only for testing purpose) virtual void draw() const; // Draw the AABB (only for testing purpose)
#endif #endif
}; };
// Return the center point of the AABB in world coordinates // Return the center point of the AABB in world coordinates
inline Vector3D AABB::getCenter() const { inline Vector3 AABB::getCenter() const {
return (minCoordinates + maxCoordinates) * 0.5; return (minCoordinates + maxCoordinates) * 0.5;
} }
// Return the minimum coordinates of the AABB // Return the minimum coordinates of the AABB
inline const Vector3D& AABB::getMinCoordinates() const { inline const Vector3& AABB::getMinCoordinates() const {
return minCoordinates; return minCoordinates;
} }
// Return the maximum coordinates of the AABB // Return the maximum coordinates of the AABB
inline const Vector3D& AABB::getMaxCoordinates() const { inline const Vector3& AABB::getMaxCoordinates() const {
return maxCoordinates; return maxCoordinates;
} }
@ -100,9 +100,9 @@ inline bool AABB::testCollision(const AABB& aabb) const {
} }
// Update the world minimum and maximum coordinates of the AABB on the three x,y and z axis // Update the world minimum and maximum coordinates of the AABB on the three x,y and z axis
inline void AABB::update(const Transform& newTransform, const Vector3D& extents) { inline void AABB::update(const Transform& newTransform, const Vector3& extents) {
Matrix3x3 worldAxis = newTransform.getOrientation().getMatrix().getAbsoluteMatrix(); Matrix3x3 worldAxis = newTransform.getOrientation().getMatrix().getAbsoluteMatrix();
Vector3D worldExtents = Vector3D(worldAxis.getColumn(0).dot(extents), Vector3 worldExtents = Vector3(worldAxis.getColumn(0).dot(extents),
worldAxis.getColumn(1).dot(extents), worldAxis.getColumn(1).dot(extents),
worldAxis.getColumn(2).dot(extents)); worldAxis.getColumn(2).dot(extents));
minCoordinates = newTransform.getPosition() - worldExtents; minCoordinates = newTransform.getPosition() - worldExtents;

View File

@ -36,7 +36,7 @@ using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
BoxShape::BoxShape(const Vector3D& extent) : extent(extent) { BoxShape::BoxShape(const Vector3& extent) : extent(extent) {
} }

View File

@ -46,16 +46,16 @@ namespace reactphysics3d {
*/ */
class BoxShape : public Shape { class BoxShape : public Shape {
private : private :
Vector3D extent; // Extent sizes of the box Vector3 extent; // Extent sizes of the box
public : public :
BoxShape(const Vector3D& extent); // Constructor BoxShape(const Vector3& extent); // Constructor
virtual ~BoxShape(); // Destructor virtual ~BoxShape(); // Destructor
const Vector3D& getExtent() const; // Return the extents of the box const Vector3& getExtent() const; // Return the extents of the box
void setExtent(const Vector3D& extent); // Set the extents of the box void setExtent(const Vector3& extent); // Set the extents of the box
virtual Vector3D getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction virtual Vector3 getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction
virtual Vector3D getLocalSupportPoint(const Vector3D& direction, double margin=0.0) const; // Return a local support point in a given direction virtual Vector3 getLocalSupportPoint(const Vector3& direction, double margin=0.0) const; // Return a local support point in a given direction
#ifdef VISUAL_DEBUG #ifdef VISUAL_DEBUG
virtual void draw() const; // Draw the Box (only for testing purpose) virtual void draw() const; // Draw the Box (only for testing purpose)
@ -63,26 +63,26 @@ class BoxShape : public Shape {
}; };
// Return the extents of the box // Return the extents of the box
inline const Vector3D& BoxShape::getExtent() const { inline const Vector3& BoxShape::getExtent() const {
return extent; return extent;
} }
// Set the extents of the box // Set the extents of the box
inline void BoxShape::setExtent(const Vector3D& extent) { inline void BoxShape::setExtent(const Vector3& extent) {
this->extent = extent; this->extent = extent;
} }
// Return the local extents of the shape (half-width) in x,y and z local direction // Return the local extents of the shape (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 Vector3D BoxShape::getLocalExtents(double margin) const { inline Vector3 BoxShape::getLocalExtents(double margin) const {
return extent + Vector3D(margin, margin, margin); return extent + Vector3(margin, margin, margin);
} }
// Return a local support point in a given direction // Return a local support point in a given direction
inline Vector3D BoxShape::getLocalSupportPoint(const Vector3D& direction, double margin) const { inline Vector3 BoxShape::getLocalSupportPoint(const Vector3& direction, double margin) const {
assert(margin >= 0.0); assert(margin >= 0.0);
return Vector3D(direction.getX() < 0.0 ? -extent.getX()-margin : extent.getX()+margin, return Vector3(direction.getX() < 0.0 ? -extent.getX()-margin : extent.getX()+margin,
direction.getY() < 0.0 ? -extent.getY()-margin : extent.getY()+margin, direction.getY() < 0.0 ? -extent.getY()-margin : extent.getY()+margin,
direction.getZ() < 0.0 ? -extent.getZ()-margin : extent.getZ()+margin); direction.getZ() < 0.0 ? -extent.getZ()-margin : extent.getZ()+margin);
} }

View File

@ -48,30 +48,30 @@ ConeShape::~ConeShape() {
} }
// Return a local support point in a given direction // Return a local support point in a given direction
inline Vector3D ConeShape::getLocalSupportPoint(const Vector3D& direction, double margin) const { inline Vector3 ConeShape::getLocalSupportPoint(const Vector3& direction, double margin) const {
assert(margin >= 0.0); assert(margin >= 0.0);
const Vector3D& v = direction; const Vector3& v = direction;
double sinThetaTimesLengthV = sinTheta * v.length(); double sinThetaTimesLengthV = sinTheta * v.length();
Vector3D supportPoint; Vector3 supportPoint;
if (v.getY() >= sinThetaTimesLengthV) { if (v.getY() >= sinThetaTimesLengthV) {
supportPoint = Vector3D(0.0, halfHeight, 0.0); supportPoint = Vector3(0.0, halfHeight, 0.0);
} }
else { else {
double projectedLength = sqrt(v.getX() * v.getX() + v.getZ() * v.getZ()); double projectedLength = sqrt(v.getX() * v.getX() + v.getZ() * v.getZ());
if (projectedLength > MACHINE_EPSILON) { if (projectedLength > MACHINE_EPSILON) {
double d = radius / projectedLength; double d = radius / projectedLength;
supportPoint = Vector3D(v.getX() * d, -halfHeight, v.getZ() * d); supportPoint = Vector3(v.getX() * d, -halfHeight, v.getZ() * d);
} }
else { else {
supportPoint = Vector3D(radius, -halfHeight, 0.0); supportPoint = Vector3(radius, -halfHeight, 0.0);
} }
} }
// Add the margin to the support point // Add the margin to the support point
if (margin != 0.0) { if (margin != 0.0) {
Vector3D unitVec(0.0, -1.0, 0.0); Vector3 unitVec(0.0, -1.0, 0.0);
if (v.lengthSquare() > MACHINE_EPSILON * MACHINE_EPSILON) { if (v.lengthSquare() > MACHINE_EPSILON * MACHINE_EPSILON) {
unitVec = v.getUnit(); unitVec = v.getUnit();
} }

View File

@ -29,9 +29,6 @@
#include "Shape.h" #include "Shape.h"
#include "../mathematics/mathematics.h" #include "../mathematics/mathematics.h"
// TODO : CHECK THAT THE AABB IS CORRECT
// TODO : TEST THIS SHAPE WITH GJK AND EPA ALGORITHMS
// ReactPhysics3D namespace // ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -59,8 +56,8 @@ class ConeShape : public Shape {
void setRadius(double radius); // Set the radius void setRadius(double radius); // Set the radius
double getHeight() const; // Return the height double getHeight() const; // Return the height
void setHeight(double height); // Set the height void setHeight(double height); // Set the height
virtual Vector3D getLocalSupportPoint(const Vector3D& direction, double margin=0.0) const; // Return a support point in a given direction virtual Vector3 getLocalSupportPoint(const Vector3& direction, double margin=0.0) const; // Return a support point in a given direction
virtual Vector3D getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction virtual Vector3 getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction
#ifdef VISUAL_DEBUG #ifdef VISUAL_DEBUG
@ -95,8 +92,8 @@ inline void ConeShape::setHeight(double height) {
} }
// Return the local extents in x,y and z direction // Return the local extents in x,y and z direction
inline Vector3D ConeShape::getLocalExtents(double margin) const { inline Vector3 ConeShape::getLocalExtents(double margin) const {
return Vector3D(radius + margin, halfHeight + margin, radius + margin); return Vector3(radius + margin, halfHeight + margin, radius + margin);
} }
}; // End of the ReactPhysics3D namespace }; // End of the ReactPhysics3D namespace

View File

@ -42,12 +42,12 @@ CylinderShape::~CylinderShape() {
} }
// Return a local support point in a given direction // Return a local support point in a given direction
Vector3D CylinderShape::getLocalSupportPoint(const Vector3D& direction, double margin) const { Vector3 CylinderShape::getLocalSupportPoint(const Vector3& direction, double margin) const {
assert(margin >= 0.0); assert(margin >= 0.0);
Vector3D supportPoint(0.0, 0.0, 0.0); Vector3 supportPoint(0.0, 0.0, 0.0);
double uDotv = direction.getY(); double uDotv = direction.getY();
Vector3D w(direction.getX(), 0.0, direction.getZ()); Vector3 w(direction.getX(), 0.0, direction.getZ());
double lengthW = sqrt(direction.getX() * direction.getX() + direction.getZ() * direction.getZ()); double lengthW = sqrt(direction.getX() * direction.getX() + direction.getZ() * direction.getZ());
if (lengthW != 0.0) { if (lengthW != 0.0) {
@ -62,7 +62,7 @@ Vector3D CylinderShape::getLocalSupportPoint(const Vector3D& direction, double m
// Add the margin to the support point // Add the margin to the support point
if (margin != 0.0) { if (margin != 0.0) {
Vector3D unitVec(0.0, 1.0, 0.0); Vector3 unitVec(0.0, 1.0, 0.0);
if (direction.lengthSquare() > MACHINE_EPSILON * MACHINE_EPSILON) { if (direction.lengthSquare() > MACHINE_EPSILON * MACHINE_EPSILON) {
unitVec = direction.getUnit(); unitVec = direction.getUnit();
} }

View File

@ -56,8 +56,8 @@ class CylinderShape : public Shape {
void setRadius(double radius); // Set the radius void setRadius(double radius); // Set the radius
double getHeight() const; // Return the height double getHeight() const; // Return the height
void setHeight(double height); // Set the height void setHeight(double height); // Set the height
virtual Vector3D getLocalSupportPoint(const Vector3D& direction, double margin=0.0) const; // Return a support point in a given direction virtual Vector3 getLocalSupportPoint(const Vector3& direction, double margin=0.0) const; // Return a support point in a given direction
virtual Vector3D getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction virtual Vector3 getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction
#ifdef VISUAL_DEBUG #ifdef VISUAL_DEBUG
@ -86,8 +86,8 @@ inline void CylinderShape::setHeight(double height) {
} }
// Return the local extents in x,y and z direction // Return the local extents in x,y and z direction
inline Vector3D CylinderShape::getLocalExtents(double margin) const { inline Vector3 CylinderShape::getLocalExtents(double margin) const {
return Vector3D(radius + margin, halfHeight + margin, radius + margin); return Vector3(radius + margin, halfHeight + margin, radius + margin);
} }
}; // End of the ReactPhysics3D namespace }; // End of the ReactPhysics3D namespace

View File

@ -28,7 +28,7 @@
// Libraries // Libraries
#include <cassert> #include <cassert>
#include "../mathematics/Vector3D.h" #include "../mathematics/Vector3.h"
// ReactPhysics3D namespace // ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -52,8 +52,8 @@ class Shape {
Body* getBodyPointer() const; // Return the body pointer Body* getBodyPointer() const; // Return the body pointer
void setBodyPointer(Body* bodyPointer); // Set the body pointer void setBodyPointer(Body* bodyPointer); // Set the body pointer
virtual Vector3D getLocalSupportPoint(const Vector3D& direction, double margin=0.0) const=0; // Return a local support point in a given direction virtual Vector3 getLocalSupportPoint(const Vector3& direction, double margin=0.0) const=0; // Return a local support point in a given direction
virtual Vector3D getLocalExtents(double margin=0.0) const=0; // Return the local extents in x,y and z direction virtual Vector3 getLocalExtents(double margin=0.0) const=0; // Return the local extents in x,y and z direction
}; };
// Return the body pointer // Return the body pointer

View File

@ -48,8 +48,8 @@ class SphereShape : public Shape {
double getRadius() const; // Return the radius of the sphere double getRadius() const; // Return the radius of the sphere
void setRadius(double radius); // Set the radius of the sphere void setRadius(double radius); // Set the radius of the sphere
virtual Vector3D getLocalSupportPoint(const Vector3D& direction, double margin=0.0) const; // Return a local support point in a given direction virtual Vector3 getLocalSupportPoint(const Vector3& direction, double margin=0.0) const; // Return a local support point in a given direction
virtual Vector3D getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction virtual Vector3 getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction
#ifdef VISUAL_DEBUG #ifdef VISUAL_DEBUG
virtual void draw() const; // Draw the sphere (only for testing purpose) virtual void draw() const; // Draw the sphere (only for testing purpose)
@ -67,7 +67,7 @@ inline void SphereShape::setRadius(double radius) {
} }
// Return a local support point in a given direction // Return a local support point in a given direction
inline Vector3D SphereShape::getLocalSupportPoint(const Vector3D& direction, double margin) const { inline Vector3 SphereShape::getLocalSupportPoint(const Vector3& direction, double margin) const {
assert(margin >= 0.0); assert(margin >= 0.0);
double length = direction.length(); double length = direction.length();
@ -79,13 +79,13 @@ inline Vector3D SphereShape::getLocalSupportPoint(const Vector3D& direction, dou
// If the direction vector is the zero vector we return a point on the // If the direction vector is the zero vector we return a point on the
// boundary of the sphere // boundary of the sphere
return Vector3D(0, radius + margin, 0); return Vector3(0, radius + margin, 0);
} }
// Return the local extents of the shape (half-width) in x,y and z local direction // Return the local extents of the shape (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 Vector3D SphereShape::getLocalExtents(double margin) const { inline Vector3 SphereShape::getLocalExtents(double margin) const {
return Vector3D(radius + margin, radius + margin, radius + margin); return Vector3(radius + margin, radius + margin, radius + margin);
} }
}; // End of the ReactPhysics3D namespace }; // End of the ReactPhysics3D namespace