2014-08-04 20:46:58 +00:00
|
|
|
#ifndef REACTPHYSICS3D_PROXY_SHAPE_H
|
|
|
|
#define REACTPHYSICS3D_PROXY_SHAPE_H
|
|
|
|
|
|
|
|
// Libraries
|
|
|
|
#include "body/CollisionBody.h"
|
|
|
|
#include "shapes/CollisionShape.h"
|
|
|
|
|
|
|
|
namespace reactphysics3d {
|
|
|
|
|
|
|
|
// Class ProxyShape
|
|
|
|
/**
|
|
|
|
* The CollisionShape instances are supposed to be unique for memory optimization. For instance,
|
|
|
|
* consider two rigid bodies with the same sphere collision shape. In this situation, we will have
|
|
|
|
* a unique instance of SphereShape but we need to differentiate between the two instances during
|
|
|
|
* the collision detection. They do not have the same position in the world and they do not
|
|
|
|
* belong to the same rigid body. The ProxyShape class is used for that purpose by attaching a
|
|
|
|
* rigid body with one of its collision shape. A body can have multiple proxy shapes (one for
|
|
|
|
* each collision shape attached to the body).
|
|
|
|
*/
|
|
|
|
class ProxyShape {
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
// -------------------- Attributes -------------------- //
|
|
|
|
|
|
|
|
/// Pointer to the parent body
|
|
|
|
CollisionBody* mBody;
|
|
|
|
|
|
|
|
/// Internal collision shape
|
|
|
|
CollisionShape* mCollisionShape;
|
|
|
|
|
|
|
|
/// Local-space to parent body-space transform (does not change over time)
|
|
|
|
const Transform mLocalToBodyTransform;
|
|
|
|
|
|
|
|
/// Mass (in kilogramms) of the corresponding collision shape
|
|
|
|
decimal mMass;
|
|
|
|
|
|
|
|
/// Pointer to the next proxy shape of the body (linked list)
|
|
|
|
ProxyShape* mNext;
|
|
|
|
|
|
|
|
/// Broad-phase ID (node ID in the dynamic AABB tree)
|
|
|
|
int mBroadPhaseID;
|
|
|
|
|
|
|
|
/// Cached collision data
|
|
|
|
void* mCachedCollisionData;
|
|
|
|
|
2014-08-04 20:57:24 +00:00
|
|
|
/// Pointer to user data
|
|
|
|
void* mUserData;
|
|
|
|
|
2014-12-31 00:19:14 +00:00
|
|
|
/// Bits used to define the collision category of this shape.
|
|
|
|
/// You can set a single bit to one to define a category value for this
|
|
|
|
/// shape. This value is one (0x0001) by default. This variable can be used
|
|
|
|
/// together with the mCollideWithMaskBits variable so that given
|
|
|
|
/// categories of shapes collide with each other and do not collide with
|
|
|
|
/// other categories.
|
|
|
|
unsigned short mCollisionCategoryBits;
|
|
|
|
|
|
|
|
/// Bits mask used to state which collision categories this shape can
|
|
|
|
/// collide with. This value is 0xFFFF by default. It means that this
|
|
|
|
/// proxy shape will collide with every collision categories by default.
|
|
|
|
unsigned short mCollideWithMaskBits;
|
|
|
|
|
2014-08-04 20:46:58 +00:00
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
|
|
|
|
/// Private copy-constructor
|
|
|
|
ProxyShape(const ProxyShape& proxyShape);
|
|
|
|
|
|
|
|
/// Private assignment operator
|
|
|
|
ProxyShape& operator=(const ProxyShape& proxyShape);
|
|
|
|
|
|
|
|
// Return a local support point in a given direction with the object margin
|
|
|
|
Vector3 getLocalSupportPointWithMargin(const Vector3& direction);
|
|
|
|
|
|
|
|
/// Return a local support point in a given direction without the object margin.
|
|
|
|
Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction);
|
|
|
|
|
|
|
|
/// Return the collision shape margin
|
|
|
|
decimal getMargin() const;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
ProxyShape(CollisionBody* body, CollisionShape* shape,
|
|
|
|
const Transform& transform, decimal mass);
|
|
|
|
|
|
|
|
/// Destructor
|
|
|
|
~ProxyShape();
|
|
|
|
|
|
|
|
/// Return the collision shape
|
|
|
|
const CollisionShape* getCollisionShape() const;
|
|
|
|
|
|
|
|
/// Return the parent body
|
|
|
|
CollisionBody* getBody() const;
|
|
|
|
|
|
|
|
/// Return the mass of the collision shape
|
|
|
|
decimal getMass() const;
|
|
|
|
|
2014-08-04 20:57:24 +00:00
|
|
|
/// Return a pointer to the user data attached to this body
|
|
|
|
void* getUserData() const;
|
|
|
|
|
|
|
|
/// Attach user data to this body
|
|
|
|
void setUserData(void* userData);
|
|
|
|
|
2014-08-04 20:46:58 +00:00
|
|
|
/// Return the local to parent body transform
|
|
|
|
const Transform& getLocalToBodyTransform() const;
|
|
|
|
|
2014-09-02 20:54:19 +00:00
|
|
|
/// Return the local to world transform
|
|
|
|
const Transform getLocalToWorldTransform() const;
|
|
|
|
|
2014-08-04 20:46:58 +00:00
|
|
|
/// Return true if a point is inside the collision shape
|
|
|
|
bool testPointInside(const Vector3& worldPoint);
|
|
|
|
|
|
|
|
/// Raycast method with feedback information
|
2014-10-21 20:26:40 +00:00
|
|
|
bool raycast(const Ray& ray, RaycastInfo& raycastInfo);
|
2014-08-04 20:46:58 +00:00
|
|
|
|
2015-02-12 21:31:26 +00:00
|
|
|
/// Return the collision bits mask
|
|
|
|
unsigned short getCollideWithMaskBits() const;
|
|
|
|
|
|
|
|
/// Set the collision bits mask
|
|
|
|
void setCollideWithMaskBits(unsigned short collideWithMaskBits);
|
|
|
|
|
2014-12-31 00:19:14 +00:00
|
|
|
/// Return the collision category bits
|
|
|
|
unsigned short getCollisionCategoryBits() const;
|
|
|
|
|
|
|
|
/// Set the collision category bits
|
|
|
|
void setCollisionCategoryBits(unsigned short collisionCategoryBits);
|
|
|
|
|
2015-02-12 21:31:26 +00:00
|
|
|
/// Return the next proxy shape in the linked list of proxy shapes
|
|
|
|
ProxyShape* getNext();
|
2014-12-31 00:19:14 +00:00
|
|
|
|
2015-02-12 21:31:26 +00:00
|
|
|
/// Return the next proxy shape in the linked list of proxy shapes
|
|
|
|
const ProxyShape* getNext() const;
|
2014-12-31 00:19:14 +00:00
|
|
|
|
2014-08-04 20:46:58 +00:00
|
|
|
// -------------------- Friendship -------------------- //
|
|
|
|
|
|
|
|
friend class OverlappingPair;
|
|
|
|
friend class CollisionBody;
|
|
|
|
friend class RigidBody;
|
|
|
|
friend class BroadPhaseAlgorithm;
|
|
|
|
friend class DynamicAABBTree;
|
|
|
|
friend class CollisionDetection;
|
2014-12-27 23:54:34 +00:00
|
|
|
friend class CollisionWorld;
|
|
|
|
friend class DynamicsWorld;
|
2014-08-04 20:46:58 +00:00
|
|
|
friend class EPAAlgorithm;
|
|
|
|
friend class GJKAlgorithm;
|
2014-08-09 08:28:37 +00:00
|
|
|
friend class ConvexMeshShape;
|
2014-08-04 20:46:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Return the collision shape
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return Pointer to the internal collision shape
|
|
|
|
*/
|
2014-08-04 20:46:58 +00:00
|
|
|
inline const CollisionShape* ProxyShape::getCollisionShape() const {
|
|
|
|
return mCollisionShape;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the parent body
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return Pointer to the parent body
|
|
|
|
*/
|
2014-08-04 20:46:58 +00:00
|
|
|
inline CollisionBody* ProxyShape::getBody() const {
|
|
|
|
return mBody;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the mass of the collision shape
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return Mass of the collision shape (in kilograms)
|
|
|
|
*/
|
2014-08-04 20:46:58 +00:00
|
|
|
inline decimal ProxyShape::getMass() const {
|
|
|
|
return mMass;
|
|
|
|
}
|
|
|
|
|
2014-08-04 20:57:24 +00:00
|
|
|
// Return a pointer to the user data attached to this body
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return A pointer to the user data stored into the proxy shape
|
|
|
|
*/
|
2014-08-04 20:57:24 +00:00
|
|
|
inline void* ProxyShape::getUserData() const {
|
|
|
|
return mUserData;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Attach user data to this body
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @param userData Pointer to the user data you want to store within the proxy shape
|
|
|
|
*/
|
2014-08-04 20:57:24 +00:00
|
|
|
inline void ProxyShape::setUserData(void* userData) {
|
|
|
|
mUserData = userData;
|
|
|
|
}
|
|
|
|
|
2014-08-04 20:46:58 +00:00
|
|
|
// Return the local to parent body transform
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return The transformation that transforms the local-space of the collision shape
|
|
|
|
* to the local-space of the parent body
|
|
|
|
*/
|
2014-08-04 20:46:58 +00:00
|
|
|
inline const Transform& ProxyShape::getLocalToBodyTransform() const {
|
|
|
|
return mLocalToBodyTransform;
|
|
|
|
}
|
|
|
|
|
2014-09-02 20:54:19 +00:00
|
|
|
// Return the local to world transform
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return The transformation that transforms the local-space of the collision
|
|
|
|
* shape to the world-space
|
|
|
|
*/
|
2014-09-02 20:54:19 +00:00
|
|
|
inline const Transform ProxyShape::getLocalToWorldTransform() const {
|
|
|
|
return mBody->mTransform * mLocalToBodyTransform;
|
|
|
|
}
|
|
|
|
|
2014-08-04 20:46:58 +00:00
|
|
|
// Return a local support point in a given direction with the object margin
|
|
|
|
inline Vector3 ProxyShape::getLocalSupportPointWithMargin(const Vector3& direction) {
|
|
|
|
return mCollisionShape->getLocalSupportPointWithMargin(direction, &mCachedCollisionData);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return a local support point in a given direction without the object margin.
|
|
|
|
inline Vector3 ProxyShape::getLocalSupportPointWithoutMargin(const Vector3& direction) {
|
|
|
|
return mCollisionShape->getLocalSupportPointWithoutMargin(direction, &mCachedCollisionData);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the collision shape margin
|
|
|
|
inline decimal ProxyShape::getMargin() const {
|
|
|
|
return mCollisionShape->getMargin();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Raycast method with feedback information
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @param ray Ray to use for the raycasting
|
|
|
|
* @param[out] raycastInfo Result of the raycasting that is valid only if the
|
|
|
|
* methods returned true
|
|
|
|
* @return True if the ray hit the collision shape
|
|
|
|
*/
|
2014-10-21 20:26:40 +00:00
|
|
|
inline bool ProxyShape::raycast(const Ray& ray, RaycastInfo& raycastInfo) {
|
2014-11-29 16:05:53 +00:00
|
|
|
|
|
|
|
// If the corresponding body is not active, it cannot be hit by rays
|
|
|
|
if (!mBody->isActive()) return false;
|
|
|
|
|
2014-10-21 20:26:40 +00:00
|
|
|
return mCollisionShape->raycast(ray, raycastInfo, this);
|
2014-08-04 20:46:58 +00:00
|
|
|
}
|
|
|
|
|
2014-12-27 23:54:34 +00:00
|
|
|
// Return the next proxy shape in the linked list of proxy shapes
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return Pointer to the next proxy shape in the linked list of proxy shapes
|
|
|
|
*/
|
2014-12-27 23:54:34 +00:00
|
|
|
inline ProxyShape* ProxyShape::getNext() {
|
|
|
|
return mNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the next proxy shape in the linked list of proxy shapes
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return Pointer to the next proxy shape in the linked list of proxy shapes
|
|
|
|
*/
|
2014-12-27 23:54:34 +00:00
|
|
|
inline const ProxyShape* ProxyShape::getNext() const {
|
|
|
|
return mNext;
|
|
|
|
}
|
|
|
|
|
2014-12-31 00:19:14 +00:00
|
|
|
// Return the collision category bits
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return The collision category bits mask of the proxy shape
|
|
|
|
*/
|
2014-12-31 00:19:14 +00:00
|
|
|
inline unsigned short ProxyShape::getCollisionCategoryBits() const {
|
|
|
|
return mCollisionCategoryBits;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the collision category bits
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @param collisionCategoryBits The collision category bits mask of the proxy shape
|
|
|
|
*/
|
2014-12-31 00:19:14 +00:00
|
|
|
inline void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) {
|
|
|
|
mCollisionCategoryBits = collisionCategoryBits;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the collision bits mask
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @return The bits mask that specifies with which collision category this shape will collide
|
|
|
|
*/
|
2014-12-31 00:19:14 +00:00
|
|
|
inline unsigned short ProxyShape::getCollideWithMaskBits() const {
|
|
|
|
return mCollideWithMaskBits;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the collision bits mask
|
2015-02-12 21:31:26 +00:00
|
|
|
/**
|
|
|
|
* @param collideWithMaskBits The bits mask that specifies with which collision category this shape will collide
|
|
|
|
*/
|
2014-12-31 00:19:14 +00:00
|
|
|
inline void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBits) {
|
|
|
|
mCollideWithMaskBits = collideWithMaskBits;
|
|
|
|
}
|
|
|
|
|
2014-08-04 20:46:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|