Compute the fat AABB by adding a percentage of the size of the initial AABB instead of using a constant offset. Do not use linear displacement anymore in inflate the AABB in direction of the motion in the broad-phase
This commit is contained in:
parent
7477460e4f
commit
0ec26f5184
|
@ -35,8 +35,8 @@ using namespace reactphysics3d;
|
|||
const int32 TreeNode::NULL_TREE_NODE = -1;
|
||||
|
||||
// Constructor
|
||||
DynamicAABBTree::DynamicAABBTree(MemoryAllocator& allocator, decimal extraAABBGap)
|
||||
: mAllocator(allocator), mExtraAABBGap(extraAABBGap) {
|
||||
DynamicAABBTree::DynamicAABBTree(MemoryAllocator& allocator, decimal fatAABBInflatePercentage)
|
||||
: mAllocator(allocator), mFatAABBInflatePercentage(fatAABBInflatePercentage) {
|
||||
|
||||
init();
|
||||
}
|
||||
|
@ -135,8 +135,8 @@ int32 DynamicAABBTree::addObjectInternal(const AABB& aabb) {
|
|||
// Get the next available node (or allocate new ones if necessary)
|
||||
int32 nodeID = allocateNode();
|
||||
|
||||
// Create the fat aabb to use in the tree
|
||||
const Vector3 gap(mExtraAABBGap, mExtraAABBGap, mExtraAABBGap);
|
||||
// Create the fat aabb to use in the tree (inflate the aabb by a constant percentage of its size)
|
||||
const Vector3 gap(aabb.getExtent() * mFatAABBInflatePercentage * decimal(0.5f));
|
||||
mNodes[nodeID].aabb.setMin(aabb.getMin() - gap);
|
||||
mNodes[nodeID].aabb.setMax(aabb.getMax() + gap);
|
||||
|
||||
|
@ -167,12 +167,11 @@ void DynamicAABBTree::removeObject(int32 nodeID) {
|
|||
// Update the dynamic tree after an object has moved.
|
||||
/// If the new AABB of the object that has moved is still inside its fat AABB, then
|
||||
/// 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. If the "forceReInsert" parameter is true, we force the existing AABB to take the size
|
||||
/// The method returns true if the object has been reinserted into the tree.
|
||||
/// 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) {
|
||||
bool DynamicAABBTree::updateObject(int32 nodeID, const AABB& newAABB, bool forceReinsert) {
|
||||
|
||||
RP3D_PROFILE("DynamicAABBTree::updateObject()", mProfiler);
|
||||
|
||||
|
@ -188,32 +187,12 @@ bool DynamicAABBTree::updateObject(int32 nodeID, const AABB& newAABB, const Vect
|
|||
// If the new AABB is outside the fat AABB, we remove the corresponding node
|
||||
removeLeafNode(nodeID);
|
||||
|
||||
// Compute the fat AABB by inflating the AABB with a constant gap
|
||||
// Compute the fat AABB by inflating the AABB with by a constant percentage of the size of the AABB
|
||||
mNodes[nodeID].aabb = newAABB;
|
||||
const Vector3 gap(mExtraAABBGap, mExtraAABBGap, mExtraAABBGap);
|
||||
const Vector3 gap(newAABB.getExtent() * mFatAABBInflatePercentage * decimal(0.5f));
|
||||
mNodes[nodeID].aabb.mMinCoordinates -= gap;
|
||||
mNodes[nodeID].aabb.mMaxCoordinates += gap;
|
||||
|
||||
// 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;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
}
|
||||
else {
|
||||
mNodes[nodeID].aabb.mMaxCoordinates.z += DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER * displacement.z;
|
||||
}
|
||||
|
||||
assert(mNodes[nodeID].aabb.contains(newAABB));
|
||||
|
||||
// Reinsert the node into the tree
|
||||
|
|
|
@ -158,9 +158,8 @@ class DynamicAABBTree {
|
|||
/// Number of nodes in the tree
|
||||
int32 mNbNodes;
|
||||
|
||||
/// Extra AABB Gap used to allow the collision shape to move a little bit
|
||||
/// without triggering a large modification of the tree which can be costly
|
||||
decimal mExtraAABBGap;
|
||||
/// The fat AABB is the initial AABB inflated by a given percentage of its size.
|
||||
decimal mFatAABBInflatePercentage;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -210,7 +209,7 @@ class DynamicAABBTree {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
DynamicAABBTree(MemoryAllocator& allocator, decimal extraAABBGap = decimal(0.0));
|
||||
DynamicAABBTree(MemoryAllocator& allocator, decimal fatAABBInflatePercentage = decimal(0.0));
|
||||
|
||||
/// Destructor
|
||||
~DynamicAABBTree();
|
||||
|
@ -225,8 +224,7 @@ 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 forceReinsert = false);
|
||||
bool updateObject(int32 nodeID, const AABB& newAABB, bool forceReinsert = false);
|
||||
|
||||
/// Return the fat AABB corresponding to a given node ID
|
||||
const AABB& getFatAABB(int32 nodeID) const;
|
||||
|
|
|
@ -100,14 +100,9 @@ constexpr decimal PI = decimal(3.14159265);
|
|||
constexpr decimal PI_TIMES_2 = decimal(6.28318530);
|
||||
|
||||
/// In the broad-phase collision detection (dynamic AABB tree), the AABBs are
|
||||
/// inflated with a constant gap to allow the collision shape to move a little bit
|
||||
/// without triggering a large modification of the tree which can be costly
|
||||
constexpr decimal DYNAMIC_TREE_AABB_GAP = decimal(0.1);
|
||||
|
||||
/// In the broad-phase collision detection (dynamic AABB tree), the AABBs are
|
||||
/// also inflated in direction of the linear motion of the body by mutliplying the
|
||||
/// followin constant with the linear velocity and the elapsed time between two frames.
|
||||
constexpr decimal DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER = decimal(1.7);
|
||||
/// inflated by a constant percentage of its size to allow the collision shape to move a little bit
|
||||
/// without triggering a large modification of the tree each frame which can be costly
|
||||
constexpr decimal DYNAMIC_TREE_FAT_AABB_INFLATE_PERCENTAGE = decimal(0.08);
|
||||
|
||||
/// Current version of ReactPhysics3D
|
||||
const std::string RP3D_VERSION = std::string("0.7.1");
|
||||
|
|
|
@ -36,8 +36,8 @@ using namespace reactphysics3d;
|
|||
|
||||
// Constructor
|
||||
BroadPhaseSystem::BroadPhaseSystem(CollisionDetectionSystem& collisionDetection, ColliderComponents& collidersComponents,
|
||||
TransformComponents& transformComponents, RigidBodyComponents &rigidBodyComponents)
|
||||
:mDynamicAABBTree(collisionDetection.getMemoryManager().getPoolAllocator(), DYNAMIC_TREE_AABB_GAP),
|
||||
TransformComponents& transformComponents, RigidBodyComponents& rigidBodyComponents)
|
||||
:mDynamicAABBTree(collisionDetection.getMemoryManager().getPoolAllocator(), DYNAMIC_TREE_FAT_AABB_INFLATE_PERCENTAGE),
|
||||
mCollidersComponents(collidersComponents), mTransformsComponents(transformComponents),
|
||||
mRigidBodyComponents(rigidBodyComponents), mMovedShapes(collisionDetection.getMemoryManager().getPoolAllocator()),
|
||||
mCollisionDetection(collisionDetection) {
|
||||
|
@ -133,13 +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,
|
||||
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, forceReInsert);
|
||||
bool hasBeenReInserted = mDynamicAABBTree.updateObject(broadPhaseId, aabb, forceReInsert);
|
||||
|
||||
// If the collision shape has moved out of its fat AABB (and therefore has been reinserted
|
||||
// into the tree).
|
||||
|
@ -176,16 +176,6 @@ void BroadPhaseSystem::updateCollidersComponents(uint32 startIndex, uint32 nbIte
|
|||
const Entity& bodyEntity = mCollidersComponents.mBodiesEntities[i];
|
||||
const Transform& transform = mTransformsComponents.getTransform(bodyEntity);
|
||||
|
||||
// If there is a dynamics component for the current entity
|
||||
Vector3 displacement(0, 0, 0);
|
||||
if (mRigidBodyComponents.hasComponent(bodyEntity)) {
|
||||
|
||||
// Get the linear velocity from the dynamics component
|
||||
const Vector3& linearVelocity = mRigidBodyComponents.getLinearVelocity(bodyEntity);
|
||||
|
||||
displacement = timeStep * linearVelocity;
|
||||
}
|
||||
|
||||
// Recompute the world-space AABB of the collision shape
|
||||
AABB aabb;
|
||||
mCollidersComponents.mCollisionShapes[i]->computeAABB(aabb, transform * mCollidersComponents.mLocalToBodyTransforms[i]);
|
||||
|
@ -195,7 +185,7 @@ void BroadPhaseSystem::updateCollidersComponents(uint32 startIndex, uint32 nbIte
|
|||
const bool forceReInsert = mCollidersComponents.mHasCollisionShapeChangedSize[i];
|
||||
|
||||
// Update the broad-phase state of the collider
|
||||
updateColliderInternal(broadPhaseId, mCollidersComponents.mColliders[i], aabb, displacement, forceReInsert);
|
||||
updateColliderInternal(broadPhaseId, mCollidersComponents.mColliders[i], aabb, forceReInsert);
|
||||
|
||||
mCollidersComponents.mHasCollisionShapeChangedSize[i] = false;
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ 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,
|
||||
bool forceReInsert);
|
||||
|
||||
/// Update the broad-phase state of some colliders components
|
||||
|
|
|
@ -238,10 +238,10 @@ class TestDynamicAABBTree : public Test {
|
|||
|
||||
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
||||
|
||||
tree.updateObject(object1Id, aabb1, Vector3::zero());
|
||||
tree.updateObject(object2Id, aabb2, Vector3::zero());
|
||||
tree.updateObject(object3Id, aabb3, Vector3::zero());
|
||||
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
||||
tree.updateObject(object1Id, aabb1);
|
||||
tree.updateObject(object2Id, aabb2);
|
||||
tree.updateObject(object3Id, aabb3);
|
||||
tree.updateObject(object4Id, aabb4);
|
||||
|
||||
// AABB overlapping nothing
|
||||
overlappingNodes.clear();
|
||||
|
@ -285,10 +285,10 @@ class TestDynamicAABBTree : public Test {
|
|||
|
||||
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
||||
|
||||
tree.updateObject(object1Id, aabb1, Vector3::zero());
|
||||
tree.updateObject(object2Id, aabb2, Vector3::zero());
|
||||
tree.updateObject(object3Id, aabb3, Vector3::zero());
|
||||
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
||||
tree.updateObject(object1Id, aabb1);
|
||||
tree.updateObject(object2Id, aabb2);
|
||||
tree.updateObject(object3Id, aabb3);
|
||||
tree.updateObject(object4Id, aabb4);
|
||||
|
||||
// AABB overlapping nothing
|
||||
overlappingNodes.clear();
|
||||
|
@ -333,10 +333,10 @@ class TestDynamicAABBTree : public Test {
|
|||
// ---- Move objects 2 and 3 ----- //
|
||||
|
||||
AABB newAABB2(Vector3(-7, 10, -3), Vector3(1, 13, 3));
|
||||
tree.updateObject(object2Id, newAABB2, Vector3::zero());
|
||||
tree.updateObject(object2Id, newAABB2);
|
||||
|
||||
AABB newAABB3(Vector3(7, -6, -3), Vector3(9, 1, 3));
|
||||
tree.updateObject(object3Id, newAABB3, Vector3::zero());
|
||||
tree.updateObject(object3Id, newAABB3);
|
||||
|
||||
// AABB overlapping object 3
|
||||
overlappingNodes.clear();
|
||||
|
@ -424,10 +424,10 @@ class TestDynamicAABBTree : public Test {
|
|||
|
||||
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
||||
|
||||
tree.updateObject(object1Id, aabb1, Vector3::zero());
|
||||
tree.updateObject(object2Id, aabb2, Vector3::zero());
|
||||
tree.updateObject(object3Id, aabb3, Vector3::zero());
|
||||
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
||||
tree.updateObject(object1Id, aabb1);
|
||||
tree.updateObject(object2Id, aabb2);
|
||||
tree.updateObject(object3Id, aabb3);
|
||||
tree.updateObject(object4Id, aabb4);
|
||||
|
||||
// Ray with no hits
|
||||
mRaycastCallback.reset();
|
||||
|
@ -463,10 +463,10 @@ class TestDynamicAABBTree : public Test {
|
|||
|
||||
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
||||
|
||||
tree.updateObject(object1Id, aabb1, Vector3::zero());
|
||||
tree.updateObject(object2Id, aabb2, Vector3::zero());
|
||||
tree.updateObject(object3Id, aabb3, Vector3::zero());
|
||||
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
||||
tree.updateObject(object1Id, aabb1);
|
||||
tree.updateObject(object2Id, aabb2);
|
||||
tree.updateObject(object3Id, aabb3);
|
||||
tree.updateObject(object4Id, aabb4);
|
||||
|
||||
// Ray with no hits
|
||||
mRaycastCallback.reset();
|
||||
|
@ -503,10 +503,10 @@ class TestDynamicAABBTree : public Test {
|
|||
// ---- Move objects 2 and 3 ----- //
|
||||
|
||||
AABB newAABB2(Vector3(-7, 10, -3), Vector3(1, 13, 3));
|
||||
tree.updateObject(object2Id, newAABB2, Vector3::zero());
|
||||
tree.updateObject(object2Id, newAABB2);
|
||||
|
||||
AABB newAABB3(Vector3(7, -6, -3), Vector3(9, 1, 3));
|
||||
tree.updateObject(object3Id, newAABB3, Vector3::zero());
|
||||
tree.updateObject(object3Id, newAABB3);
|
||||
|
||||
// Ray that hits object 1, 2
|
||||
Ray ray5(Vector3(-4, -5, 0), Vector3(-4, 12, 0));
|
||||
|
|
Loading…
Reference in New Issue
Block a user