Add the CapsuleShape class for the capsule collision shape
This commit is contained in:
parent
e081661d8c
commit
9d9142af30
125
src/collision/shapes/CapsuleShape.cpp
Normal file
125
src/collision/shapes/CapsuleShape.cpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "CapsuleShape.h"
|
||||
#include "../../configuration.h"
|
||||
#include <cassert>
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
CapsuleShape::CapsuleShape(decimal radius, decimal height)
|
||||
: CollisionShape(CAPSULE, radius), mRadius(radius), mHalfHeight(height * decimal(0.5)) {
|
||||
assert(radius > decimal(0.0));
|
||||
assert(height > decimal(0.0));
|
||||
}
|
||||
|
||||
// Private copy-constructor
|
||||
CapsuleShape::CapsuleShape(const CapsuleShape& shape)
|
||||
: CollisionShape(shape), mRadius(shape.mRadius), mHalfHeight(shape.mHalfHeight) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
CapsuleShape::~CapsuleShape() {
|
||||
|
||||
}
|
||||
|
||||
// Return a local support point in a given direction with the object margin.
|
||||
/// A capsule is the convex hull of two spheres S1 and S2. The support point in the direction "d"
|
||||
/// of the convex hull of a set of convex objects is the support point "p" in the set of all
|
||||
/// support points from all the convex objects with the maximum dot product with the direction "d".
|
||||
/// 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 {
|
||||
|
||||
// If the direction vector is not the zero vector
|
||||
if (direction.lengthSquare() >= MACHINE_EPSILON * MACHINE_EPSILON) {
|
||||
|
||||
Vector3 unitDirection = direction.getUnit();
|
||||
|
||||
// Support point top sphere
|
||||
Vector3 centerTopSphere(0, mHalfHeight, 0);
|
||||
Vector3 topSpherePoint = centerTopSphere + unitDirection * mRadius;
|
||||
decimal dotProductTop = topSpherePoint.dot(direction);
|
||||
|
||||
// Support point bottom sphere
|
||||
Vector3 centerBottomSphere(0, -mHalfHeight, 0);
|
||||
Vector3 bottomSpherePoint = centerBottomSphere + unitDirection * mRadius;
|
||||
decimal dotProductBottom = bottomSpherePoint.dot(direction);
|
||||
|
||||
// Return the point with the maximum dot product
|
||||
if (dotProductTop > dotProductBottom) {
|
||||
return topSpherePoint;
|
||||
}
|
||||
else {
|
||||
return bottomSpherePoint;
|
||||
}
|
||||
}
|
||||
|
||||
// If the direction vector is the zero vector we return a point on the
|
||||
// boundary of the capsule
|
||||
return Vector3(0, mRadius, 0);
|
||||
}
|
||||
|
||||
// Return a local support point in a given direction without the object margin.
|
||||
Vector3 CapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& direction) const {
|
||||
|
||||
// If the dot product of the direction and the local Y axis (dotProduct = direction.y)
|
||||
// is positive
|
||||
if (direction.y > 0.0) {
|
||||
|
||||
// Return the top sphere center point
|
||||
return Vector3(0, mHalfHeight, 0);
|
||||
}
|
||||
else {
|
||||
|
||||
// Return the bottom sphere center point
|
||||
return Vector3(0, -mHalfHeight, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the local inertia tensor of the capsule
|
||||
void CapsuleShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const {
|
||||
|
||||
// The inertia tensor formula for a capsule can be found in : Game Engine Gems, Volume 1
|
||||
|
||||
decimal height = mHalfHeight + mHalfHeight;
|
||||
decimal radiusSquare = mRadius * mRadius;
|
||||
decimal heightSquare = height * height;
|
||||
decimal radiusSquareDouble = radiusSquare + radiusSquare;
|
||||
decimal factor1 = decimal(2.0) * mRadius / (decimal(4.0) * mRadius + decimal(3.0) * height);
|
||||
decimal factor2 = decimal(3.0) * height / (decimal(4.0) * mRadius + decimal(3.0) * height);
|
||||
decimal sum1 = decimal(0.4) * radiusSquareDouble;
|
||||
decimal sum2 = decimal(0.75) * height * mRadius + decimal(0.5) * heightSquare;
|
||||
decimal sum3 = decimal(0.25) * radiusSquare + decimal(1.0 / 12.0) * heightSquare;
|
||||
decimal IxxAndzz = factor1 * mass * (sum1 + sum2) + factor2 * mass * sum3;
|
||||
decimal Iyy = factor1 * mass * sum1 + factor2 * mass * decimal(0.25) * radiusSquareDouble;
|
||||
tensor.setAllValues(IxxAndzz, 0.0, 0.0,
|
||||
0.0, Iyy, 0.0,
|
||||
0.0, 0.0, IxxAndzz);
|
||||
}
|
140
src/collision/shapes/CapsuleShape.h
Normal file
140
src/collision/shapes/CapsuleShape.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef REACTPHYSICS3D_CAPSULE_SHAPE_H
|
||||
#define REACTPHYSICS3D_CAPSULE_SHAPE_H
|
||||
|
||||
// Libraries
|
||||
#include "CollisionShape.h"
|
||||
#include "../../mathematics/mathematics.h"
|
||||
|
||||
// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Class CapsuleShape
|
||||
/**
|
||||
* This class represents a capsule collision shape that is defined around the Y axis.
|
||||
* A capsule shape can be seen as the convex hull of two spheres.
|
||||
* The capsule shape is defined by its radius (radius of the two spheres of the capsule)
|
||||
* and its height (distance between the centers of the two spheres). This collision shape
|
||||
* does not have an explicit object margin distance. The margin is implicitly the radius
|
||||
* and height of the shape. Therefore, no need to specify an object margin for a
|
||||
* capsule shape.
|
||||
*/
|
||||
class CapsuleShape : public CollisionShape {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Radius of the two spheres of the capsule
|
||||
decimal mRadius;
|
||||
|
||||
/// Half height of the capsule (height = distance between the centers of the two spheres)
|
||||
decimal mHalfHeight;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Private copy-constructor
|
||||
CapsuleShape(const CapsuleShape& shape);
|
||||
|
||||
/// Private assignment operator
|
||||
CapsuleShape& operator=(const CapsuleShape& shape);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CapsuleShape(decimal radius, decimal height);
|
||||
|
||||
/// Destructor
|
||||
virtual ~CapsuleShape();
|
||||
|
||||
/// Allocate and return a copy of the object
|
||||
virtual CapsuleShape* clone(void* allocatedMemory) const;
|
||||
|
||||
/// Return the radius of the capsule
|
||||
decimal getRadius() const;
|
||||
|
||||
/// Return the height of the capsule
|
||||
decimal getHeight() 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;
|
||||
|
||||
/// Return a local support point in a given direction without the object margin
|
||||
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const;
|
||||
|
||||
/// Return the local extents in x,y and z direction
|
||||
virtual Vector3 getLocalExtents() const;
|
||||
|
||||
/// Return the local inertia tensor of the collision shape
|
||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const;
|
||||
|
||||
/// Test equality between two capsule shapes
|
||||
virtual bool isEqualTo(const CollisionShape& otherCollisionShape) const;
|
||||
};
|
||||
|
||||
/// Allocate and return a copy of the object
|
||||
inline CapsuleShape* CapsuleShape::clone(void* allocatedMemory) const {
|
||||
return new (allocatedMemory) CapsuleShape(*this);
|
||||
}
|
||||
|
||||
// Get the radius of the capsule
|
||||
inline decimal CapsuleShape::getRadius() const {
|
||||
return mRadius;
|
||||
}
|
||||
|
||||
// Return the height of the capsule
|
||||
inline decimal CapsuleShape::getHeight() const {
|
||||
return mHalfHeight + mHalfHeight;
|
||||
}
|
||||
|
||||
// Return the number of bytes used by the collision shape
|
||||
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
|
||||
// This method is used to compute the AABB of the box
|
||||
inline Vector3 CapsuleShape::getLocalExtents() const {
|
||||
return Vector3(mRadius,
|
||||
mHalfHeight + mRadius,
|
||||
mRadius);
|
||||
}
|
||||
|
||||
// Test equality between two capsule shapes
|
||||
inline bool CapsuleShape::isEqualTo(const CollisionShape& otherCollisionShape) const {
|
||||
const CapsuleShape& otherShape = dynamic_cast<const CapsuleShape&>(otherCollisionShape);
|
||||
return (mRadius == otherShape.mRadius && mHalfHeight == otherShape.mHalfHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -41,11 +41,13 @@
|
|||
#include "body/RigidBody.h"
|
||||
#include "engine/DynamicsWorld.h"
|
||||
#include "engine/CollisionWorld.h"
|
||||
#include "engine/Material.h"
|
||||
#include "collision/shapes/CollisionShape.h"
|
||||
#include "collision/shapes/BoxShape.h"
|
||||
#include "collision/shapes/SphereShape.h"
|
||||
#include "collision/shapes/ConeShape.h"
|
||||
#include "collision/shapes/CylinderShape.h"
|
||||
#include "collision/shapes/CapsuleShape.h"
|
||||
#include "collision/shapes/AABB.h"
|
||||
#include "constraint/BallAndSocketJoint.h"
|
||||
#include "constraint/SliderJoint.h"
|
||||
|
|
Loading…
Reference in New Issue
Block a user