Make possible to resize the collision shapes after their creation
This commit is contained in:
parent
9d776e32dc
commit
7477460e4f
|
@ -92,6 +92,9 @@ Collider* CollisionBody::addCollider(CollisionShape* collisionShape, const Trans
|
|||
|
||||
mWorld.mCollisionBodyComponents.addColliderToBody(mEntity, colliderEntity);
|
||||
|
||||
// Assign the collider with the collision shape
|
||||
collisionShape->addCollider(collider);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Set the profiler
|
||||
|
@ -175,6 +178,9 @@ void CollisionBody::removeCollider(Collider* collider) {
|
|||
|
||||
mWorld.mCollisionBodyComponents.removeColliderFromBody(mEntity, collider->getEntity());
|
||||
|
||||
// Unassign the collider from the collision shape
|
||||
collider->getCollisionShape()->removeCollider(collider);
|
||||
|
||||
// Remove the collider component
|
||||
mWorld.mCollidersComponents.removeComponent(collider->getEntity());
|
||||
|
||||
|
|
|
@ -341,6 +341,9 @@ Collider* RigidBody::addCollider(CollisionShape* collisionShape, const Transform
|
|||
|
||||
mWorld.mCollisionBodyComponents.addColliderToBody(mEntity, colliderEntity);
|
||||
|
||||
// Assign the collider with the collision shape
|
||||
collisionShape->addCollider(collider);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Set the profiler
|
||||
|
|
|
@ -42,8 +42,7 @@ using namespace reactphysics3d;
|
|||
Collider::Collider(Entity entity, CollisionBody* body, MemoryManager& memoryManager)
|
||||
:mMemoryManager(memoryManager), mEntity(entity), mBody(body),
|
||||
mMaterial(body->mWorld.mConfig.defaultFrictionCoefficient, body->mWorld.mConfig.defaultRollingRestistance,
|
||||
body->mWorld.mConfig.defaultBounciness),
|
||||
mUserData(nullptr) {
|
||||
body->mWorld.mConfig.defaultBounciness), mUserData(nullptr) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -144,19 +143,11 @@ const AABB Collider::getWorldAABB() const {
|
|||
return aabb;
|
||||
}
|
||||
|
||||
// Return the collision shape
|
||||
// Return a pointer to the collision shape
|
||||
/**
|
||||
* @return Pointer to the internal collision shape
|
||||
*/
|
||||
const CollisionShape* Collider::getCollisionShape() const {
|
||||
return mBody->mWorld.mCollidersComponents.getCollisionShape(mEntity);
|
||||
}
|
||||
|
||||
// Return the collision shape
|
||||
/**
|
||||
* @return Pointer to the internal collision shape
|
||||
*/
|
||||
CollisionShape* Collider::getCollisionShape() {
|
||||
CollisionShape* Collider::getCollisionShape() const {
|
||||
return mBody->mWorld.mCollidersComponents.getCollisionShape(mEntity);
|
||||
}
|
||||
|
||||
|
@ -220,6 +211,11 @@ unsigned short Collider::getCollideWithMaskBits() const {
|
|||
return mBody->mWorld.mCollidersComponents.getCollideWithMaskBits(mEntity);
|
||||
}
|
||||
|
||||
// Notify the collider that the size of the collision shape has been changed by the user
|
||||
void Collider::setHasCollisionShapeChangedSize(bool hasCollisionShapeChangedSize) {
|
||||
mBody->mWorld.mCollidersComponents.setHasCollisionShapeChangedSize(mEntity, hasCollisionShapeChangedSize);
|
||||
}
|
||||
|
||||
// Return the local to world transform
|
||||
/**
|
||||
* @return The transformation that transforms the local-space of the collision
|
||||
|
|
|
@ -80,8 +80,9 @@ class Collider {
|
|||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Return the collision shape
|
||||
CollisionShape* getCollisionShape();
|
||||
/// Notify the collider that the size of the collision shape has been
|
||||
/// changed by the user
|
||||
void setHasCollisionShapeChangedSize(bool hasCollisionShapeChangedSize);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -102,8 +103,8 @@ class Collider {
|
|||
/// Return the corresponding entity of the collider
|
||||
Entity getEntity() const;
|
||||
|
||||
/// Return the collision shape
|
||||
const CollisionShape* getCollisionShape() const;
|
||||
/// Return a pointer to the collision shape
|
||||
CollisionShape* getCollisionShape() const;
|
||||
|
||||
/// Return the parent body
|
||||
CollisionBody* getBody() const;
|
||||
|
@ -183,7 +184,8 @@ class Collider {
|
|||
friend class PhysicsWorld;
|
||||
friend class GJKAlgorithm;
|
||||
friend class ConvexMeshShape;
|
||||
friend class ContactManifoldSet;
|
||||
friend class CollisionShape;
|
||||
friend class ContactManifoldSet;
|
||||
friend class MiddlePhaseTriangleCallback;
|
||||
|
||||
};
|
||||
|
|
|
@ -169,8 +169,10 @@ void DynamicAABBTree::removeObject(int32 nodeID) {
|
|||
/// nothing is done. Otherwise, the corresponding node is removed and reinserted into the tree.
|
||||
/// The method returns true if the object has been reinserted into the tree. The "displacement"
|
||||
/// argument is the linear velocity of the AABB multiplied by the elapsed time between two
|
||||
/// frames.
|
||||
bool DynamicAABBTree::updateObject(int32 nodeID, const AABB& newAABB, const Vector3& displacement) {
|
||||
/// frames. If the "forceReInsert" parameter is true, we force the existing AABB to take the size
|
||||
/// of the "newAABB" parameter even if it is larger than "newAABB". This can be used to shrink the
|
||||
/// AABB in the tree for instance if the corresponding collision shape has been shrunk.
|
||||
bool DynamicAABBTree::updateObject(int32 nodeID, const AABB& newAABB, const Vector3& displacement, bool forceReinsert) {
|
||||
|
||||
RP3D_PROFILE("DynamicAABBTree::updateObject()", mProfiler);
|
||||
|
||||
|
@ -179,7 +181,7 @@ bool DynamicAABBTree::updateObject(int32 nodeID, const AABB& newAABB, const Vect
|
|||
assert(mNodes[nodeID].height >= 0);
|
||||
|
||||
// If the new AABB is still inside the fat AABB of the node
|
||||
if (mNodes[nodeID].aabb.contains(newAABB)) {
|
||||
if (!forceReinsert && mNodes[nodeID].aabb.contains(newAABB)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -194,22 +196,22 @@ bool DynamicAABBTree::updateObject(int32 nodeID, const AABB& newAABB, const Vect
|
|||
|
||||
// Inflate the fat AABB in direction of the linear motion of the AABB
|
||||
if (displacement.x < decimal(0.0)) {
|
||||
mNodes[nodeID].aabb.mMinCoordinates.x += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.x;
|
||||
mNodes[nodeID].aabb.mMinCoordinates.x += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER * displacement.x;
|
||||
}
|
||||
else {
|
||||
mNodes[nodeID].aabb.mMaxCoordinates.x += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.x;
|
||||
mNodes[nodeID].aabb.mMaxCoordinates.x += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER * displacement.x;
|
||||
}
|
||||
if (displacement.y < decimal(0.0)) {
|
||||
mNodes[nodeID].aabb.mMinCoordinates.y += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.y;
|
||||
mNodes[nodeID].aabb.mMinCoordinates.y += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER * displacement.y;
|
||||
}
|
||||
else {
|
||||
mNodes[nodeID].aabb.mMaxCoordinates.y += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.y;
|
||||
mNodes[nodeID].aabb.mMaxCoordinates.y += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER * displacement.y;
|
||||
}
|
||||
if (displacement.z < decimal(0.0)) {
|
||||
mNodes[nodeID].aabb.mMinCoordinates.z += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.z;
|
||||
mNodes[nodeID].aabb.mMinCoordinates.z += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER * displacement.z;
|
||||
}
|
||||
else {
|
||||
mNodes[nodeID].aabb.mMaxCoordinates.z += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.z;
|
||||
mNodes[nodeID].aabb.mMaxCoordinates.z += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER * displacement.z;
|
||||
}
|
||||
|
||||
assert(mNodes[nodeID].aabb.contains(newAABB));
|
||||
|
|
|
@ -225,7 +225,8 @@ class DynamicAABBTree {
|
|||
void removeObject(int32 nodeID);
|
||||
|
||||
/// Update the dynamic tree after an object has moved.
|
||||
bool updateObject(int32 nodeID, const AABB& newAABB, const Vector3& displacement);
|
||||
bool updateObject(int32 nodeID, const AABB& newAABB, const Vector3& displacement,
|
||||
bool forceReinsert = false);
|
||||
|
||||
/// Return the fat AABB corresponding to a given node ID
|
||||
const AABB& getFatAABB(int32 nodeID) const;
|
||||
|
|
|
@ -38,7 +38,7 @@ using namespace reactphysics3d;
|
|||
* @param halfExtents The vector with the three half-extents of the box
|
||||
*/
|
||||
BoxShape::BoxShape(const Vector3& halfExtents, MemoryAllocator& allocator)
|
||||
: ConvexPolyhedronShape(CollisionShapeName::BOX), mHalfExtents(halfExtents),
|
||||
: ConvexPolyhedronShape(CollisionShapeName::BOX, allocator), mHalfExtents(halfExtents),
|
||||
mHalfEdgeStructure(allocator, 6, 8, 24) {
|
||||
|
||||
assert(halfExtents.x > decimal(0.0));
|
||||
|
|
|
@ -149,6 +149,8 @@ inline Vector3 BoxShape::getHalfExtents() const {
|
|||
*/
|
||||
inline void BoxShape::setHalfExtents(const Vector3& halfExtents) {
|
||||
mHalfExtents = halfExtents;
|
||||
|
||||
notifyColliderAboutChangedSize();
|
||||
}
|
||||
|
||||
// Return the local bounds of the shape in x, y and z directions
|
||||
|
|
|
@ -37,8 +37,8 @@ using namespace reactphysics3d;
|
|||
* @param radius The radius of the capsule (in meters)
|
||||
* @param height The height of the capsule (in meters)
|
||||
*/
|
||||
CapsuleShape::CapsuleShape(decimal radius, decimal height)
|
||||
: ConvexShape(CollisionShapeName::CAPSULE, CollisionShapeType::CAPSULE, radius), mHalfHeight(height * decimal(0.5)) {
|
||||
CapsuleShape::CapsuleShape(decimal radius, decimal height, MemoryAllocator& allocator)
|
||||
: ConvexShape(CollisionShapeName::CAPSULE, CollisionShapeType::CAPSULE, allocator, radius), mHalfHeight(height * decimal(0.5)) {
|
||||
// TODO : Throw a library error here if radius or height is not larger than zero
|
||||
assert(radius > decimal(0.0));
|
||||
assert(height > decimal(0.0));
|
||||
|
|
|
@ -58,7 +58,7 @@ class CapsuleShape : public ConvexShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CapsuleShape(decimal radius, decimal height);
|
||||
CapsuleShape(decimal radius, decimal height, MemoryAllocator& allocator);
|
||||
|
||||
/// Return a local support point in a given direction without the object margin
|
||||
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const override;
|
||||
|
@ -137,6 +137,8 @@ inline void CapsuleShape::setRadius(decimal radius) {
|
|||
// TODO : Throw a library error here if radius is not larger than zero
|
||||
assert(radius > decimal(0.0));
|
||||
mMargin = radius;
|
||||
|
||||
notifyColliderAboutChangedSize();
|
||||
}
|
||||
|
||||
// Return the height of the capsule
|
||||
|
@ -158,6 +160,8 @@ inline void CapsuleShape::setHeight(decimal height) {
|
|||
// TODO : Throw a library error here if radius is not larger than zero
|
||||
assert(height > decimal(0.0));
|
||||
mHalfHeight = height * decimal(0.5);
|
||||
|
||||
notifyColliderAboutChangedSize();
|
||||
}
|
||||
|
||||
// Return the number of bytes used by the collision shape
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
#include "CollisionShape.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include "body/CollisionBody.h"
|
||||
#include "collision/Collider.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
CollisionShape::CollisionShape(CollisionShapeName name, CollisionShapeType type)
|
||||
: mType(type), mName(name), mId(0) {
|
||||
CollisionShape::CollisionShape(CollisionShapeName name, CollisionShapeType type, MemoryAllocator &allocator)
|
||||
: mType(type), mName(name), mId(0), mColliders(allocator) {
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
mProfiler = nullptr;
|
||||
|
@ -90,3 +91,11 @@ void CollisionShape::computeAABB(AABB& aabb, const Transform& transform) const {
|
|||
aabb.setMin(resultMin);
|
||||
aabb.setMax(resultMax);
|
||||
}
|
||||
|
||||
/// Notify all the assign colliders that the size of the collision shape has changed
|
||||
void CollisionShape::notifyColliderAboutChangedSize() {
|
||||
|
||||
for (uint i=0; i < mColliders.size(); i++) {
|
||||
mColliders[i]->setHasCollisionShapeChangedSize(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,9 @@ class CollisionShape {
|
|||
/// Unique identifier of the shape inside an overlapping pair
|
||||
uint32 mId;
|
||||
|
||||
/// List of the colliders associated with this shape
|
||||
List<Collider*> mColliders;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Pointer to the profiler
|
||||
|
@ -93,12 +96,21 @@ class CollisionShape {
|
|||
/// Return the number of bytes used by the collision shape
|
||||
virtual size_t getSizeInBytes() const = 0;
|
||||
|
||||
/// Assign a new collider to the collision shape
|
||||
void addCollider(Collider* collider);
|
||||
|
||||
/// Remove an assigned collider from the collision shape
|
||||
void removeCollider(Collider* collider);
|
||||
|
||||
/// Notify all the assign colliders that the size of the collision shape has changed
|
||||
void notifyColliderAboutChangedSize();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CollisionShape(CollisionShapeName name, CollisionShapeType type);
|
||||
CollisionShape(CollisionShapeName name, CollisionShapeType type, MemoryAllocator& allocator);
|
||||
|
||||
/// Destructor
|
||||
virtual ~CollisionShape() = default;
|
||||
|
@ -146,7 +158,10 @@ class CollisionShape {
|
|||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class Collider;
|
||||
friend class CollisionBody;
|
||||
friend class RigidBody;
|
||||
friend class PhyscisWorld;
|
||||
friend class BroadPhaseSystem;
|
||||
};
|
||||
|
||||
// Return the name of the collision shape
|
||||
|
@ -170,6 +185,16 @@ inline uint32 CollisionShape::getId() const {
|
|||
return mId;
|
||||
}
|
||||
|
||||
// Assign a new collider to the collision shape
|
||||
inline void CollisionShape::addCollider(Collider* collider) {
|
||||
mColliders.add(collider);
|
||||
}
|
||||
|
||||
// Remove an assigned collider from the collision shape
|
||||
inline void CollisionShape::removeCollider(Collider* collider) {
|
||||
mColliders.remove(collider);
|
||||
}
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Set the profiler
|
||||
|
|
|
@ -35,7 +35,7 @@ using namespace reactphysics3d;
|
|||
|
||||
// Constructor
|
||||
ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, MemoryAllocator& allocator, const Vector3& scaling)
|
||||
: ConcaveShape(CollisionShapeName::TRIANGLE_MESH, scaling), mDynamicAABBTree(allocator) {
|
||||
: ConcaveShape(CollisionShapeName::TRIANGLE_MESH, allocator, scaling), mDynamicAABBTree(allocator) {
|
||||
|
||||
mTriangleMesh = triangleMesh;
|
||||
mRaycastTestType = TriangleRaycastSide::FRONT;
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
ConcaveShape::ConcaveShape(CollisionShapeName name, const Vector3& scaling)
|
||||
: CollisionShape(name, CollisionShapeType::CONCAVE_SHAPE), mRaycastTestType(TriangleRaycastSide::FRONT),
|
||||
ConcaveShape::ConcaveShape(CollisionShapeName name, MemoryAllocator& allocator, const Vector3& scaling)
|
||||
: CollisionShape(name, CollisionShapeType::CONCAVE_SHAPE, allocator), mRaycastTestType(TriangleRaycastSide::FRONT),
|
||||
mScale(scaling) {
|
||||
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ class ConcaveShape : public CollisionShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ConcaveShape(CollisionShapeName name, const Vector3& scaling);
|
||||
ConcaveShape(CollisionShapeName name, MemoryAllocator& allocator, const Vector3& scaling);
|
||||
|
||||
/// Destructor
|
||||
virtual ~ConcaveShape() override = default;
|
||||
|
@ -151,6 +151,8 @@ inline const Vector3& ConcaveShape::getScale() const {
|
|||
/// after changing the scale of a collision shape
|
||||
inline void ConcaveShape::setScale(const Vector3& scale) {
|
||||
mScale = scale;
|
||||
|
||||
notifyColliderAboutChangedSize();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ using namespace reactphysics3d;
|
|||
* @param stride Stride between the beginning of two elements in the vertices array
|
||||
* @param margin Collision margin (in meters) around the collision shape
|
||||
*/
|
||||
ConvexMeshShape::ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scale)
|
||||
: ConvexPolyhedronShape(CollisionShapeName::CONVEX_MESH), mPolyhedronMesh(polyhedronMesh),
|
||||
ConvexMeshShape::ConvexMeshShape(PolyhedronMesh* polyhedronMesh, MemoryAllocator& allocator, const Vector3& scale)
|
||||
: ConvexPolyhedronShape(CollisionShapeName::CONVEX_MESH, allocator), mPolyhedronMesh(polyhedronMesh),
|
||||
mMinBounds(0, 0, 0), mMaxBounds(0, 0, 0), mScale(scale) {
|
||||
|
||||
// Recalculate the bounds of the mesh
|
||||
|
|
|
@ -66,7 +66,7 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scale = Vector3(1,1,1));
|
||||
ConvexMeshShape(PolyhedronMesh* polyhedronMesh, MemoryAllocator& allocator, const Vector3& scale = Vector3(1,1,1));
|
||||
|
||||
/// Recompute the bounds of the mesh
|
||||
void recalculateBounds();
|
||||
|
@ -159,6 +159,7 @@ inline const Vector3& ConvexMeshShape::getScale() const {
|
|||
inline void ConvexMeshShape::setScale(const Vector3& scale) {
|
||||
mScale = scale;
|
||||
recalculateBounds();
|
||||
notifyColliderAboutChangedSize();
|
||||
}
|
||||
|
||||
// Return the local bounds of the shape in x, y and z directions
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
ConvexPolyhedronShape::ConvexPolyhedronShape(CollisionShapeName name)
|
||||
: ConvexShape(name, CollisionShapeType::CONVEX_POLYHEDRON) {
|
||||
ConvexPolyhedronShape::ConvexPolyhedronShape(CollisionShapeName name, MemoryAllocator& allocator)
|
||||
: ConvexShape(name, CollisionShapeType::CONVEX_POLYHEDRON, allocator) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class ConvexPolyhedronShape : public ConvexShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ConvexPolyhedronShape(CollisionShapeName name);
|
||||
ConvexPolyhedronShape(CollisionShapeName name, MemoryAllocator& allocator);
|
||||
|
||||
/// Destructor
|
||||
virtual ~ConvexPolyhedronShape() override = default;
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
ConvexShape::ConvexShape(CollisionShapeName name, CollisionShapeType type, decimal margin)
|
||||
: CollisionShape(name, type), mMargin(margin) {
|
||||
ConvexShape::ConvexShape(CollisionShapeName name, CollisionShapeType type, MemoryAllocator& allocator, decimal margin)
|
||||
: CollisionShape(name, type, allocator), mMargin(margin) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ class ConvexShape : public CollisionShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ConvexShape(CollisionShapeName name, CollisionShapeType type, decimal margin = decimal(0.0));
|
||||
ConvexShape(CollisionShapeName name, CollisionShapeType type, MemoryAllocator& allocator, decimal margin = decimal(0.0));
|
||||
|
||||
/// Destructor
|
||||
virtual ~ConvexShape() override = default;
|
||||
|
|
|
@ -42,9 +42,9 @@ using namespace reactphysics3d;
|
|||
* @param integerHeightScale Scaling factor used to scale the height values (only when height values type is integer)
|
||||
*/
|
||||
HeightFieldShape::HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight,
|
||||
const void* heightFieldData, HeightDataType dataType, int upAxis,
|
||||
const void* heightFieldData, HeightDataType dataType, MemoryAllocator& allocator, int upAxis,
|
||||
decimal integerHeightScale, const Vector3& scaling)
|
||||
: ConcaveShape(CollisionShapeName::HEIGHTFIELD, scaling), mNbColumns(nbGridColumns), mNbRows(nbGridRows),
|
||||
: ConcaveShape(CollisionShapeName::HEIGHTFIELD, allocator, scaling), mNbColumns(nbGridColumns), mNbRows(nbGridRows),
|
||||
mWidth(nbGridColumns - 1), mLength(nbGridRows - 1), mMinHeight(minHeight),
|
||||
mMaxHeight(maxHeight), mUpAxis(upAxis), mIntegerHeightScale(integerHeightScale),
|
||||
mHeightDataType(dataType) {
|
||||
|
|
|
@ -95,7 +95,7 @@ class HeightFieldShape : public ConcaveShape {
|
|||
|
||||
/// Constructor
|
||||
HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight,
|
||||
const void* heightFieldData, HeightDataType dataType,
|
||||
const void* heightFieldData, HeightDataType dataType, MemoryAllocator& allocator,
|
||||
int upAxis = 1, decimal integerHeightScale = 1.0f,
|
||||
const Vector3& scaling = Vector3(1,1,1));
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ using namespace reactphysics3d;
|
|||
/**
|
||||
* @param radius Radius of the sphere
|
||||
*/
|
||||
SphereShape::SphereShape(decimal radius)
|
||||
: ConvexShape(CollisionShapeName::SPHERE, CollisionShapeType::SPHERE, radius) {
|
||||
SphereShape::SphereShape(decimal radius, MemoryAllocator& allocator)
|
||||
: ConvexShape(CollisionShapeName::SPHERE, CollisionShapeType::SPHERE, allocator, radius) {
|
||||
assert(radius > decimal(0.0));
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ class SphereShape : public ConvexShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
SphereShape(decimal radius);
|
||||
SphereShape(decimal radius, MemoryAllocator& allocator);
|
||||
|
||||
/// Return a local support point in a given direction without the object margin
|
||||
virtual Vector3 getLocalSupportPointWithoutMargin(const Vector3& direction) const override;
|
||||
|
@ -121,6 +121,8 @@ inline decimal SphereShape::getRadius() const {
|
|||
inline void SphereShape::setRadius(decimal radius) {
|
||||
assert(radius > decimal(0.0));
|
||||
mMargin = radius;
|
||||
|
||||
notifyColliderAboutChangedSize();
|
||||
}
|
||||
|
||||
// Return true if the collision shape is a polyhedron
|
||||
|
|
|
@ -47,7 +47,7 @@ using namespace reactphysics3d;
|
|||
*/
|
||||
TriangleShape::TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, uint shapeId,
|
||||
MemoryAllocator& allocator)
|
||||
: ConvexPolyhedronShape(CollisionShapeName::TRIANGLE), mFaces{HalfEdgeStructure::Face(allocator), HalfEdgeStructure::Face(allocator)} {
|
||||
: ConvexPolyhedronShape(CollisionShapeName::TRIANGLE, allocator), mFaces{HalfEdgeStructure::Face(allocator), HalfEdgeStructure::Face(allocator)} {
|
||||
|
||||
mPoints[0] = vertices[0];
|
||||
mPoints[1] = vertices[1];
|
||||
|
|
|
@ -37,7 +37,7 @@ using namespace reactphysics3d;
|
|||
ColliderComponents::ColliderComponents(MemoryAllocator& allocator)
|
||||
:Components(allocator, sizeof(Entity) + sizeof(Entity) + sizeof(Collider*) + sizeof(int) +
|
||||
sizeof(Transform) + sizeof(CollisionShape*) + sizeof(decimal) + sizeof(unsigned short) +
|
||||
sizeof(unsigned short) + sizeof(Transform) + sizeof(List<uint64>)) {
|
||||
sizeof(unsigned short) + sizeof(Transform) + sizeof(List<uint64>) + sizeof(bool)) {
|
||||
|
||||
// Allocate memory for the components data
|
||||
allocate(INIT_NB_ALLOCATED_COMPONENTS);
|
||||
|
@ -67,6 +67,7 @@ void ColliderComponents::allocate(uint32 nbComponentsToAllocate) {
|
|||
unsigned short* newCollideWithMaskBits = reinterpret_cast<unsigned short*>(newCollisionCategoryBits + nbComponentsToAllocate);
|
||||
Transform* newLocalToWorldTransforms = reinterpret_cast<Transform*>(newCollideWithMaskBits + nbComponentsToAllocate);
|
||||
List<uint64>* newOverlappingPairs = reinterpret_cast<List<uint64>*>(newLocalToWorldTransforms + nbComponentsToAllocate);
|
||||
bool* hasCollisionShapeChangedSize = reinterpret_cast<bool*>(newOverlappingPairs + nbComponentsToAllocate);
|
||||
|
||||
// If there was already components before
|
||||
if (mNbComponents > 0) {
|
||||
|
@ -83,6 +84,7 @@ void ColliderComponents::allocate(uint32 nbComponentsToAllocate) {
|
|||
memcpy(newCollideWithMaskBits, mCollideWithMaskBits, mNbComponents * sizeof(unsigned short));
|
||||
memcpy(newLocalToWorldTransforms, mLocalToWorldTransforms, mNbComponents * sizeof(Transform));
|
||||
memcpy(newOverlappingPairs, mOverlappingPairs, mNbComponents * sizeof(List<uint64>));
|
||||
memcpy(hasCollisionShapeChangedSize, mHasCollisionShapeChangedSize, mNbComponents * sizeof(bool));
|
||||
|
||||
// Deallocate previous memory
|
||||
mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * mComponentDataSize);
|
||||
|
@ -101,6 +103,7 @@ void ColliderComponents::allocate(uint32 nbComponentsToAllocate) {
|
|||
mCollideWithMaskBits = newCollideWithMaskBits;
|
||||
mLocalToWorldTransforms = newLocalToWorldTransforms;
|
||||
mOverlappingPairs = newOverlappingPairs;
|
||||
mHasCollisionShapeChangedSize = hasCollisionShapeChangedSize;
|
||||
|
||||
mNbAllocatedComponents = nbComponentsToAllocate;
|
||||
}
|
||||
|
@ -123,6 +126,7 @@ void ColliderComponents::addComponent(Entity colliderEntity, bool isSleeping, co
|
|||
new (mCollideWithMaskBits + index) unsigned short(component.collideWithMaskBits);
|
||||
new (mLocalToWorldTransforms + index) Transform(component.localToWorldTransform);
|
||||
new (mOverlappingPairs + index) List<uint64>(mMemoryAllocator);
|
||||
mHasCollisionShapeChangedSize[index] = false;
|
||||
|
||||
// Map the entity with the new component lookup index
|
||||
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(colliderEntity, index));
|
||||
|
@ -150,6 +154,7 @@ void ColliderComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex)
|
|||
new (mCollideWithMaskBits + destIndex) unsigned short(mCollideWithMaskBits[srcIndex]);
|
||||
new (mLocalToWorldTransforms + destIndex) Transform(mLocalToWorldTransforms[srcIndex]);
|
||||
new (mOverlappingPairs + destIndex) List<uint64>(mOverlappingPairs[srcIndex]);
|
||||
mHasCollisionShapeChangedSize[destIndex] = mHasCollisionShapeChangedSize[srcIndex];
|
||||
|
||||
// Destroy the source component
|
||||
destroyComponent(srcIndex);
|
||||
|
@ -177,6 +182,7 @@ void ColliderComponents::swapComponents(uint32 index1, uint32 index2) {
|
|||
unsigned short collideWithMaskBits1 = mCollideWithMaskBits[index1];
|
||||
Transform localToWorldTransform1 = mLocalToWorldTransforms[index1];
|
||||
List<uint64> overlappingPairs = mOverlappingPairs[index1];
|
||||
bool hasCollisionShapeChangedSize = mHasCollisionShapeChangedSize[index1];
|
||||
|
||||
// Destroy component 1
|
||||
destroyComponent(index1);
|
||||
|
@ -195,6 +201,7 @@ void ColliderComponents::swapComponents(uint32 index1, uint32 index2) {
|
|||
new (mCollideWithMaskBits + index2) unsigned short(collideWithMaskBits1);
|
||||
new (mLocalToWorldTransforms + index2) Transform(localToWorldTransform1);
|
||||
new (mOverlappingPairs + index2) List<uint64>(overlappingPairs);
|
||||
mHasCollisionShapeChangedSize[index2] = hasCollisionShapeChangedSize;
|
||||
|
||||
// Update the entity to component index mapping
|
||||
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(colliderEntity1, index2));
|
||||
|
|
|
@ -95,6 +95,11 @@ class ColliderComponents : public Components {
|
|||
/// Array with the list of involved overlapping pairs for each collider
|
||||
List<uint64>* mOverlappingPairs;
|
||||
|
||||
/// True if the size of the collision shape associated with the collider
|
||||
/// has been changed by the user
|
||||
bool* mHasCollisionShapeChangedSize;
|
||||
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Allocate memory for a given number of components
|
||||
|
@ -191,6 +196,12 @@ class ColliderComponents : public Components {
|
|||
/// Return a reference to the list of overlapping pairs for a given collider
|
||||
List<uint64>& getOverlappingPairs(Entity colliderEntity);
|
||||
|
||||
/// Return true if the size of collision shape of the collider has been changed by the user
|
||||
bool getHasCollisionShapeChangedSize(Entity colliderEntity) const;
|
||||
|
||||
/// Return true if the size of collision shape of the collider has been changed by the user
|
||||
void setHasCollisionShapeChangedSize(Entity colliderEntity, bool hasCollisionShapeChangedSize);
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class BroadPhaseSystem;
|
||||
|
@ -319,6 +330,22 @@ inline List<uint64>& ColliderComponents::getOverlappingPairs(Entity colliderEnti
|
|||
return mOverlappingPairs[mMapEntityToComponentIndex[colliderEntity]];
|
||||
}
|
||||
|
||||
// Return true if the size of collision shape of the collider has been changed by the user
|
||||
inline bool ColliderComponents::getHasCollisionShapeChangedSize(Entity colliderEntity) const {
|
||||
|
||||
assert(mMapEntityToComponentIndex.containsKey(colliderEntity));
|
||||
|
||||
return mHasCollisionShapeChangedSize[mMapEntityToComponentIndex[colliderEntity]];
|
||||
}
|
||||
|
||||
// Return true if the size of collision shape of the collider has been changed by the user
|
||||
inline void ColliderComponents::setHasCollisionShapeChangedSize(Entity colliderEntity, bool hasCollisionShapeChangedSize) {
|
||||
|
||||
assert(mMapEntityToComponentIndex.containsKey(colliderEntity));
|
||||
|
||||
mHasCollisionShapeChangedSize[mMapEntityToComponentIndex[colliderEntity]] = hasCollisionShapeChangedSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -159,7 +159,7 @@ void PhysicsCommon::destroyPhysicsWorld(PhysicsWorld* world) {
|
|||
// Create and return a sphere collision shape
|
||||
SphereShape* PhysicsCommon::createSphereShape(const decimal radius) {
|
||||
|
||||
SphereShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(SphereShape))) SphereShape(radius);
|
||||
SphereShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(SphereShape))) SphereShape(radius, mMemoryManager.getHeapAllocator());
|
||||
mSphereShapes.add(shape);
|
||||
|
||||
return shape;
|
||||
|
@ -202,7 +202,7 @@ void PhysicsCommon::destroyBoxShape(BoxShape* boxShape) {
|
|||
// Create and return a capsule shape
|
||||
CapsuleShape* PhysicsCommon::createCapsuleShape(decimal radius, decimal height) {
|
||||
|
||||
CapsuleShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(CapsuleShape))) CapsuleShape(radius, height);
|
||||
CapsuleShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(CapsuleShape))) CapsuleShape(radius, height, mMemoryManager.getHeapAllocator());
|
||||
|
||||
mCapsuleShapes.add(shape);
|
||||
|
||||
|
@ -224,7 +224,7 @@ void PhysicsCommon::destroyCapsuleShape(CapsuleShape* capsuleShape) {
|
|||
// Create and return a convex mesh shape
|
||||
ConvexMeshShape* PhysicsCommon::createConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling) {
|
||||
|
||||
ConvexMeshShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(ConvexMeshShape))) ConvexMeshShape(polyhedronMesh, scaling);
|
||||
ConvexMeshShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(ConvexMeshShape))) ConvexMeshShape(polyhedronMesh, mMemoryManager.getHeapAllocator(), scaling);
|
||||
|
||||
mConvexMeshShapes.add(shape);
|
||||
|
||||
|
@ -249,7 +249,7 @@ HeightFieldShape* PhysicsCommon::createHeightFieldShape(int nbGridColumns, int n
|
|||
int upAxis, decimal integerHeightScale, const Vector3& scaling) {
|
||||
|
||||
HeightFieldShape* shape = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(HeightFieldShape))) HeightFieldShape(nbGridColumns, nbGridRows, minHeight, maxHeight,
|
||||
heightFieldData, dataType, upAxis, integerHeightScale, scaling);
|
||||
heightFieldData, dataType, mMemoryManager.getHeapAllocator(), upAxis, integerHeightScale, scaling);
|
||||
|
||||
mHeightFieldShapes.add(shape);
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ void BroadPhaseSystem::addCollider(Collider* collider, const AABB& aabb) {
|
|||
|
||||
// Add the collision shape into the array of bodies that have moved (or have been created)
|
||||
// during the last simulation step
|
||||
addMovedCollisionShape(collider->getBroadPhaseId(), collider);
|
||||
addMovedCollider(collider->getBroadPhaseId(), collider);
|
||||
}
|
||||
|
||||
// Remove a collider from the broad-phase collision detection
|
||||
|
@ -106,7 +106,7 @@ void BroadPhaseSystem::removeCollider(Collider* collider) {
|
|||
|
||||
// Remove the collision shape into the array of shapes that have moved (or have been created)
|
||||
// during the last simulation step
|
||||
removeMovedCollisionShape(broadPhaseID);
|
||||
removeMovedCollider(broadPhaseID);
|
||||
}
|
||||
|
||||
// Update the broad-phase state of a single collider
|
||||
|
@ -133,12 +133,13 @@ void BroadPhaseSystem::updateColliders(decimal timeStep) {
|
|||
}
|
||||
|
||||
// Notify the broad-phase that a collision shape has moved and need to be updated
|
||||
void BroadPhaseSystem::updateColliderInternal(int32 broadPhaseId, Collider* collider, const AABB& aabb, const Vector3& displacement) {
|
||||
void BroadPhaseSystem::updateColliderInternal(int32 broadPhaseId, Collider* collider, const AABB& aabb, const Vector3& displacement,
|
||||
bool forceReInsert) {
|
||||
|
||||
assert(broadPhaseId >= 0);
|
||||
|
||||
// Update the dynamic AABB tree according to the movement of the collision shape
|
||||
bool hasBeenReInserted = mDynamicAABBTree.updateObject(broadPhaseId, aabb, displacement);
|
||||
bool hasBeenReInserted = mDynamicAABBTree.updateObject(broadPhaseId, aabb, displacement, forceReInsert);
|
||||
|
||||
// If the collision shape has moved out of its fat AABB (and therefore has been reinserted
|
||||
// into the tree).
|
||||
|
@ -146,7 +147,7 @@ void BroadPhaseSystem::updateColliderInternal(int32 broadPhaseId, Collider* coll
|
|||
|
||||
// Add the collision shape into the array of shapes that have moved (or have been created)
|
||||
// during the last simulation step
|
||||
addMovedCollisionShape(broadPhaseId, collider);
|
||||
addMovedCollider(broadPhaseId, collider);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,16 +190,22 @@ void BroadPhaseSystem::updateCollidersComponents(uint32 startIndex, uint32 nbIte
|
|||
AABB aabb;
|
||||
mCollidersComponents.mCollisionShapes[i]->computeAABB(aabb, transform * mCollidersComponents.mLocalToBodyTransforms[i]);
|
||||
|
||||
// Update the broad-phase state for the collider
|
||||
updateColliderInternal(broadPhaseId, mCollidersComponents.mColliders[i], aabb, displacement);
|
||||
// If the size of the collision shape has been changed by the user,
|
||||
// we need to reset the broad-phase AABB to its new size
|
||||
const bool forceReInsert = mCollidersComponents.mHasCollisionShapeChangedSize[i];
|
||||
|
||||
// Update the broad-phase state of the collider
|
||||
updateColliderInternal(broadPhaseId, mCollidersComponents.mColliders[i], aabb, displacement, forceReInsert);
|
||||
|
||||
mCollidersComponents.mHasCollisionShapeChangedSize[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add a collision shape in the array of shapes that have moved in the last simulation step
|
||||
// Add a collider in the array of colliders that have moved in the last simulation step
|
||||
// and that need to be tested again for broad-phase overlapping.
|
||||
void BroadPhaseSystem::addMovedCollisionShape(int broadPhaseID, Collider* collider) {
|
||||
void BroadPhaseSystem::addMovedCollider(int broadPhaseID, Collider* collider) {
|
||||
|
||||
assert(broadPhaseID != -1);
|
||||
|
||||
|
|
|
@ -140,7 +140,8 @@ class BroadPhaseSystem {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Notify the Dynamic AABB tree that a collider needs to be updated
|
||||
void updateColliderInternal(int32 broadPhaseId, Collider* collider, const AABB& aabb, const Vector3& displacement);
|
||||
void updateColliderInternal(int32 broadPhaseId, Collider* collider, const AABB& aabb, const Vector3& displacement,
|
||||
bool forceReInsert);
|
||||
|
||||
/// Update the broad-phase state of some colliders components
|
||||
void updateCollidersComponents(uint32 startIndex, uint32 nbItems, decimal timeStep);
|
||||
|
@ -174,13 +175,13 @@ class BroadPhaseSystem {
|
|||
/// Update the broad-phase state of all the enabled colliders
|
||||
void updateColliders(decimal timeStep);
|
||||
|
||||
/// Add a collision shape in the array of shapes that have moved in the last simulation step
|
||||
/// Add a collider in the array of colliders that have moved in the last simulation step
|
||||
/// and that need to be tested again for broad-phase overlapping.
|
||||
void addMovedCollisionShape(int broadPhaseID, Collider* collider);
|
||||
void addMovedCollider(int broadPhaseID, Collider* collider);
|
||||
|
||||
/// Remove a collision shape from the array of shapes that have moved in the last simulation
|
||||
/// Remove a collider from the array of colliders that have moved in the last simulation
|
||||
/// step and that need to be tested again for broad-phase overlapping.
|
||||
void removeMovedCollisionShape(int broadPhaseID);
|
||||
void removeMovedCollider(int broadPhaseID);
|
||||
|
||||
/// Compute all the overlapping pairs of collision shapes
|
||||
void computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int32, int32>>& overlappingNodes);
|
||||
|
@ -211,9 +212,9 @@ inline const AABB& BroadPhaseSystem::getFatAABB(int broadPhaseId) const {
|
|||
return mDynamicAABBTree.getFatAABB(broadPhaseId);
|
||||
}
|
||||
|
||||
// Remove a collision shape from the array of shapes that have moved in the last simulation step
|
||||
// Remove a collider from the array of colliders that have moved in the last simulation step
|
||||
// and that need to be tested again for broad-phase overlapping.
|
||||
inline void BroadPhaseSystem::removeMovedCollisionShape(int broadPhaseID) {
|
||||
inline void BroadPhaseSystem::removeMovedCollider(int broadPhaseID) {
|
||||
|
||||
// Remove the broad-phase ID from the set
|
||||
mMovedShapes.remove(broadPhaseID);
|
||||
|
|
|
@ -99,7 +99,7 @@ void CollisionDetectionSystem::computeBroadPhase() {
|
|||
|
||||
RP3D_PROFILE("CollisionDetectionSystem::computeBroadPhase()", mProfiler);
|
||||
|
||||
// Ask the broad-phase to compute all the shapes overlapping the shapes that
|
||||
// Ask the broad-phase to compute all the shapes overlapping with the shapes that
|
||||
// have moved or have been added in the last frame. This call can only add new
|
||||
// overlapping pairs in the collision detection.
|
||||
List<Pair<int32, int32>> overlappingNodes(mMemoryManager.getPoolAllocator(), 32);
|
||||
|
|
|
@ -396,7 +396,7 @@ inline void CollisionDetectionSystem::removeNoCollisionPair(Entity body1Entity,
|
|||
inline void CollisionDetectionSystem::askForBroadPhaseCollisionCheck(Collider* shape) {
|
||||
|
||||
if (shape->getBroadPhaseId() != -1) {
|
||||
mBroadPhaseSystem.addMovedCollisionShape(shape->getBroadPhaseId(), shape);
|
||||
mBroadPhaseSystem.addMovedCollider(shape->getBroadPhaseId(), shape);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user