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