Correction of a bug in collision detection and creation of new collision shapes
git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@434 92aac97c-a6ce-11dd-a772-7fcde58d38e6
This commit is contained in:
parent
0de337cfe5
commit
00b9fc45dc
|
@ -43,7 +43,7 @@ Body::Body(const Transform& transform, Shape* shape, double mass)
|
|||
oldTransform = transform;
|
||||
|
||||
// Create the AABB for broad-phase collision detection
|
||||
aabb = new AABB(transform, shape->getLocalExtents());
|
||||
aabb = new AABB(transform, shape->getLocalExtents(OBJECT_MARGIN));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
|
|
@ -151,7 +151,7 @@ inline void Body::updateOldTransform() {
|
|||
// Update the rigid body in order to reflect a change in the body state
|
||||
inline void Body::updateAABB() {
|
||||
// Update the AABB
|
||||
aabb->update(transform, shape->getLocalExtents());
|
||||
aabb->update(transform, shape->getLocalExtents(OBJECT_MARGIN));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -146,18 +146,18 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
|
|||
Vector3D v3 = rotationMat * v2;
|
||||
|
||||
// Compute the support point in the direction of v1
|
||||
suppPointsA[2] = shape1->getSupportPoint(v1, OBJECT_MARGIN);
|
||||
suppPointsB[2] = shape2ToShape1 * shape2->getSupportPoint(rotateToShape2 * v1.getOpposite(), OBJECT_MARGIN);
|
||||
suppPointsA[2] = shape1->getLocalSupportPoint(v1, OBJECT_MARGIN);
|
||||
suppPointsB[2] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v1.getOpposite(), OBJECT_MARGIN);
|
||||
points[2] = suppPointsA[2] - suppPointsB[2];
|
||||
|
||||
// Compute the support point in the direction of v2
|
||||
suppPointsA[3] = shape1->getSupportPoint(v2, OBJECT_MARGIN);
|
||||
suppPointsB[3] = shape2ToShape1 * shape2->getSupportPoint(rotateToShape2 * v2.getOpposite(), OBJECT_MARGIN);
|
||||
suppPointsA[3] = shape1->getLocalSupportPoint(v2, OBJECT_MARGIN);
|
||||
suppPointsB[3] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v2.getOpposite(), OBJECT_MARGIN);
|
||||
points[3] = suppPointsA[3] - suppPointsB[3];
|
||||
|
||||
// Compute the support point in the direction of v3
|
||||
suppPointsA[4] = shape1->getSupportPoint(v3, OBJECT_MARGIN);
|
||||
suppPointsB[4] = shape2ToShape1 * shape2->getSupportPoint(rotateToShape2 * v3.getOpposite(), OBJECT_MARGIN);
|
||||
suppPointsA[4] = shape1->getLocalSupportPoint(v3, OBJECT_MARGIN);
|
||||
suppPointsB[4] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v3.getOpposite(), OBJECT_MARGIN);
|
||||
points[4] = suppPointsA[4] - suppPointsB[4];
|
||||
|
||||
// Now we have an hexahedron (two tetrahedron glued together). We can simply keep the
|
||||
|
@ -173,9 +173,9 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
|
|||
}
|
||||
else if (isOriginInTetrahedron(points[1], points[2], points[3], points[4]) == 0) { // If the origin is in the tetrahedron of points 1, 2, 3, 4
|
||||
// We use the point 4 instead of point 0 for the initial tetrahedron
|
||||
suppPointsA[0] = suppPointsA[0];
|
||||
suppPointsB[0] = suppPointsB[0];
|
||||
points[0] = points[0];
|
||||
suppPointsA[0] = suppPointsA[4];
|
||||
suppPointsB[0] = suppPointsB[4];
|
||||
points[0] = points[4];
|
||||
}
|
||||
else {
|
||||
// The origin is not in the initial polytope
|
||||
|
@ -251,11 +251,11 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
|
|||
Vector3D n = v1.cross(v2);
|
||||
|
||||
// Compute the two new vertices to obtain a hexahedron
|
||||
suppPointsA[3] = shape1->getSupportPoint(n, OBJECT_MARGIN);
|
||||
suppPointsB[3] = shape2ToShape1 * shape2->getSupportPoint(rotateToShape2 * n.getOpposite(), OBJECT_MARGIN);
|
||||
suppPointsA[3] = shape1->getLocalSupportPoint(n, OBJECT_MARGIN);
|
||||
suppPointsB[3] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * n.getOpposite(), OBJECT_MARGIN);
|
||||
points[3] = suppPointsA[3] - suppPointsB[3];
|
||||
suppPointsA[4] = shape1->getSupportPoint(n.getOpposite(), OBJECT_MARGIN);
|
||||
suppPointsB[4] = shape2ToShape1 * shape2->getSupportPoint(rotateToShape2 * n, OBJECT_MARGIN);
|
||||
suppPointsA[4] = shape1->getLocalSupportPoint(n.getOpposite(), OBJECT_MARGIN);
|
||||
suppPointsB[4] = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * n, OBJECT_MARGIN);
|
||||
points[4] = suppPointsA[4] - suppPointsB[4];
|
||||
|
||||
// Construct the triangle faces
|
||||
|
@ -324,8 +324,8 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
|
|||
}
|
||||
|
||||
// Compute the support point of the Minkowski difference (A-B) in the closest point direction
|
||||
suppPointsA[nbVertices] = shape1->getSupportPoint(triangle->getClosestPoint(), OBJECT_MARGIN);
|
||||
suppPointsB[nbVertices] = shape2ToShape1 *shape2->getSupportPoint(rotateToShape2 * triangle->getClosestPoint().getOpposite(), OBJECT_MARGIN);
|
||||
suppPointsA[nbVertices] = shape1->getLocalSupportPoint(triangle->getClosestPoint(), OBJECT_MARGIN);
|
||||
suppPointsB[nbVertices] = shape2ToShape1 *shape2->getLocalSupportPoint(rotateToShape2 * triangle->getClosestPoint().getOpposite(), OBJECT_MARGIN);
|
||||
points[nbVertices] = suppPointsA[nbVertices] - suppPointsB[nbVertices];
|
||||
|
||||
int indexNewVertex = nbVertices;
|
||||
|
@ -364,7 +364,6 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
} while(nbTriangles > 0 && triangleHeap[0]->getDistSquare() <= upperBoundSquarePenDepth);
|
||||
|
||||
// Compute the contact info (in world-space)
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// TODO : Check that allocated memory is correctly deleted
|
||||
|
||||
// Constructor
|
||||
GJKAlgorithm::GJKAlgorithm() {
|
||||
|
||||
|
@ -91,15 +89,15 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
|
|||
// Get the last point V (last separating axis)
|
||||
// TODO : Implement frame coherence. For each pair of body, store
|
||||
// the last separating axis and use it to initialize the v vector
|
||||
Vector3D v(0.0, 1.0, 0.0);
|
||||
Vector3D v(1.0, 1.0, 1.0);
|
||||
|
||||
// Initialize the upper bound for the square distance
|
||||
double distSquare = DBL_MAX;
|
||||
|
||||
do {
|
||||
// Compute the support points for original objects (without margins) A and B
|
||||
suppA = shape1->getSupportPoint(v.getOpposite());
|
||||
suppB = shape2ToShape1 * shape2->getSupportPoint(rotateToShape2 * v);
|
||||
suppA = shape1->getLocalSupportPoint(v.getOpposite());
|
||||
suppB = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v);
|
||||
|
||||
// Compute the support point for the Minkowski difference A-B
|
||||
w = suppA - suppB;
|
||||
|
@ -208,10 +206,6 @@ bool GJKAlgorithm::testCollision(const Shape* shape1, const Transform& transform
|
|||
// There is an intersection, therefore we return true
|
||||
return true;
|
||||
}
|
||||
|
||||
double test = simplex.getMaxLengthSquareOfAPoint(); // TODO : Remove this
|
||||
test = 4.5;
|
||||
|
||||
} while(!simplex.isFull() && distSquare > MACHINE_EPSILON * simplex.getMaxLengthSquareOfAPoint());
|
||||
|
||||
// The objects (without margins) intersect. Therefore, we run the GJK algorithm again but on the
|
||||
|
@ -245,8 +239,8 @@ bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(const Shape* const
|
|||
|
||||
do {
|
||||
// Compute the support points for the enlarged object A and B
|
||||
suppA = shape1->getSupportPoint(v.getOpposite(), OBJECT_MARGIN);
|
||||
suppB = shape2ToShape1 * shape2->getSupportPoint(rotateToShape2 * v, OBJECT_MARGIN);
|
||||
suppA = shape1->getLocalSupportPoint(v.getOpposite(), OBJECT_MARGIN);
|
||||
suppB = shape2ToShape1 * shape2->getLocalSupportPoint(rotateToShape2 * v, OBJECT_MARGIN);
|
||||
|
||||
// Compute the support point for the Minkowski difference A-B
|
||||
w = suppA - suppB;
|
||||
|
|
|
@ -63,6 +63,7 @@ class Vector3D {
|
|||
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
|
||||
|
@ -148,6 +149,11 @@ inline double Vector3D::length() const {
|
|||
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);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "shapes/BoxShape.h"
|
||||
#include "shapes/SphereShape.h"
|
||||
#include "shapes/ConeShape.h"
|
||||
#include "shapes/CylinderShape.h"
|
||||
#include "shapes/AABB.h"
|
||||
|
||||
// Alias to the ReactPhysics3D namespace
|
||||
|
|
|
@ -60,9 +60,9 @@ class AABB {
|
|||
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
|
||||
virtual void update(const Transform& newTransform, const Vector3D& extents); // Update the oriented bounding box orientation according to a new orientation of the rigid body
|
||||
#ifdef VISUAL_DEBUG
|
||||
virtual void draw() const; // Draw the AABB (only for testing purpose)
|
||||
#endif
|
||||
#ifdef VISUAL_DEBUG
|
||||
virtual void draw() const; // Draw the AABB (only for testing purpose)
|
||||
#endif
|
||||
};
|
||||
|
||||
// Return the center point of the AABB in world coordinates
|
||||
|
@ -93,22 +93,18 @@ inline void AABB::setBodyPointer(Body* bodyPointer) {
|
|||
// Return true if the current AABB is overlapping with the AABB in argument
|
||||
// Two AABB overlap if they overlap in the three x, y and z axis at the same time
|
||||
inline bool AABB::testCollision(const AABB& aabb) const {
|
||||
if (maxCoordinates.getX() + OBJECT_MARGIN < aabb.minCoordinates.getX() - OBJECT_MARGIN ||
|
||||
aabb.maxCoordinates.getX() + OBJECT_MARGIN < minCoordinates.getX() - OBJECT_MARGIN) return false;
|
||||
if (maxCoordinates.getY() + OBJECT_MARGIN < aabb.minCoordinates.getY() - OBJECT_MARGIN ||
|
||||
aabb.maxCoordinates.getY() + OBJECT_MARGIN < minCoordinates.getY() - OBJECT_MARGIN) return false;
|
||||
if (maxCoordinates.getZ() + OBJECT_MARGIN < aabb.minCoordinates.getZ() - OBJECT_MARGIN ||
|
||||
aabb.maxCoordinates.getZ() + OBJECT_MARGIN < minCoordinates.getZ() - OBJECT_MARGIN) return false;
|
||||
if (maxCoordinates.getX() < aabb.minCoordinates.getX() || aabb.maxCoordinates.getX() < minCoordinates.getX()) return false;
|
||||
if (maxCoordinates.getY() < aabb.minCoordinates.getY() || aabb.maxCoordinates.getY() < minCoordinates.getY()) return false;
|
||||
if (maxCoordinates.getZ() < aabb.minCoordinates.getZ() || aabb.maxCoordinates.getZ() < minCoordinates.getZ()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
Vector3D localExtents = extents + Vector3D(OBJECT_MARGIN, OBJECT_MARGIN, OBJECT_MARGIN);
|
||||
Matrix3x3 worldAxis = newTransform.getOrientation().getAbsoluteMatrix();
|
||||
Vector3D worldExtents = Vector3D(worldAxis.getColumn(0).dot(localExtents),
|
||||
worldAxis.getColumn(1).dot(localExtents),
|
||||
worldAxis.getColumn(2).dot(localExtents));
|
||||
Vector3D worldExtents = Vector3D(worldAxis.getColumn(0).dot(extents),
|
||||
worldAxis.getColumn(1).dot(extents),
|
||||
worldAxis.getColumn(2).dot(extents));
|
||||
minCoordinates = newTransform.getPosition() - worldExtents;
|
||||
maxCoordinates = newTransform.getPosition() + worldExtents;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#include "Shape.h"
|
||||
#include "../mathematics/mathematics.h"
|
||||
|
||||
// TODO : CHECK THAT THE AABB IS CORRECT
|
||||
// TODO : TEST THIS SHAPE WITH GJK AND EPA ALGORITHMS
|
||||
|
||||
// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
|
@ -38,7 +41,7 @@ namespace reactphysics3d {
|
|||
This class represents a 3D box. Those axis are unit length.
|
||||
The three extents are half-widths of the box along the three
|
||||
axis x, y, z local axis. The "transform" of the corresponding
|
||||
rigid body given an orientation and a position to the box
|
||||
rigid body gives an orientation and a position to the box.
|
||||
-------------------------------------------------------------------
|
||||
*/
|
||||
class BoxShape : public Shape {
|
||||
|
@ -51,8 +54,8 @@ class BoxShape : public Shape {
|
|||
|
||||
const Vector3D& getExtent() const; // Return the extents of the box
|
||||
void setExtent(const Vector3D& extent); // Set the extents of the box
|
||||
virtual Vector3D getLocalExtents() const; // Return the local extents in x,y and z direction
|
||||
virtual Vector3D getSupportPoint(const Vector3D& 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 Vector3D getLocalSupportPoint(const Vector3D& direction, double margin=0.0) const; // Return a local support point in a given direction
|
||||
|
||||
#ifdef VISUAL_DEBUG
|
||||
virtual void draw() const; // Draw the Box (only for testing purpose)
|
||||
|
@ -71,12 +74,12 @@ inline void BoxShape::setExtent(const Vector3D& extent) {
|
|||
|
||||
// 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
|
||||
inline Vector3D BoxShape::getLocalExtents() const {
|
||||
return extent;
|
||||
inline Vector3D BoxShape::getLocalExtents(double margin) const {
|
||||
return extent + Vector3D(margin, margin, margin);
|
||||
}
|
||||
|
||||
// Return a support point in a given direction
|
||||
inline Vector3D BoxShape::getSupportPoint(const Vector3D& direction, double margin) const {
|
||||
// Return a local support point in a given direction
|
||||
inline Vector3D BoxShape::getLocalSupportPoint(const Vector3D& direction, double margin) const {
|
||||
assert(margin >= 0.0);
|
||||
|
||||
return Vector3D(direction.getX() < 0.0 ? -extent.getX()-margin : extent.getX()+margin,
|
||||
|
|
|
@ -1 +1,94 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2011 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 <complex>
|
||||
|
||||
#include "ConeShape.h"
|
||||
#ifdef VISUAL_DEBUG
|
||||
#include <GL/freeglut.h> // TODO : Remove this in the final version
|
||||
#include <GL/gl.h> // TODO : Remove this in the final version
|
||||
#endif
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
ConeShape::ConeShape(double radius, double height) : radius(radius), halfHeight(height/2.0) {
|
||||
assert(radius > 0.0);
|
||||
assert(halfHeight > 0.0);
|
||||
|
||||
// Compute the sine of the semi-angle at the apex point
|
||||
sinTheta = radius / (sqrt(radius * radius + height * height));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
ConeShape::~ConeShape() {
|
||||
|
||||
}
|
||||
|
||||
// Return a local support point in a given direction
|
||||
inline Vector3D ConeShape::getLocalSupportPoint(const Vector3D& direction, double margin) const {
|
||||
assert(margin >= 0.0);
|
||||
|
||||
const Vector3D& v = direction;
|
||||
double sinThetaTimesLengthV = sinTheta * v.length();
|
||||
Vector3D supportPoint;
|
||||
|
||||
if (v.getY() >= sinThetaTimesLengthV) {
|
||||
supportPoint = Vector3D(0.0, halfHeight, 0.0);
|
||||
}
|
||||
else {
|
||||
double projectedLength = sqrt(v.getX() * v.getX() + v.getZ() * v.getZ());
|
||||
if (projectedLength > MACHINE_EPSILON) {
|
||||
double d = radius / projectedLength;
|
||||
supportPoint = Vector3D(v.getX() * d, -halfHeight, v.getZ() * d);
|
||||
}
|
||||
else {
|
||||
supportPoint = Vector3D(radius, -halfHeight, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the margin to the support point
|
||||
if (margin != 0.0) {
|
||||
Vector3D unitVec(0.0, -1.0, 0.0);
|
||||
if (v.lengthSquare() > MACHINE_EPSILON * MACHINE_EPSILON) {
|
||||
unitVec = v.getUnit();
|
||||
}
|
||||
supportPoint = supportPoint + unitVec * margin;
|
||||
}
|
||||
|
||||
return supportPoint;
|
||||
}
|
||||
|
||||
#ifdef VISUAL_DEBUG
|
||||
// Draw the cone (only for debuging purpose)
|
||||
void ConeShape::draw() const {
|
||||
|
||||
// Draw in red
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
|
||||
// Draw the sphere
|
||||
glutWireCone(radius, 2.0 * halfHeight, 50, 50);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -29,27 +29,76 @@
|
|||
#include "Shape.h"
|
||||
#include "../mathematics/mathematics.h"
|
||||
|
||||
// TODO : CHECK THAT THE AABB IS CORRECT
|
||||
// TODO : TEST THIS SHAPE WITH GJK AND EPA ALGORITHMS
|
||||
|
||||
// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
Class ConeShape :
|
||||
This class represents a cone bounding volume.
|
||||
This class represents a cone collision shape centered at the
|
||||
origin and alligned with the Y axis. The cone is defined
|
||||
by its height and by the radius of its base. The center of the
|
||||
cone is at the half of the height. The "transform" of the
|
||||
corresponding rigid body gives an orientation and a position
|
||||
to the cone.
|
||||
-------------------------------------------------------------------
|
||||
*/
|
||||
class ConeShape : public Shape {
|
||||
private :
|
||||
|
||||
double radius; // Radius of the base
|
||||
double halfHeight; // Half height of the cone
|
||||
double sinTheta; // sine of the semi angle at the apex point
|
||||
|
||||
public :
|
||||
ConeShape(); // Constructor
|
||||
virtual ~ConeShape(); // Destructor
|
||||
ConeShape(double radius, double height); // Constructor
|
||||
virtual ~ConeShape(); // Destructor
|
||||
|
||||
double getRadius() const; // Return the radius
|
||||
void setRadius(double radius); // Set the radius
|
||||
double getHeight() const; // Return 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 Vector3D getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction
|
||||
|
||||
|
||||
#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)
|
||||
#endif
|
||||
};
|
||||
|
||||
// Return the radius
|
||||
inline double ConeShape::getRadius() const {
|
||||
return radius;
|
||||
}
|
||||
|
||||
// Set the radius
|
||||
inline void ConeShape::setRadius(double radius) {
|
||||
this->radius = radius;
|
||||
|
||||
// Update sine of the semi-angle at the apex point
|
||||
sinTheta = radius / (sqrt(radius * radius + 4 * halfHeight * halfHeight));
|
||||
}
|
||||
|
||||
// Return the height
|
||||
inline double ConeShape::getHeight() const {
|
||||
return 2.0 * halfHeight;
|
||||
}
|
||||
|
||||
// Set the height
|
||||
inline void ConeShape::setHeight(double height) {
|
||||
this->halfHeight = height / 2.0;
|
||||
|
||||
// Update the sine of the semi-angle at the apex point
|
||||
sinTheta = radius / (sqrt(radius * radius + height * height));
|
||||
}
|
||||
|
||||
// Return the local extents in x,y and z direction
|
||||
inline Vector3D ConeShape::getLocalExtents(double margin) const {
|
||||
return Vector3D(radius + margin, halfHeight + margin, radius + margin);
|
||||
}
|
||||
|
||||
}; // End of the ReactPhysics3D namespace
|
||||
|
||||
#endif
|
85
src/shapes/CylinderShape.cpp
Normal file
85
src/shapes/CylinderShape.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2011 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 "CylinderShape.h"
|
||||
#ifdef VISUAL_DEBUG
|
||||
#include <GL/freeglut.h> // TODO : Remove this in the final version
|
||||
#include <GL/gl.h> // TODO : Remove this in the final version
|
||||
#endif
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
CylinderShape::CylinderShape(double radius, double height) : radius(radius), halfHeight(height/2.0) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
CylinderShape::~CylinderShape() {
|
||||
|
||||
}
|
||||
|
||||
// Return a local support point in a given direction
|
||||
Vector3D CylinderShape::getLocalSupportPoint(const Vector3D& direction, double margin) const {
|
||||
assert(margin >= 0.0);
|
||||
|
||||
Vector3D supportPoint(0.0, 0.0, 0.0);
|
||||
double uDotv = direction.getY();
|
||||
Vector3D w(direction.getX(), 0.0, direction.getZ());
|
||||
double lengthW = sqrt(direction.getX() * direction.getX() + direction.getZ() * direction.getZ());
|
||||
|
||||
if (lengthW != 0.0) {
|
||||
if (uDotv < 0.0) supportPoint.setY(-halfHeight);
|
||||
else supportPoint.setY(halfHeight);
|
||||
supportPoint = supportPoint + (radius / lengthW) * w;
|
||||
}
|
||||
else {
|
||||
if (uDotv < 0.0) supportPoint.setY(-halfHeight);
|
||||
else supportPoint.setY(halfHeight);
|
||||
}
|
||||
|
||||
// Add the margin to the support point
|
||||
if (margin != 0.0) {
|
||||
Vector3D unitVec(0.0, 1.0, 0.0);
|
||||
if (direction.lengthSquare() > MACHINE_EPSILON * MACHINE_EPSILON) {
|
||||
unitVec = direction.getUnit();
|
||||
}
|
||||
supportPoint = supportPoint + unitVec * margin;
|
||||
}
|
||||
|
||||
return supportPoint;
|
||||
}
|
||||
|
||||
#ifdef VISUAL_DEBUG
|
||||
// Draw the cone (only for debuging purpose)
|
||||
void CylinderShape::draw() const {
|
||||
|
||||
// Draw in red
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
|
||||
// Draw the sphere
|
||||
glutWireSphere(radius, 50, 50);
|
||||
}
|
||||
#endif
|
96
src/shapes/CylinderShape.h
Normal file
96
src/shapes/CylinderShape.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2011 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 CYLINDER_SHAPE_H
|
||||
#define CYLINDER_SHAPE_H
|
||||
|
||||
// Libraries
|
||||
#include "Shape.h"
|
||||
#include "../mathematics/mathematics.h"
|
||||
|
||||
// TODO : CHECK THAT THE AABB IS CORRECT
|
||||
// TODO : TEST THIS SHAPE WITH GJK AND EPA ALGORITHMS
|
||||
|
||||
// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
Class CylinderShape :
|
||||
This class represents a cylinder collision shape around the Y axis
|
||||
and centered at the origin. The cylinder is defined by its height
|
||||
and the radius of its base. The "transform" of the corresponding
|
||||
rigid body gives an orientation and a position to the cylinder.
|
||||
-------------------------------------------------------------------
|
||||
*/
|
||||
class CylinderShape : public Shape {
|
||||
private :
|
||||
double radius; // Radius of the base
|
||||
double halfHeight; // Half height of the cone
|
||||
|
||||
public :
|
||||
CylinderShape(double radius, double height); // Constructor
|
||||
virtual ~CylinderShape(); // Destructor
|
||||
|
||||
double getRadius() const; // Return the radius
|
||||
void setRadius(double radius); // Set the radius
|
||||
double getHeight() const; // Return 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 Vector3D getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction
|
||||
|
||||
|
||||
#ifdef VISUAL_DEBUG
|
||||
virtual void draw() const; // Draw the sphere (only for testing purpose)
|
||||
#endif
|
||||
};
|
||||
|
||||
// Return the radius
|
||||
inline double CylinderShape::getRadius() const {
|
||||
return radius;
|
||||
}
|
||||
|
||||
// Set the radius
|
||||
inline void CylinderShape::setRadius(double radius) {
|
||||
this->radius = radius;
|
||||
}
|
||||
|
||||
// Return the height
|
||||
inline double CylinderShape::getHeight() const {
|
||||
return halfHeight * 2.0;
|
||||
}
|
||||
|
||||
// Set the height
|
||||
inline void CylinderShape::setHeight(double height) {
|
||||
this->halfHeight = height / 2.0;
|
||||
}
|
||||
|
||||
// Return the local extents in x,y and z direction
|
||||
inline Vector3D CylinderShape::getLocalExtents(double margin) const {
|
||||
return Vector3D(radius + margin, halfHeight + margin, radius + margin);
|
||||
}
|
||||
|
||||
}; // End of the ReactPhysics3D namespace
|
||||
|
||||
#endif
|
||||
|
|
@ -50,10 +50,10 @@ class Shape {
|
|||
Shape(); // Constructor
|
||||
virtual ~Shape(); // Destructor
|
||||
|
||||
Body* getBodyPointer() const; // Return the body pointer
|
||||
void setBodyPointer(Body* bodyPointer); // Set the body pointer
|
||||
virtual Vector3D getSupportPoint(const Vector3D& direction, double margin=0.0) const=0; // Return a support point in a given direction
|
||||
virtual Vector3D getLocalExtents() const=0; // Return the local extents in x,y and z direction
|
||||
Body* getBodyPointer() const; // Return 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 Vector3D getLocalExtents(double margin=0.0) const=0; // Return the local extents in x,y and z direction
|
||||
};
|
||||
|
||||
// Return the body pointer
|
||||
|
|
|
@ -36,9 +36,8 @@ using namespace reactphysics3d;
|
|||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
SphereShape::SphereShape(const Vector3D& center, double radius) {
|
||||
this->center = center;
|
||||
this->radius = radius;
|
||||
SphereShape::SphereShape(double radius) : radius(radius) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
@ -53,17 +52,7 @@ void SphereShape::draw() const {
|
|||
// Draw in red
|
||||
glColor3f(1.0, 0.0, 0.0);
|
||||
|
||||
glTranslatef(center.getX(), center.getY(), center.getZ());
|
||||
|
||||
// Draw the sphere
|
||||
glutWireSphere(radius, 50, 50);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*TODO: DELETE THIS
|
||||
// Return the corresponding AABB
|
||||
AABB* BoundingSphere::computeAABB() const {
|
||||
// Create and return the AABB
|
||||
return new AABB(center, radius, radius, radius);
|
||||
}
|
||||
*/
|
||||
#endif
|
|
@ -34,43 +34,28 @@ namespace reactphysics3d {
|
|||
|
||||
/* -------------------------------------------------------------------
|
||||
Class SphereShape :
|
||||
This class represents a sphere bounding volume.
|
||||
This class represents a sphere collision shape that is centered
|
||||
at the origin and defined by its radius.
|
||||
-------------------------------------------------------------------
|
||||
*/
|
||||
class SphereShape : public Shape {
|
||||
private :
|
||||
Vector3D center; // Center point of the sphere
|
||||
double radius; // Radius of the sphere
|
||||
|
||||
public :
|
||||
SphereShape(const Vector3D& center, double radius); // Constructor
|
||||
virtual ~SphereShape(); // Destructor
|
||||
SphereShape(double radius); // Constructor
|
||||
virtual ~SphereShape(); // Destructor
|
||||
|
||||
Vector3D getCenter() const; // Return the center point of the sphere
|
||||
void setCenter(const Vector3D& center); // Set the center point of the sphere
|
||||
double getRadius() const; // Return the radius of the sphere
|
||||
void setRadius(double radius); // Set the radius of the sphere
|
||||
virtual void update(const Vector3D& newCenter,
|
||||
const Quaternion& rotationQuaternion); // Update the sphere orientation according to a new orientation of the rigid body
|
||||
// TODO : DELETE virtual AABB* computeAABB() const; // Return the corresponding AABB
|
||||
virtual Vector3D getSupportPoint(const Vector3D& direction, double margin=0.0) const; // Return a support point in a given direction
|
||||
virtual Vector3D getLocalExtents() const; // Return the local extents in x,y and z direction
|
||||
double getRadius() const; // Return 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 Vector3D getLocalExtents(double margin=0.0) const; // Return the local extents in x,y and z direction
|
||||
|
||||
#ifdef VISUAL_DEBUG
|
||||
virtual void draw() const; // Draw the sphere (only for testing purpose)
|
||||
#endif
|
||||
};
|
||||
|
||||
// Return the center point of the sphere
|
||||
inline Vector3D SphereShape::getCenter() const {
|
||||
return center;
|
||||
}
|
||||
|
||||
// Set the center point of the sphere
|
||||
inline void SphereShape::setCenter(const Vector3D& center) {
|
||||
this->center = center;
|
||||
}
|
||||
|
||||
// Get the radius of the sphere
|
||||
inline double SphereShape::getRadius() const {
|
||||
return radius;
|
||||
|
@ -81,14 +66,8 @@ inline void SphereShape::setRadius(double radius) {
|
|||
this->radius = radius;
|
||||
}
|
||||
|
||||
// Update the orientation of the shere according to the orientation of the rigid body
|
||||
inline void SphereShape::update(const Vector3D& newCenter, const Quaternion& rotationQuaternion) {
|
||||
// Update the center of the sphere
|
||||
center = newCenter;
|
||||
}
|
||||
|
||||
// Return a support point in a given direction
|
||||
inline Vector3D SphereShape::getSupportPoint(const Vector3D& direction, double margin) const {
|
||||
// Return a local support point in a given direction
|
||||
inline Vector3D SphereShape::getLocalSupportPoint(const Vector3D& direction, double margin) const {
|
||||
assert(margin >= 0.0);
|
||||
double length = direction.length();
|
||||
|
||||
|
@ -105,8 +84,8 @@ inline Vector3D SphereShape::getSupportPoint(const Vector3D& direction, double m
|
|||
|
||||
// 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
|
||||
inline Vector3D SphereShape::getLocalExtents() const {
|
||||
return Vector3D(radius, radius, radius);
|
||||
inline Vector3D SphereShape::getLocalExtents(double margin) const {
|
||||
return Vector3D(radius + margin, radius + margin, radius + margin);
|
||||
}
|
||||
|
||||
}; // End of the ReactPhysics3D namespace
|
||||
|
|
Loading…
Reference in New Issue
Block a user