Modify the method that return the bounds of a collision shape and make the getSupportPoint() methods non-const

This commit is contained in:
Daniel Chappuis 2013-07-15 19:09:07 +02:00
parent e4d283186f
commit c3f4355c25
18 changed files with 128 additions and 89 deletions

View File

@ -83,9 +83,9 @@ int EPAAlgorithm::isOriginInTetrahedron(const Vector3& p1, const Vector3& p2,
/// GJK algorithm. The EPA Algorithm will extend this simplex polytope to find
/// the correct penetration depth
bool EPAAlgorithm::computePenetrationDepthAndContactPoints(const Simplex& simplex,
const CollisionShape* collisionShape1,
CollisionShape* collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape* collisionShape2,
const Transform& transform2,
Vector3& v, ContactPointInfo*& contactInfo) {

View File

@ -119,9 +119,9 @@ class EPAAlgorithm {
/// Compute the penetration depth with EPA algorithm.
bool computePenetrationDepthAndContactPoints(const Simplex& simplex,
const CollisionShape* collisionShape1,
CollisionShape* collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape* collisionShape2,
const Transform& transform2,
Vector3& v, ContactPointInfo*& contactInfo);
};

View File

@ -57,9 +57,9 @@ GJKAlgorithm::~GJKAlgorithm() {
/// algorithm on the enlarged object to obtain a simplex polytope that contains the
/// origin, they we give that simplex polytope to the EPA algorithm which will compute
/// the correct penetration depth and contact points between the enlarged objects.
bool GJKAlgorithm::testCollision(const CollisionShape* collisionShape1,
bool GJKAlgorithm::testCollision(CollisionShape* collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape* collisionShape2,
const Transform& transform2,
ContactPointInfo*& contactInfo) {
@ -259,9 +259,9 @@ bool GJKAlgorithm::testCollision(const CollisionShape* collisionShape1,
/// assumed to intersect in the original objects (without margin). Therefore such
/// a polytope must exist. Then, we give that polytope to the EPA algorithm to
/// compute the correct penetration depth and contact points of the enlarged objects.
bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(const CollisionShape* collisionShape1,
bool GJKAlgorithm::computePenetrationDepthForEnlargedObjects(CollisionShape* collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape* collisionShape2,
const Transform& transform2,
ContactPointInfo*& contactInfo,
Vector3& v) {

View File

@ -74,9 +74,9 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm {
GJKAlgorithm& operator=(const GJKAlgorithm& algorithm);
/// Compute the penetration depth for enlarged objects.
bool computePenetrationDepthForEnlargedObjects(const CollisionShape* collisionShape1,
bool computePenetrationDepthForEnlargedObjects(CollisionShape* collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape* collisionShape2,
const Transform& transform2,
ContactPointInfo*& contactInfo, Vector3& v);
@ -91,9 +91,9 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm {
~GJKAlgorithm();
/// Return true and compute a contact info if the two bounding volumes collide.
virtual bool testCollision(const CollisionShape* collisionShape1,
virtual bool testCollision(CollisionShape *collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape *collisionShape2,
const Transform& transform2,
ContactPointInfo*& contactInfo);
};

View File

@ -78,9 +78,9 @@ class NarrowPhaseAlgorithm {
void setCurrentOverlappingPair(BroadPhasePair* overlappingPair);
/// Return true and compute a contact info if the two bounding volume collide
virtual bool testCollision(const CollisionShape* collisionShape1,
virtual bool testCollision(CollisionShape* collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape* collisionShape2,
const Transform& transform2,
ContactPointInfo*& contactInfo)=0;
};

View File

@ -41,9 +41,9 @@ SphereVsSphereAlgorithm::~SphereVsSphereAlgorithm() {
}
bool SphereVsSphereAlgorithm::testCollision(const CollisionShape* collisionShape1,
bool SphereVsSphereAlgorithm::testCollision(CollisionShape* collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape* collisionShape2,
const Transform& transform2,
ContactPointInfo*& contactInfo) {

View File

@ -63,9 +63,9 @@ class SphereVsSphereAlgorithm : public NarrowPhaseAlgorithm {
virtual ~SphereVsSphereAlgorithm();
/// Return true and compute a contact info if the two bounding volume collide
virtual bool testCollision(const CollisionShape* collisionShape1,
virtual bool testCollision(CollisionShape* collisionShape1,
const Transform& transform1,
const CollisionShape* collisionShape2,
CollisionShape* collisionShape2,
const Transform& transform2,
ContactPointInfo*& contactInfo);
};

View File

@ -80,19 +80,19 @@ class BoxShape : public CollisionShape {
virtual BoxShape* clone(void* allocatedMemory) const;
/// Return the extents of the box
const Vector3& getExtent() const;
Vector3 getExtent() const;
/// Return the local extents in x,y and z direction.
virtual Vector3 getLocalExtents() const;
/// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const;
/// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const;
/// Return a local support point in a given direction with the object margin
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction);
/// Return a local support point in a given direction without the object margin
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction);
/// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
@ -107,14 +107,19 @@ inline BoxShape* BoxShape::clone(void* allocatedMemory) const {
}
// Return the extents of the box
inline const Vector3& BoxShape::getExtent() const {
inline Vector3 BoxShape::getExtent() const {
return mExtent + Vector3(mMargin, mMargin, mMargin);
}
// Return the local extents of the box (half-width) in x,y and z local direction.
// Return the local bounds of the shape in x, y and z directions
/// This method is used to compute the AABB of the box
inline Vector3 BoxShape::getLocalExtents() const {
return mExtent + Vector3(mMargin, mMargin, mMargin);
inline void BoxShape::getLocalBounds(Vector3& min, Vector3& max) const {
// Maximum bounds
max = mExtent + Vector3(mMargin, mMargin, mMargin);
// Minimum bounds
min = -max;
}
// Return the number of bytes used by the collision shape
@ -123,7 +128,7 @@ inline size_t BoxShape::getSizeInBytes() const {
}
// Return a local support point in a given direction with the object margin
inline Vector3 BoxShape::getLocalSupportPointWithMargin(const Vector3& direction) const {
inline Vector3 BoxShape::getLocalSupportPointWithMargin(const Vector3& direction) {
assert(mMargin > 0.0);
@ -133,7 +138,7 @@ inline Vector3 BoxShape::getLocalSupportPointWithMargin(const Vector3& direction
}
// Return a local support point in a given direction without the objec margin
inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const {
inline Vector3 BoxShape::getLocalSupportPointWithoutMargin(const Vector3& direction) {
return Vector3(direction.x < 0.0 ? -mExtent.x : mExtent.x,
direction.y < 0.0 ? -mExtent.y : mExtent.y,

View File

@ -55,7 +55,7 @@ CapsuleShape::~CapsuleShape() {
/// Therefore, in this method, we compute the support points of both top and bottom spheres of
/// the capsule and return the point with the maximum dot product with the direction vector. Note
/// that the object margin is implicitly the radius and height of the capsule.
Vector3 CapsuleShape::getLocalSupportPointWithMargin(const Vector3& direction) const {
Vector3 CapsuleShape::getLocalSupportPointWithMargin(const Vector3& direction) {
// If the direction vector is not the zero vector
if (direction.lengthSquare() >= MACHINE_EPSILON * MACHINE_EPSILON) {
@ -87,7 +87,7 @@ Vector3 CapsuleShape::getLocalSupportPointWithMargin(const Vector3& direction) c
}
// Return a local support point in a given direction without the object margin.
Vector3 CapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const {
Vector3 CapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& direction) {
// If the dot product of the direction and the local Y axis (dotProduct = direction.y)
// is positive

View File

@ -86,13 +86,13 @@ class CapsuleShape : public CollisionShape {
virtual size_t getSizeInBytes() const;
/// Return a local support point in a given direction with the object margin.
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction);
/// Return a local support point in a given direction without the object margin
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction);
/// Return the local extents in x,y and z direction
virtual Vector3 getLocalExtents() const;
/// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const;
/// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
@ -121,12 +121,19 @@ inline size_t CapsuleShape::getSizeInBytes() const {
return sizeof(CapsuleShape);
}
// Return the local extents of the collision shape (half-width) in x,y and z local direction
// Return the local bounds of the shape in x, y and z directions
// This method is used to compute the AABB of the box
inline Vector3 CapsuleShape::getLocalExtents() const {
return Vector3(mRadius,
mHalfHeight + mRadius,
mRadius);
inline void CapsuleShape::getLocalBounds(Vector3& min, Vector3& max) const {
// Maximum bounds
max.x = mRadius;
max.y = mHalfHeight + mRadius;
max.z = mRadius;
// Minimum bounds
min.x = -mRadius;
min.y = -max.y;
min.z = min.x;
}
// Test equality between two capsule shapes

View File

@ -48,20 +48,25 @@ CollisionShape::~CollisionShape() {
}
// Update the AABB of a body using its collision shape
inline void CollisionShape::updateAABB(AABB& aabb, const Transform& transform) {
void CollisionShape::updateAABB(AABB& aabb, const Transform& transform) {
// Get the local extents in x,y and z direction
Vector3 extents = getLocalExtents();
// Get the local bounds in x,y and z direction
Vector3 minBounds;
Vector3 maxBounds;
getLocalBounds(minBounds, maxBounds);
// Rotate the local extents according to the orientation of the body
// Rotate the local bounds according to the orientation of the body
Matrix3x3 worldAxis = transform.getOrientation().getMatrix().getAbsoluteMatrix();
Vector3 worldExtents = Vector3(worldAxis.getColumn(0).dot(extents),
worldAxis.getColumn(1).dot(extents),
worldAxis.getColumn(2).dot(extents));
Vector3 worldMinBounds(worldAxis.getColumn(0).dot(minBounds),
worldAxis.getColumn(1).dot(minBounds),
worldAxis.getColumn(2).dot(minBounds));
Vector3 worldMaxBounds(worldAxis.getColumn(0).dot(maxBounds),
worldAxis.getColumn(1).dot(maxBounds),
worldAxis.getColumn(2).dot(maxBounds));
// Compute the minimum and maximum coordinates of the rotated extents
Vector3 minCoordinates = transform.getPosition() - worldExtents;
Vector3 maxCoordinates = transform.getPosition() + worldExtents;
Vector3 minCoordinates = transform.getPosition() + worldMinBounds;
Vector3 maxCoordinates = transform.getPosition() + worldMaxBounds;
// Update the AABB with the new minimum and maximum coordinates
aabb.setMin(minCoordinates);

View File

@ -36,7 +36,7 @@
namespace reactphysics3d {
/// Type of the collision shape
enum CollisionShapeType {BOX, SPHERE, CONE, CYLINDER, CAPSULE};
enum CollisionShapeType {BOX, SPHERE, CONE, CYLINDER, CAPSULE, CONVEX_MESH};
// Declarations
class Body;
@ -95,13 +95,13 @@ class CollisionShape {
virtual size_t getSizeInBytes() const = 0;
/// Return a local support point in a given direction with the object margin
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const=0;
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction)=0;
/// Return a local support point in a given direction without the object margin
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const=0;
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction)=0;
/// Return the local extents in x,y and z direction
virtual Vector3 getLocalExtents() const=0;
/// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const=0;
/// Return the local inertia tensor of the collision shapes
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const=0;

View File

@ -54,7 +54,7 @@ ConeShape::~ConeShape() {
}
// Return a local support point in a given direction with the object margin
inline Vector3 ConeShape::getLocalSupportPointWithMargin(const Vector3& direction) const {
Vector3 ConeShape::getLocalSupportPointWithMargin(const Vector3& direction) {
// Compute the support point without the margin
Vector3 supportPoint = getLocalSupportPointWithoutMargin(direction);
@ -70,7 +70,7 @@ inline Vector3 ConeShape::getLocalSupportPointWithMargin(const Vector3& directio
}
// Return a local support point in a given direction without the object margin
inline Vector3 ConeShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const {
Vector3 ConeShape::getLocalSupportPointWithoutMargin(const Vector3& direction) {
const Vector3& v = direction;
decimal sinThetaTimesLengthV = mSinTheta * v.length();

View File

@ -94,13 +94,13 @@ class ConeShape : public CollisionShape {
virtual size_t getSizeInBytes() const;
/// Return a local support point in a given direction with the object margin
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction);
/// Return a local support point in a given direction without the object margin
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction);
/// Return the local extents in x,y and z direction
virtual Vector3 getLocalExtents() const;
/// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const;
/// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
@ -129,9 +129,18 @@ inline size_t ConeShape::getSizeInBytes() const {
return sizeof(ConeShape);
}
// Return the local extents in x,y and z direction
inline Vector3 ConeShape::getLocalExtents() const {
return Vector3(mRadius + mMargin, mHalfHeight + mMargin, mRadius + mMargin);
// Return the local bounds of the shape in x, y and z directions
inline void ConeShape::getLocalBounds(Vector3& min, Vector3& max) const {
// Maximum bounds
max.x = mRadius + mMargin;
max.y = mHalfHeight + mMargin;
max.z = max.x;
// Minimum bounds
min.x = -max.x;
min.y = -max.y;
min.z = min.x;
}
// Return the local inertia tensor of the collision shape

View File

@ -50,7 +50,7 @@ CylinderShape::~CylinderShape() {
}
// Return a local support point in a given direction with the object margin
Vector3 CylinderShape::getLocalSupportPointWithMargin(const Vector3& direction) const {
Vector3 CylinderShape::getLocalSupportPointWithMargin(const Vector3& direction) {
// Compute the support point without the margin
Vector3 supportPoint = getLocalSupportPointWithoutMargin(direction);
@ -66,7 +66,7 @@ Vector3 CylinderShape::getLocalSupportPointWithMargin(const Vector3& direction)
}
// Return a local support point in a given direction without the object margin
Vector3 CylinderShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const {
Vector3 CylinderShape::getLocalSupportPointWithoutMargin(const Vector3& direction) {
Vector3 supportPoint(0.0, 0.0, 0.0);
decimal uDotv = direction.y;

View File

@ -91,13 +91,13 @@ class CylinderShape : public CollisionShape {
virtual size_t getSizeInBytes() const;
/// Return a local support point in a given direction with the object margin
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction);
/// Return a local support point in a given direction without the object margin
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction);
/// Return the local extents in x,y and z direction
virtual Vector3 getLocalExtents() const;
/// Return the local bounds of the shape in x, y and z directions
virtual void getLocalBounds(Vector3& min, Vector3& max) const;
/// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
@ -126,9 +126,18 @@ inline size_t CylinderShape::getSizeInBytes() const {
return sizeof(CylinderShape);
}
// Return the local extents in x,y and z direction
inline Vector3 CylinderShape::getLocalExtents() const {
return Vector3(mRadius + mMargin, mHalfHeight + mMargin, mRadius + mMargin);
// Return the local bounds of the shape in x, y and z directions
inline void CylinderShape::getLocalBounds(Vector3& min, Vector3& max) const {
// Maximum bounds
max.x = mRadius + mMargin;
max.y = mHalfHeight + mMargin;
max.z = max.x;
// Minimum bounds
min.x = -max.x;
min.y = -max.y;
min.z = min.x;
}
// Return the local inertia tensor of the cylinder

View File

@ -78,13 +78,13 @@ class SphereShape : public CollisionShape {
virtual size_t getSizeInBytes() const;
/// Return a local support point in a given direction with the object margin
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithMargin(const Vector3& direction);
/// Return a local support point in a given direction without the object margin
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction);
/// Return the local extents in x,y and z direction
virtual Vector3 getLocalExtents() const;
/// Return the local bounds of the shape in x, y and z directions.
virtual void getLocalBounds(Vector3& min, Vector3& max) const;
/// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
@ -112,7 +112,7 @@ inline size_t SphereShape::getSizeInBytes() const {
}
// Return a local support point in a given direction with the object margin
inline Vector3 SphereShape::getLocalSupportPointWithMargin(const Vector3& direction) const {
inline Vector3 SphereShape::getLocalSupportPointWithMargin(const Vector3& direction) {
// If the direction vector is not the zero vector
if (direction.lengthSquare() >= MACHINE_EPSILON * MACHINE_EPSILON) {
@ -127,16 +127,25 @@ inline Vector3 SphereShape::getLocalSupportPointWithMargin(const Vector3& direct
}
// Return a local support point in a given direction without the object margin
inline Vector3 SphereShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const {
inline Vector3 SphereShape::getLocalSupportPointWithoutMargin(const Vector3& direction) {
// Return the center of the sphere (the radius is taken into account in the object margin)
return Vector3(0.0, 0.0, 0.0);
}
// Return the local extents of the collision shape (half-width) in x,y and z local direction
// Return the local bounds of the shape in x, y and z directions.
// This method is used to compute the AABB of the box
inline Vector3 SphereShape::getLocalExtents() const {
return Vector3(mRadius, mRadius, mRadius);
inline void SphereShape::getLocalBounds(Vector3& min, Vector3& max) const {
// Maximum bounds
max.x = mRadius;
max.y = mRadius;
max.z = mRadius;
// Minimum bounds
min.x = -mRadius;
min.y = min.x;
min.z = min.x;
}
// Return the local inertia tensor of the sphere
@ -151,15 +160,11 @@ inline void SphereShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal ma
inline void SphereShape::updateAABB(AABB& aabb, const Transform& transform) {
// Get the local extents in x,y and z direction
Vector3 extents = getLocalExtents();
// Compute the minimum and maximum coordinates of the rotated extents
Vector3 minCoordinates = transform.getPosition() - extents;
Vector3 maxCoordinates = transform.getPosition() + extents;
Vector3 extents(mRadius, mRadius, mRadius);
// Update the AABB with the new minimum and maximum coordinates
aabb.setMin(minCoordinates);
aabb.setMax(maxCoordinates);
aabb.setMin(transform.getPosition() - extents);
aabb.setMax(transform.getPosition() + extents);
}
// Test equality between two sphere shapes

View File

@ -154,7 +154,6 @@ CollisionShape* CollisionWorld::createCollisionShape(const CollisionShape& colli
// A similar collision shape does not already exist in the world, so we create a
// new one and add it to the world
void* allocatedMemory = mMemoryAllocator.allocate(collisionShape.getSizeInBytes());
size_t test = collisionShape.getSizeInBytes();
CollisionShape* newCollisionShape = collisionShape.clone(allocatedMemory);
mCollisionShapes.push_back(newCollisionShape);