Do not use callbacks for middle-phase collision detection
This commit is contained in:
parent
9deb90dc6f
commit
db995ea52c
|
@ -120,7 +120,6 @@ SET (REACTPHYSICS3D_HEADERS
|
||||||
"src/collision/HalfEdgeStructure.h"
|
"src/collision/HalfEdgeStructure.h"
|
||||||
"src/collision/CollisionDetection.h"
|
"src/collision/CollisionDetection.h"
|
||||||
"src/collision/ContactManifold.h"
|
"src/collision/ContactManifold.h"
|
||||||
"src/collision/MiddlePhaseTriangleCallback.h"
|
|
||||||
"src/constraint/BallAndSocketJoint.h"
|
"src/constraint/BallAndSocketJoint.h"
|
||||||
"src/constraint/ContactPoint.h"
|
"src/constraint/ContactPoint.h"
|
||||||
"src/constraint/FixedJoint.h"
|
"src/constraint/FixedJoint.h"
|
||||||
|
@ -213,7 +212,6 @@ SET (REACTPHYSICS3D_SOURCES
|
||||||
"src/collision/HalfEdgeStructure.cpp"
|
"src/collision/HalfEdgeStructure.cpp"
|
||||||
"src/collision/CollisionDetection.cpp"
|
"src/collision/CollisionDetection.cpp"
|
||||||
"src/collision/ContactManifold.cpp"
|
"src/collision/ContactManifold.cpp"
|
||||||
"src/collision/MiddlePhaseTriangleCallback.cpp"
|
|
||||||
"src/constraint/BallAndSocketJoint.cpp"
|
"src/constraint/BallAndSocketJoint.cpp"
|
||||||
"src/constraint/ContactPoint.cpp"
|
"src/constraint/ContactPoint.cpp"
|
||||||
"src/constraint/FixedJoint.cpp"
|
"src/constraint/FixedJoint.cpp"
|
||||||
|
|
|
@ -90,7 +90,7 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, con
|
||||||
AABB(localBoundsMin, localBoundsMax),
|
AABB(localBoundsMin, localBoundsMax),
|
||||||
transform, collisionShape, decimal(1), 0x0001, 0xFFFF);
|
transform, collisionShape, decimal(1), 0x0001, 0xFFFF);
|
||||||
bool isActive = mWorld.mCollisionBodyComponents.getIsActive(mEntity);
|
bool isActive = mWorld.mCollisionBodyComponents.getIsActive(mEntity);
|
||||||
mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, isActive, proxyShapeComponent);
|
mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, !isActive, proxyShapeComponent);
|
||||||
|
|
||||||
mWorld.mCollisionBodyComponents.addProxyShapeToBody(mEntity, proxyShapeEntity);
|
mWorld.mCollisionBodyComponents.addProxyShapeToBody(mEntity, proxyShapeEntity);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "body/RigidBody.h"
|
#include "body/RigidBody.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "collision/CollisionCallback.h"
|
#include "collision/CollisionCallback.h"
|
||||||
#include "collision/MiddlePhaseTriangleCallback.h"
|
|
||||||
#include "collision/OverlapCallback.h"
|
#include "collision/OverlapCallback.h"
|
||||||
#include "collision/narrowphase/NarrowPhaseInfoBatch.h"
|
#include "collision/narrowphase/NarrowPhaseInfoBatch.h"
|
||||||
#include "collision/ContactManifold.h"
|
#include "collision/ContactManifold.h"
|
||||||
|
@ -289,26 +288,28 @@ void CollisionDetection::computeMiddlePhase(OverlappingPairMap& overlappingPairs
|
||||||
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
|
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
|
||||||
NarrowPhaseInput& narrowPhaseInput) {
|
NarrowPhaseInput& narrowPhaseInput) {
|
||||||
|
|
||||||
|
RP3D_PROFILE("CollisionDetection::computeConvexVsConcaveMiddlePhase()", mProfiler);
|
||||||
|
|
||||||
ProxyShape* shape1 = pair->getShape1();
|
ProxyShape* shape1 = pair->getShape1();
|
||||||
ProxyShape* shape2 = pair->getShape2();
|
ProxyShape* shape2 = pair->getShape2();
|
||||||
|
|
||||||
ProxyShape* convexProxyShape;
|
ProxyShape* convexProxyShape;
|
||||||
ProxyShape* concaveProxyShape;
|
ProxyShape* concaveProxyShape;
|
||||||
const ConvexShape* convexShape;
|
ConvexShape* convexShape;
|
||||||
const ConcaveShape* concaveShape;
|
ConcaveShape* concaveShape;
|
||||||
|
|
||||||
// Collision shape 1 is convex, collision shape 2 is concave
|
// Collision shape 1 is convex, collision shape 2 is concave
|
||||||
if (shape1->getCollisionShape()->isConvex()) {
|
if (shape1->getCollisionShape()->isConvex()) {
|
||||||
convexProxyShape = shape1;
|
convexProxyShape = shape1;
|
||||||
convexShape = static_cast<const ConvexShape*>(shape1->getCollisionShape());
|
convexShape = static_cast<ConvexShape*>(shape1->getCollisionShape());
|
||||||
concaveProxyShape = shape2;
|
concaveProxyShape = shape2;
|
||||||
concaveShape = static_cast<const ConcaveShape*>(shape2->getCollisionShape());
|
concaveShape = static_cast<ConcaveShape*>(shape2->getCollisionShape());
|
||||||
}
|
}
|
||||||
else { // Collision shape 2 is convex, collision shape 1 is concave
|
else { // Collision shape 2 is convex, collision shape 1 is concave
|
||||||
convexProxyShape = shape2;
|
convexProxyShape = shape2;
|
||||||
convexShape = static_cast<const ConvexShape*>(shape2->getCollisionShape());
|
convexShape = static_cast<ConvexShape*>(shape2->getCollisionShape());
|
||||||
concaveProxyShape = shape1;
|
concaveProxyShape = shape1;
|
||||||
concaveShape = static_cast<const ConcaveShape*>(shape1->getCollisionShape());
|
concaveShape = static_cast<ConcaveShape*>(shape1->getCollisionShape());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select the narrow phase algorithm to use according to the two collision shapes
|
// Select the narrow phase algorithm to use according to the two collision shapes
|
||||||
|
@ -317,25 +318,48 @@ void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair
|
||||||
|
|
||||||
assert(algorithmType != NarrowPhaseAlgorithmType::None);
|
assert(algorithmType != NarrowPhaseAlgorithmType::None);
|
||||||
|
|
||||||
// Set the parameters of the callback object
|
|
||||||
MiddlePhaseTriangleCallback middlePhaseCallback(pair, concaveProxyShape, convexProxyShape,
|
|
||||||
concaveShape, narrowPhaseInput, algorithmType, allocator);
|
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
|
||||||
|
|
||||||
// Set the profiler
|
|
||||||
middlePhaseCallback.setProfiler(mProfiler);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Compute the convex shape AABB in the local-space of the convex shape
|
// Compute the convex shape AABB in the local-space of the convex shape
|
||||||
const Transform convexToConcaveTransform = concaveProxyShape->getLocalToWorldTransform().getInverse() *
|
const Transform convexToConcaveTransform = concaveProxyShape->getLocalToWorldTransform().getInverse() *
|
||||||
convexProxyShape->getLocalToWorldTransform();
|
convexProxyShape->getLocalToWorldTransform();
|
||||||
AABB aabb;
|
AABB aabb;
|
||||||
convexShape->computeAABB(aabb, convexToConcaveTransform);
|
convexShape->computeAABB(aabb, convexToConcaveTransform);
|
||||||
|
|
||||||
// Call the convex vs triangle callback for each triangle of the concave shape
|
// Compute the concave shape triangles that are overlapping with the convex mesh AABB
|
||||||
concaveShape->testAllTriangles(middlePhaseCallback, aabb);
|
List<Vector3> triangleVertices(allocator);
|
||||||
|
List<Vector3> triangleVerticesNormals(allocator);
|
||||||
|
List<uint> shapeIds(allocator);
|
||||||
|
concaveShape->computeOverlappingTriangles(aabb, triangleVertices, triangleVerticesNormals, shapeIds, allocator);
|
||||||
|
|
||||||
|
assert(triangleVertices.size() == triangleVerticesNormals.size());
|
||||||
|
assert(shapeIds.size() == triangleVertices.size() / 3);
|
||||||
|
assert(triangleVertices.size() % 3 == 0);
|
||||||
|
assert(triangleVerticesNormals.size() % 3 == 0);
|
||||||
|
|
||||||
|
// For each overlapping triangle
|
||||||
|
for (uint i=0; i < shapeIds.size(); i++)
|
||||||
|
{
|
||||||
|
// Create a triangle collision shape (the allocated memory for the TriangleShape will be released in the
|
||||||
|
// destructor of the corresponding NarrowPhaseInfo.
|
||||||
|
TriangleShape* triangleShape = new (allocator.allocate(sizeof(TriangleShape)))
|
||||||
|
TriangleShape(&(triangleVertices[i * 3]), &(triangleVerticesNormals[i * 3]), shapeIds[i], allocator);
|
||||||
|
|
||||||
|
#ifdef IS_PROFILING_ACTIVE
|
||||||
|
|
||||||
|
// Set the profiler to the triangle shape
|
||||||
|
triangleShape->setProfiler(mProfiler);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool isShape1Convex = pair->getShape1()->getCollisionShape()->isConvex();
|
||||||
|
ProxyShape* shape1 = isShape1Convex ? convexProxyShape : concaveProxyShape;
|
||||||
|
ProxyShape* shape2 = isShape1Convex ? concaveProxyShape : convexProxyShape;
|
||||||
|
|
||||||
|
// Create a narrow phase info for the narrow-phase collision detection
|
||||||
|
narrowPhaseInput.addNarrowPhaseTest(pair, isShape1Convex ? convexShape : triangleShape,
|
||||||
|
isShape1Convex ? triangleShape : convexShape,
|
||||||
|
shape1->getLocalToWorldTransform(), shape2->getLocalToWorldTransform(),
|
||||||
|
algorithmType, allocator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the narrow-phase collision detection algorithm on batches
|
// Execute the narrow-phase collision detection algorithm on batches
|
||||||
|
|
|
@ -65,21 +65,13 @@ struct ContactPointInfo {
|
||||||
/// Contact point of body 2 in local space of body 2
|
/// Contact point of body 2 in local space of body 2
|
||||||
Vector3 localPoint2;
|
Vector3 localPoint2;
|
||||||
|
|
||||||
// TODO : Remove this field
|
|
||||||
/// Pointer to the next contact point info
|
|
||||||
ContactPointInfo* next;
|
|
||||||
|
|
||||||
// TODO : Remove this field
|
|
||||||
/// True if the contact point has already been inserted into a manifold
|
|
||||||
bool isUsed;
|
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
ContactPointInfo(const Vector3& contactNormal, decimal penDepth,
|
ContactPointInfo(const Vector3& contactNormal, decimal penDepth,
|
||||||
const Vector3& localPt1, const Vector3& localPt2)
|
const Vector3& localPt1, const Vector3& localPt2)
|
||||||
: normal(contactNormal), penetrationDepth(penDepth),
|
: normal(contactNormal), penetrationDepth(penDepth),
|
||||||
localPoint1(localPt1), localPoint2(localPt2), next(nullptr), isUsed(false) {
|
localPoint1(localPt1), localPoint2(localPt2) {
|
||||||
|
|
||||||
assert(contactNormal.lengthSquare() > decimal(0.8));
|
assert(contactNormal.lengthSquare() > decimal(0.8));
|
||||||
assert(penDepth > decimal(0.0));
|
assert(penDepth > decimal(0.0));
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
|
||||||
* Copyright (c) 2010-2018 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 "collision/MiddlePhaseTriangleCallback.h"
|
|
||||||
#include "engine/OverlappingPair.h"
|
|
||||||
#include "collision/shapes/TriangleShape.h"
|
|
||||||
#include "collision/narrowphase/NarrowPhaseInput.h"
|
|
||||||
|
|
||||||
using namespace reactphysics3d;
|
|
||||||
|
|
||||||
// Report collision between a triangle of a concave shape and the convex mesh shape (for middle-phase)
|
|
||||||
void MiddlePhaseTriangleCallback::testTriangle(const Vector3* trianglePoints, const Vector3* verticesNormals, uint shapeId) {
|
|
||||||
|
|
||||||
// Create a triangle collision shape (the allocated memory for the TriangleShape will be released in the
|
|
||||||
// destructor of the corresponding NarrowPhaseInfo.
|
|
||||||
TriangleShape* triangleShape = new (mAllocator.allocate(sizeof(TriangleShape)))
|
|
||||||
TriangleShape(trianglePoints, verticesNormals, shapeId, mAllocator);
|
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
|
||||||
|
|
||||||
// Set the profiler to the triangle shape
|
|
||||||
triangleShape->setProfiler(mProfiler);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool isShape1Convex = mOverlappingPair->getShape1()->getCollisionShape()->isConvex();
|
|
||||||
ProxyShape* shape1 = isShape1Convex ? mConvexProxyShape : mConcaveProxyShape;
|
|
||||||
ProxyShape* shape2 = isShape1Convex ? mConcaveProxyShape : mConvexProxyShape;
|
|
||||||
|
|
||||||
// Create a narrow phase info for the narrow-phase collision detection
|
|
||||||
mOutNarrowPhaseInput.addNarrowPhaseTest(mOverlappingPair,
|
|
||||||
isShape1Convex ? mConvexProxyShape->getCollisionShape() : triangleShape,
|
|
||||||
isShape1Convex ? triangleShape : mConvexProxyShape->getCollisionShape(),
|
|
||||||
shape1->getLocalToWorldTransform(), shape2->getLocalToWorldTransform(),
|
|
||||||
mNarrowPhaseAlgorithmType, mAllocator);
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
|
||||||
* Copyright (c) 2010-2018 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_MIDDLE_PHASE_TRIANGLE_CALLBACK_H
|
|
||||||
#define REACTPHYSICS3D_MIDDLE_PHASE_TRIANGLE_CALLBACK_H
|
|
||||||
|
|
||||||
#include "configuration.h"
|
|
||||||
#include "collision/shapes/ConcaveShape.h"
|
|
||||||
|
|
||||||
/// Namespace ReactPhysics3D
|
|
||||||
namespace reactphysics3d {
|
|
||||||
|
|
||||||
// Libraries
|
|
||||||
|
|
||||||
// Declarations
|
|
||||||
class ConcaveShape;
|
|
||||||
class OverlappingPair;
|
|
||||||
class NarrowPhaseAlgorithm;
|
|
||||||
class ProxyShape;
|
|
||||||
class MemoryAllocator;
|
|
||||||
class Profiler;
|
|
||||||
class NarrowPhaseInput;
|
|
||||||
enum class NarrowPhaseAlgorithmType;
|
|
||||||
struct Vector3;
|
|
||||||
|
|
||||||
// Class ConvexVsTriangleCallback
|
|
||||||
/**
|
|
||||||
* This class is used to report a collision between the triangle
|
|
||||||
* of a concave mesh shape and a convex shape during the
|
|
||||||
* middle-phase algorithm.
|
|
||||||
*/
|
|
||||||
class MiddlePhaseTriangleCallback : public TriangleCallback {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/// Broadphase overlapping pair
|
|
||||||
OverlappingPair* mOverlappingPair;
|
|
||||||
|
|
||||||
/// Pointer to the concave proxy shape
|
|
||||||
ProxyShape* mConcaveProxyShape;
|
|
||||||
|
|
||||||
/// Pointer to the convex proxy shape
|
|
||||||
ProxyShape* mConvexProxyShape;
|
|
||||||
|
|
||||||
/// Pointer to the concave collision shape
|
|
||||||
const ConcaveShape* mConcaveShape;
|
|
||||||
|
|
||||||
/// Reference to the narrow phase input
|
|
||||||
NarrowPhaseInput& mOutNarrowPhaseInput;
|
|
||||||
|
|
||||||
/// Type of narrow-phase algorithm to use
|
|
||||||
NarrowPhaseAlgorithmType mNarrowPhaseAlgorithmType;
|
|
||||||
|
|
||||||
/// Reference to the single-frame memory allocator
|
|
||||||
MemoryAllocator& mAllocator;
|
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
|
||||||
|
|
||||||
/// Pointer to the profiler
|
|
||||||
Profiler* mProfiler;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
MiddlePhaseTriangleCallback(OverlappingPair* overlappingPair,
|
|
||||||
ProxyShape* concaveProxyShape,
|
|
||||||
ProxyShape* convexProxyShape, const ConcaveShape* concaveShape,
|
|
||||||
NarrowPhaseInput& outNarrowPhaseInput,
|
|
||||||
NarrowPhaseAlgorithmType algorithmType,
|
|
||||||
MemoryAllocator& allocator)
|
|
||||||
:mOverlappingPair(overlappingPair), mConcaveProxyShape(concaveProxyShape),
|
|
||||||
mConvexProxyShape(convexProxyShape), mConcaveShape(concaveShape),
|
|
||||||
mOutNarrowPhaseInput(outNarrowPhaseInput), mNarrowPhaseAlgorithmType(algorithmType),
|
|
||||||
mAllocator(allocator) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test collision between a triangle and the convex mesh shape
|
|
||||||
virtual void testTriangle(const Vector3* trianglePoints, const Vector3* verticesNormals, uint shapeId) override;
|
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
|
||||||
|
|
||||||
/// Set the profiler
|
|
||||||
void setProfiler(Profiler* profiler) {
|
|
||||||
mProfiler = profiler;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -642,9 +642,8 @@ void DynamicAABBTree::reportAllShapesOverlappingWithShapes(const List<int>& node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Report all shapes overlapping with the AABB given in parameter.
|
// Report all shapes overlapping with the AABB given in parameter.
|
||||||
// TODO : Do not use this method anymore. Use
|
void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const {
|
||||||
void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, DynamicAABBTreeOverlapCallback& callback) const {
|
|
||||||
|
|
||||||
// Create a stack with the nodes to visit
|
// Create a stack with the nodes to visit
|
||||||
Stack<int> stack(mAllocator, 64);
|
Stack<int> stack(mAllocator, 64);
|
||||||
|
@ -669,7 +668,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, Dynam
|
||||||
if (nodeToVisit->isLeaf()) {
|
if (nodeToVisit->isLeaf()) {
|
||||||
|
|
||||||
// Notify the broad-phase about a new potential overlapping pair
|
// Notify the broad-phase about a new potential overlapping pair
|
||||||
callback.notifyOverlappingNode(nodeIDToVisit);
|
overlappingNodes.add(nodeIDToVisit);
|
||||||
}
|
}
|
||||||
else { // If the node is not a leaf
|
else { // If the node is not a leaf
|
||||||
|
|
||||||
|
@ -682,7 +681,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, Dynam
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ray casting method
|
// Ray casting method
|
||||||
void DynamicAABBTree::raycast(const Ray& ray, DynamicAABBTreeRaycastCallback &callback) const {
|
void DynamicAABBTree::raycast(const Ray& ray, DynamicAABBTreeRaycastCallback& callback) const {
|
||||||
|
|
||||||
RP3D_PROFILE("DynamicAABBTree::raycast()", mProfiler);
|
RP3D_PROFILE("DynamicAABBTree::raycast()", mProfiler);
|
||||||
|
|
||||||
|
|
|
@ -242,7 +242,7 @@ class DynamicAABBTree {
|
||||||
size_t endIndex, List<Pair<int, int>>& outOverlappingNodes) const;
|
size_t endIndex, List<Pair<int, int>>& outOverlappingNodes) const;
|
||||||
|
|
||||||
/// Report all shapes overlapping with the AABB given in parameter.
|
/// Report all shapes overlapping with the AABB given in parameter.
|
||||||
void reportAllShapesOverlappingWithAABB(const AABB& aabb, DynamicAABBTreeOverlapCallback& callback) const;
|
void reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const;
|
||||||
|
|
||||||
/// Ray casting method
|
/// Ray casting method
|
||||||
void raycast(const Ray& ray, DynamicAABBTreeRaycastCallback& callback) const;
|
void raycast(const Ray& ray, DynamicAABBTreeRaycastCallback& callback) const;
|
||||||
|
|
|
@ -84,8 +84,7 @@ void ConcaveMeshShape::initBVHTree() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the three vertices coordinates (in the array outTriangleVertices) of a triangle
|
// Return the three vertices coordinates (in the array outTriangleVertices) of a triangle
|
||||||
void ConcaveMeshShape::getTriangleVertices(uint subPart, uint triangleIndex,
|
void ConcaveMeshShape::getTriangleVertices(uint subPart, uint triangleIndex, Vector3* outTriangleVertices) const {
|
||||||
Vector3* outTriangleVertices) const {
|
|
||||||
|
|
||||||
// Get the triangle vertex array of the current sub-part
|
// Get the triangle vertex array of the current sub-part
|
||||||
TriangleVertexArray* triangleVertexArray = mTriangleMesh->getSubpart(subPart);
|
TriangleVertexArray* triangleVertexArray = mTriangleMesh->getSubpart(subPart);
|
||||||
|
@ -116,14 +115,40 @@ void ConcaveMeshShape::getTriangleVerticesNormals(uint subPart, uint triangleInd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Use a callback method on all triangles of the concave shape inside a given AABB
|
// Compute all the triangles of the mesh that are overlapping with the AABB in parameter
|
||||||
void ConcaveMeshShape::testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const {
|
void ConcaveMeshShape::computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
|
||||||
|
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
|
||||||
|
MemoryAllocator& allocator) const {
|
||||||
|
|
||||||
ConvexTriangleAABBOverlapCallback overlapCallback(callback, *this, mDynamicAABBTree);
|
// Compute the nodes of the internal AABB tree that are overlapping with the AABB
|
||||||
|
List<int> overlappingNodes(allocator);
|
||||||
|
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(localAABB, overlappingNodes);
|
||||||
|
|
||||||
// Ask the Dynamic AABB Tree to report all the triangles that are overlapping
|
// For each overlapping node
|
||||||
// with the AABB of the convex shape.
|
for (uint i=0; i < overlappingNodes.size(); i++) {
|
||||||
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(localAABB, overlapCallback);
|
|
||||||
|
int nodeId = overlappingNodes[i];
|
||||||
|
|
||||||
|
// Get the node data (triangle index and mesh subpart index)
|
||||||
|
int32* data = mDynamicAABBTree.getNodeDataInt(nodeId);
|
||||||
|
|
||||||
|
// Get the triangle vertices for this node from the concave mesh shape
|
||||||
|
Vector3 trianglePoints[3];
|
||||||
|
getTriangleVertices(data[0], data[1], trianglePoints);
|
||||||
|
triangleVertices.add(trianglePoints[0]);
|
||||||
|
triangleVertices.add(trianglePoints[1]);
|
||||||
|
triangleVertices.add(trianglePoints[2]);
|
||||||
|
|
||||||
|
// Get the vertices normals of the triangle
|
||||||
|
Vector3 verticesNormals[3];
|
||||||
|
getTriangleVerticesNormals(data[0], data[1], verticesNormals);
|
||||||
|
triangleVerticesNormals.add(verticesNormals[0]);
|
||||||
|
triangleVerticesNormals.add(verticesNormals[1]);
|
||||||
|
triangleVerticesNormals.add(verticesNormals[2]);
|
||||||
|
|
||||||
|
// Compute the triangle shape ID
|
||||||
|
shapeIds.add(computeTriangleShapeId(data[0], data[1]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raycast method with feedback information
|
// Raycast method with feedback information
|
||||||
|
|
|
@ -155,7 +155,7 @@ class ConcaveMeshShape : public ConcaveShape {
|
||||||
/// Insert all the triangles into the dynamic AABB tree
|
/// Insert all the triangles into the dynamic AABB tree
|
||||||
void initBVHTree();
|
void initBVHTree();
|
||||||
|
|
||||||
/// Return the three vertices coordinates (in the array outTriangleVertices) of a triangle
|
/// Return the three vertices coordinates (in the list outTriangleVertices) of a triangle
|
||||||
void getTriangleVertices(uint subPart, uint triangleIndex, Vector3* outTriangleVertices) const;
|
void getTriangleVertices(uint subPart, uint triangleIndex, Vector3* outTriangleVertices) const;
|
||||||
|
|
||||||
/// Return the three vertex normals (in the array outVerticesNormals) of a triangle
|
/// Return the three vertex normals (in the array outVerticesNormals) of a triangle
|
||||||
|
@ -164,6 +164,11 @@ class ConcaveMeshShape : public ConcaveShape {
|
||||||
/// Compute the shape Id for a given triangle of the mesh
|
/// Compute the shape Id for a given triangle of the mesh
|
||||||
uint computeTriangleShapeId(uint subPart, uint triangleIndex) const;
|
uint computeTriangleShapeId(uint subPart, uint triangleIndex) const;
|
||||||
|
|
||||||
|
/// Compute all the triangles of the mesh that are overlapping with the AABB in parameter
|
||||||
|
virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3> &triangleVertices,
|
||||||
|
List<Vector3> &triangleVerticesNormals, List<uint>& shapeIds,
|
||||||
|
MemoryAllocator& allocator) const override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
|
@ -187,9 +192,6 @@ class ConcaveMeshShape : public ConcaveShape {
|
||||||
/// Return the local inertia tensor of the collision shape
|
/// Return the local inertia tensor of the collision shape
|
||||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
|
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
|
||||||
|
|
||||||
/// Use a callback method on all triangles of the concave shape inside a given AABB
|
|
||||||
virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const override;
|
|
||||||
|
|
||||||
/// Return the string representation of the shape
|
/// Return the string representation of the shape
|
||||||
virtual std::string to_string() const override;
|
virtual std::string to_string() const override;
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,9 @@ class ConcaveShape : public CollisionShape {
|
||||||
virtual bool isPolyhedron() const override;
|
virtual bool isPolyhedron() const override;
|
||||||
|
|
||||||
/// Use a callback method on all triangles of the concave shape inside a given AABB
|
/// Use a callback method on all triangles of the concave shape inside a given AABB
|
||||||
virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const=0;
|
virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
|
||||||
|
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
|
||||||
|
MemoryAllocator& allocator) const=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return true if the collision shape is convex, false if it is concave
|
// Return true if the collision shape is convex, false if it is concave
|
||||||
|
|
|
@ -91,7 +91,9 @@ void HeightFieldShape::getLocalBounds(Vector3& min, Vector3& max) const {
|
||||||
// of the body when need to test and see against which triangles of the height-field we need
|
// of the body when need to test and see against which triangles of the height-field we need
|
||||||
// to test for collision. We compute the sub-grid points that are inside the other body's AABB
|
// to test for collision. We compute the sub-grid points that are inside the other body's AABB
|
||||||
// and then for each rectangle in the sub-grid we generate two triangles that we use to test collision.
|
// and then for each rectangle in the sub-grid we generate two triangles that we use to test collision.
|
||||||
void HeightFieldShape::testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const {
|
void HeightFieldShape::computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
|
||||||
|
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
|
||||||
|
MemoryAllocator& allocator) const {
|
||||||
|
|
||||||
// Compute the non-scaled AABB
|
// Compute the non-scaled AABB
|
||||||
Vector3 inverseScaling(decimal(1.0) / mScaling.x, decimal(1.0) / mScaling.y, decimal(1.0) / mScaling.z);
|
Vector3 inverseScaling(decimal(1.0) / mScaling.x, decimal(1.0) / mScaling.y, decimal(1.0) / mScaling.z);
|
||||||
|
@ -141,7 +143,9 @@ void HeightFieldShape::testAllTriangles(TriangleCallback& callback, const AABB&
|
||||||
const Vector3 p4 = getVertexAt(i + 1, j + 1);
|
const Vector3 p4 = getVertexAt(i + 1, j + 1);
|
||||||
|
|
||||||
// Generate the first triangle for the current grid rectangle
|
// Generate the first triangle for the current grid rectangle
|
||||||
Vector3 trianglePoints[3] = {p1, p2, p3};
|
triangleVertices.add(p1);
|
||||||
|
triangleVertices.add(p2);
|
||||||
|
triangleVertices.add(p3);
|
||||||
|
|
||||||
// Compute the triangle normal
|
// Compute the triangle normal
|
||||||
Vector3 triangle1Normal = (p2 - p1).cross(p3 - p1).getUnit();
|
Vector3 triangle1Normal = (p2 - p1).cross(p3 - p1).getUnit();
|
||||||
|
@ -153,15 +157,17 @@ void HeightFieldShape::testAllTriangles(TriangleCallback& callback, const AABB&
|
||||||
// and compute the angle of incident edges with asin(). Maybe we could also precompute the
|
// and compute the angle of incident edges with asin(). Maybe we could also precompute the
|
||||||
// vertices normal at the HeightFieldShape constructor but it will require extra memory to
|
// vertices normal at the HeightFieldShape constructor but it will require extra memory to
|
||||||
// store them.
|
// store them.
|
||||||
Vector3 verticesNormals1[3] = {triangle1Normal, triangle1Normal, triangle1Normal};
|
triangleVerticesNormals.add(triangle1Normal);
|
||||||
|
triangleVerticesNormals.add(triangle1Normal);
|
||||||
|
triangleVerticesNormals.add(triangle1Normal);
|
||||||
|
|
||||||
// Test collision against the first triangle
|
// Compute the shape ID
|
||||||
callback.testTriangle(trianglePoints, verticesNormals1, computeTriangleShapeId(i, j, 0));
|
shapeIds.add(computeTriangleShapeId(i, j, 0));
|
||||||
|
|
||||||
// Generate the second triangle for the current grid rectangle
|
// Generate the second triangle for the current grid rectangle
|
||||||
trianglePoints[0] = p3;
|
triangleVertices.add(p3);
|
||||||
trianglePoints[1] = p2;
|
triangleVertices.add(p2);
|
||||||
trianglePoints[2] = p4;
|
triangleVertices.add(p4);
|
||||||
|
|
||||||
// Compute the triangle normal
|
// Compute the triangle normal
|
||||||
Vector3 triangle2Normal = (p2 - p3).cross(p4 - p3).getUnit();
|
Vector3 triangle2Normal = (p2 - p3).cross(p4 - p3).getUnit();
|
||||||
|
@ -173,10 +179,12 @@ void HeightFieldShape::testAllTriangles(TriangleCallback& callback, const AABB&
|
||||||
// and compute the angle of incident edges with asin(). Maybe we could also precompute the
|
// and compute the angle of incident edges with asin(). Maybe we could also precompute the
|
||||||
// vertices normal at the HeightFieldShape constructor but it will require extra memory to
|
// vertices normal at the HeightFieldShape constructor but it will require extra memory to
|
||||||
// store them.
|
// store them.
|
||||||
Vector3 verticesNormals2[3] = {triangle2Normal, triangle2Normal, triangle2Normal};
|
triangleVerticesNormals.add(triangle2Normal);
|
||||||
|
triangleVerticesNormals.add(triangle2Normal);
|
||||||
|
triangleVerticesNormals.add(triangle2Normal);
|
||||||
|
|
||||||
// Test collision against the second triangle
|
// Compute the shape ID
|
||||||
callback.testTriangle(trianglePoints, verticesNormals2, computeTriangleShapeId(i, j, 1));
|
shapeIds.add(computeTriangleShapeId(i, j, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,22 +229,61 @@ bool HeightFieldShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxySh
|
||||||
|
|
||||||
RP3D_PROFILE("HeightFieldShape::raycast()", mProfiler);
|
RP3D_PROFILE("HeightFieldShape::raycast()", mProfiler);
|
||||||
|
|
||||||
TriangleOverlapCallback triangleCallback(ray, proxyShape, raycastInfo, *this, allocator);
|
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
|
||||||
|
|
||||||
// Set the profiler
|
|
||||||
triangleCallback.setProfiler(mProfiler);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Compute the AABB for the ray
|
// Compute the AABB for the ray
|
||||||
const Vector3 rayEnd = ray.point1 + ray.maxFraction * (ray.point2 - ray.point1);
|
const Vector3 rayEnd = ray.point1 + ray.maxFraction * (ray.point2 - ray.point1);
|
||||||
const AABB rayAABB(Vector3::min(ray.point1, rayEnd), Vector3::max(ray.point1, rayEnd));
|
const AABB rayAABB(Vector3::min(ray.point1, rayEnd), Vector3::max(ray.point1, rayEnd));
|
||||||
|
|
||||||
testAllTriangles(triangleCallback, rayAABB);
|
// Compute the triangles overlapping with the ray AABB
|
||||||
|
List<Vector3> triangleVertices(allocator);
|
||||||
|
List<Vector3> triangleVerticesNormals(allocator);
|
||||||
|
List<uint> shapeIds(allocator);
|
||||||
|
computeOverlappingTriangles(rayAABB, triangleVertices, triangleVerticesNormals, shapeIds, allocator);
|
||||||
|
|
||||||
return triangleCallback.getIsHit();
|
assert(triangleVertices.size() == triangleVerticesNormals.size());
|
||||||
|
assert(shapeIds.size() == triangleVertices.size() / 3);
|
||||||
|
assert(triangleVertices.size() % 3 == 0);
|
||||||
|
assert(triangleVerticesNormals.size() % 3 == 0);
|
||||||
|
|
||||||
|
bool isHit = false;
|
||||||
|
decimal smallestHitFraction = ray.maxFraction;
|
||||||
|
|
||||||
|
// For each overlapping triangle
|
||||||
|
for (uint i=0; i < shapeIds.size(); i++)
|
||||||
|
{
|
||||||
|
// Create a triangle collision shape
|
||||||
|
TriangleShape triangleShape(&(triangleVertices[i * 3]), &(triangleVerticesNormals[i * 3]), shapeIds[i], allocator);
|
||||||
|
triangleShape.setRaycastTestType(getRaycastTestType());
|
||||||
|
|
||||||
|
#ifdef IS_PROFILING_ACTIVE
|
||||||
|
|
||||||
|
// Set the profiler to the triangle shape
|
||||||
|
triangleShape.setProfiler(mProfiler);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Ray casting test against the collision shape
|
||||||
|
RaycastInfo triangleRaycastInfo;
|
||||||
|
bool isTriangleHit = triangleShape.raycast(ray, triangleRaycastInfo, proxyShape, allocator);
|
||||||
|
|
||||||
|
// If the ray hit the collision shape
|
||||||
|
if (isTriangleHit && triangleRaycastInfo.hitFraction <= smallestHitFraction) {
|
||||||
|
|
||||||
|
assert(triangleRaycastInfo.hitFraction >= decimal(0.0));
|
||||||
|
|
||||||
|
raycastInfo.body = triangleRaycastInfo.body;
|
||||||
|
raycastInfo.proxyShape = triangleRaycastInfo.proxyShape;
|
||||||
|
raycastInfo.hitFraction = triangleRaycastInfo.hitFraction;
|
||||||
|
raycastInfo.worldPoint = triangleRaycastInfo.worldPoint;
|
||||||
|
raycastInfo.worldNormal = triangleRaycastInfo.worldNormal;
|
||||||
|
raycastInfo.meshSubpart = -1;
|
||||||
|
raycastInfo.triangleIndex = -1;
|
||||||
|
|
||||||
|
smallestHitFraction = triangleRaycastInfo.hitFraction;
|
||||||
|
isHit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the vertex (local-coordinates) of the height field at a given (x,y) position
|
// Return the vertex (local-coordinates) of the height field at a given (x,y) position
|
||||||
|
@ -264,42 +311,6 @@ Vector3 HeightFieldShape::getVertexAt(int x, int y) const {
|
||||||
return vertex * mScaling;
|
return vertex * mScaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raycast test between a ray and a triangle of the heightfield
|
|
||||||
void TriangleOverlapCallback::testTriangle(const Vector3* trianglePoints, const Vector3* verticesNormals, uint shapeId) {
|
|
||||||
|
|
||||||
// Create a triangle collision shape
|
|
||||||
TriangleShape triangleShape(trianglePoints, verticesNormals, shapeId, mAllocator);
|
|
||||||
triangleShape.setRaycastTestType(mHeightFieldShape.getRaycastTestType());
|
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
|
||||||
|
|
||||||
// Set the profiler to the triangle shape
|
|
||||||
triangleShape.setProfiler(mProfiler);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Ray casting test against the collision shape
|
|
||||||
RaycastInfo raycastInfo;
|
|
||||||
bool isTriangleHit = triangleShape.raycast(mRay, raycastInfo, mProxyShape, mAllocator);
|
|
||||||
|
|
||||||
// If the ray hit the collision shape
|
|
||||||
if (isTriangleHit && raycastInfo.hitFraction <= mSmallestHitFraction) {
|
|
||||||
|
|
||||||
assert(raycastInfo.hitFraction >= decimal(0.0));
|
|
||||||
|
|
||||||
mRaycastInfo.body = raycastInfo.body;
|
|
||||||
mRaycastInfo.proxyShape = raycastInfo.proxyShape;
|
|
||||||
mRaycastInfo.hitFraction = raycastInfo.hitFraction;
|
|
||||||
mRaycastInfo.worldPoint = raycastInfo.worldPoint;
|
|
||||||
mRaycastInfo.worldNormal = raycastInfo.worldNormal;
|
|
||||||
mRaycastInfo.meshSubpart = -1;
|
|
||||||
mRaycastInfo.triangleIndex = -1;
|
|
||||||
|
|
||||||
mSmallestHitFraction = raycastInfo.hitFraction;
|
|
||||||
mIsHit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the string representation of the shape
|
// Return the string representation of the shape
|
||||||
std::string HeightFieldShape::to_string() const {
|
std::string HeightFieldShape::to_string() const {
|
||||||
|
|
||||||
|
|
|
@ -36,57 +36,6 @@ class HeightFieldShape;
|
||||||
class Profiler;
|
class Profiler;
|
||||||
class TriangleShape;
|
class TriangleShape;
|
||||||
|
|
||||||
// Class TriangleOverlapCallback
|
|
||||||
/**
|
|
||||||
* This class is used for testing AABB and triangle overlap for raycasting
|
|
||||||
*/
|
|
||||||
class TriangleOverlapCallback : public TriangleCallback {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
const Ray& mRay;
|
|
||||||
ProxyShape* mProxyShape;
|
|
||||||
RaycastInfo& mRaycastInfo;
|
|
||||||
bool mIsHit;
|
|
||||||
decimal mSmallestHitFraction;
|
|
||||||
const HeightFieldShape& mHeightFieldShape;
|
|
||||||
MemoryAllocator& mAllocator;
|
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
|
||||||
|
|
||||||
/// Pointer to the profiler
|
|
||||||
Profiler* mProfiler;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
TriangleOverlapCallback(const Ray& ray, ProxyShape* proxyShape, RaycastInfo& raycastInfo,
|
|
||||||
const HeightFieldShape& heightFieldShape, MemoryAllocator& allocator)
|
|
||||||
: mRay(ray), mProxyShape(proxyShape), mRaycastInfo(raycastInfo),
|
|
||||||
mHeightFieldShape (heightFieldShape), mAllocator(allocator) {
|
|
||||||
mIsHit = false;
|
|
||||||
mSmallestHitFraction = mRay.maxFraction;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getIsHit() const {return mIsHit;}
|
|
||||||
|
|
||||||
/// Raycast test between a ray and a triangle of the heightfield
|
|
||||||
virtual void testTriangle(const Vector3* trianglePoints, const Vector3* verticesNormals, uint shapeId) override;
|
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
|
||||||
|
|
||||||
/// Set the profiler
|
|
||||||
void setProfiler(Profiler* profiler) {
|
|
||||||
mProfiler = profiler;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Class HeightFieldShape
|
// Class HeightFieldShape
|
||||||
/**
|
/**
|
||||||
* This class represents a static height field that can be used to represent
|
* This class represents a static height field that can be used to represent
|
||||||
|
@ -212,7 +161,9 @@ class HeightFieldShape : public ConcaveShape {
|
||||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
|
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
|
||||||
|
|
||||||
/// Use a callback method on all triangles of the concave shape inside a given AABB
|
/// Use a callback method on all triangles of the concave shape inside a given AABB
|
||||||
virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const override;
|
virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
|
||||||
|
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
|
||||||
|
MemoryAllocator& allocator) const override;
|
||||||
|
|
||||||
/// Return the string representation of the shape
|
/// Return the string representation of the shape
|
||||||
virtual std::string to_string() const override;
|
virtual std::string to_string() const override;
|
||||||
|
|
|
@ -180,6 +180,7 @@ class TriangleShape : public ConvexPolyhedronShape {
|
||||||
friend class ConcaveMeshRaycastCallback;
|
friend class ConcaveMeshRaycastCallback;
|
||||||
friend class TriangleOverlapCallback;
|
friend class TriangleOverlapCallback;
|
||||||
friend class MiddlePhaseTriangleCallback;
|
friend class MiddlePhaseTriangleCallback;
|
||||||
|
friend class HeightFieldShape;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return the number of bytes used by the collision shape
|
// Return the number of bytes used by the collision shape
|
||||||
|
|
|
@ -117,7 +117,7 @@ void BroadPhaseSystem::updateProxyShape(Entity proxyShapeEntity) {
|
||||||
uint32 index = mProxyShapesComponents.mMapEntityToComponentIndex[proxyShapeEntity];
|
uint32 index = mProxyShapesComponents.mMapEntityToComponentIndex[proxyShapeEntity];
|
||||||
|
|
||||||
// Update the proxy-shape component
|
// Update the proxy-shape component
|
||||||
updateProxyShapesComponents(index, index + 1);
|
updateProxyShapesComponents(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the broad-phase state of all the enabled proxy-shapes
|
// Update the broad-phase state of all the enabled proxy-shapes
|
||||||
|
@ -146,15 +146,17 @@ void BroadPhaseSystem::updateProxyShapeInternal(int broadPhaseId, const AABB& aa
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the broad-phase state of some proxy-shapes components
|
// Update the broad-phase state of some proxy-shapes components
|
||||||
void BroadPhaseSystem::updateProxyShapesComponents(uint32 startIndex, uint32 endIndex) {
|
void BroadPhaseSystem::updateProxyShapesComponents(uint32 startIndex, uint32 nbItems) {
|
||||||
|
|
||||||
assert(startIndex <= endIndex);
|
assert(nbItems > 0);
|
||||||
assert(startIndex < mProxyShapesComponents.getNbComponents());
|
assert(startIndex < mProxyShapesComponents.getNbComponents());
|
||||||
assert(endIndex <= mProxyShapesComponents.getNbComponents());
|
assert(startIndex + nbItems <= mProxyShapesComponents.getNbComponents());
|
||||||
|
|
||||||
// Make sure we do not update disabled components
|
// Make sure we do not update disabled components
|
||||||
startIndex = std::min(startIndex, mProxyShapesComponents.getNbEnabledComponents());
|
startIndex = std::min(startIndex, mProxyShapesComponents.getNbEnabledComponents());
|
||||||
endIndex = std::min(endIndex, mProxyShapesComponents.getNbEnabledComponents());
|
uint32 endIndex = std::min(startIndex + nbItems, mProxyShapesComponents.getNbEnabledComponents());
|
||||||
|
nbItems = endIndex - startIndex;
|
||||||
|
assert(nbItems >= 0);
|
||||||
|
|
||||||
// Get the time step if we are in a dynamics world
|
// Get the time step if we are in a dynamics world
|
||||||
DynamicsWorld* dynamicsWorld = dynamic_cast<DynamicsWorld*>(mCollisionDetection.getWorld());
|
DynamicsWorld* dynamicsWorld = dynamic_cast<DynamicsWorld*>(mCollisionDetection.getWorld());
|
||||||
|
@ -164,7 +166,7 @@ void BroadPhaseSystem::updateProxyShapesComponents(uint32 startIndex, uint32 end
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each proxy-shape component to update
|
// For each proxy-shape component to update
|
||||||
for (uint32 i = startIndex; i < endIndex; i++) {
|
for (uint32 i = startIndex; i < startIndex + nbItems; i++) {
|
||||||
|
|
||||||
const int broadPhaseId = mProxyShapesComponents.mBroadPhaseIds[i];
|
const int broadPhaseId = mProxyShapesComponents.mBroadPhaseIds[i];
|
||||||
if (broadPhaseId != -1) {
|
if (broadPhaseId != -1) {
|
||||||
|
@ -193,14 +195,6 @@ void BroadPhaseSystem::updateProxyShapesComponents(uint32 startIndex, uint32 end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BroadPhaseSystem::reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const {
|
|
||||||
|
|
||||||
AABBOverlapCallback callback(overlappingNodes);
|
|
||||||
|
|
||||||
// Ask the dynamic AABB tree to report all collision shapes that overlap with this AABB
|
|
||||||
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(aabb, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute all the overlapping pairs of collision shapes
|
// Compute all the overlapping pairs of collision shapes
|
||||||
void BroadPhaseSystem::computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int, int>>& overlappingNodes) {
|
void BroadPhaseSystem::computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int, int>>& overlappingNodes) {
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ class BroadPhaseSystem {
|
||||||
void updateProxyShapeInternal(int broadPhaseId, const AABB& aabb, const Vector3& displacement);
|
void updateProxyShapeInternal(int broadPhaseId, const AABB& aabb, const Vector3& displacement);
|
||||||
|
|
||||||
/// Update the broad-phase state of some proxy-shapes components
|
/// Update the broad-phase state of some proxy-shapes components
|
||||||
void updateProxyShapesComponents(uint32 startIndex, uint32 endIndex);
|
void updateProxyShapesComponents(uint32 startIndex, uint32 nbItems);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
|
@ -182,9 +182,6 @@ class BroadPhaseSystem {
|
||||||
/// step and that need to be tested again for broad-phase overlapping.
|
/// step and that need to be tested again for broad-phase overlapping.
|
||||||
void removeMovedCollisionShape(int broadPhaseID);
|
void removeMovedCollisionShape(int broadPhaseID);
|
||||||
|
|
||||||
/// Report all the shapes that are overlapping with a given AABB
|
|
||||||
void reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const;
|
|
||||||
|
|
||||||
/// Compute all the overlapping pairs of collision shapes
|
/// Compute all the overlapping pairs of collision shapes
|
||||||
void computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int, int>>& overlappingNodes);
|
void computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int, int>>& overlappingNodes);
|
||||||
|
|
||||||
|
|
|
@ -31,32 +31,11 @@
|
||||||
#include "collision/broadphase/DynamicAABBTree.h"
|
#include "collision/broadphase/DynamicAABBTree.h"
|
||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
#include "utils/Profiler.h"
|
#include "utils/Profiler.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
/// Reactphysics3D namespace
|
/// Reactphysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
class TestOverlapCallback : public DynamicAABBTreeOverlapCallback {
|
|
||||||
|
|
||||||
public :
|
|
||||||
|
|
||||||
// TODO : Replace this by rp3d::List
|
|
||||||
std::vector<int> mOverlapNodes;
|
|
||||||
|
|
||||||
// Called when a overlapping node has been found during the call to
|
|
||||||
// DynamicAABBTree:reportAllShapesOverlappingWithAABB()
|
|
||||||
virtual void notifyOverlappingNode(int nodeId) override {
|
|
||||||
mOverlapNodes.push_back(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
mOverlapNodes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isOverlapping(int nodeId) const {
|
|
||||||
return std::find(mOverlapNodes.begin(), mOverlapNodes.end(), nodeId) != mOverlapNodes.end();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback {
|
class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -78,6 +57,7 @@ class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Class TestDynamicAABBTree
|
// Class TestDynamicAABBTree
|
||||||
/**
|
/**
|
||||||
* Unit test for the dynamic AABB tree
|
* Unit test for the dynamic AABB tree
|
||||||
|
@ -88,8 +68,8 @@ class TestDynamicAABBTree : public Test {
|
||||||
|
|
||||||
// ---------- Atributes ---------- //
|
// ---------- Atributes ---------- //
|
||||||
|
|
||||||
TestOverlapCallback mOverlapCallback;
|
|
||||||
DynamicTreeRaycastCallback mRaycastCallback;
|
DynamicTreeRaycastCallback mRaycastCallback;
|
||||||
|
PoolAllocator mAllocator;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
|
@ -101,6 +81,10 @@ class TestDynamicAABBTree : public Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isOverlapping(int nodeId, const List<int>& overlappingNodes) const {
|
||||||
|
return std::find(overlappingNodes.begin(), overlappingNodes.end(), nodeId) != overlappingNodes.end();
|
||||||
|
}
|
||||||
|
|
||||||
/// Run the tests
|
/// Run the tests
|
||||||
void run() {
|
void run() {
|
||||||
|
|
||||||
|
@ -202,45 +186,47 @@ class TestDynamicAABBTree : public Test {
|
||||||
|
|
||||||
// ---------- Tests ---------- //
|
// ---------- Tests ---------- //
|
||||||
|
|
||||||
|
List<int> overlappingNodes(mAllocator);
|
||||||
|
|
||||||
// AABB overlapping nothing
|
// AABB overlapping nothing
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping everything
|
// AABB overlapping everything
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 1 and 3
|
// AABB overlapping object 1 and 3
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 3 and 4
|
// AABB overlapping object 3 and 4
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 2
|
// AABB overlapping object 2
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
||||||
|
|
||||||
|
@ -250,44 +236,44 @@ class TestDynamicAABBTree : public Test {
|
||||||
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
||||||
|
|
||||||
// AABB overlapping nothing
|
// AABB overlapping nothing
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping everything
|
// AABB overlapping everything
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 1 and 3
|
// AABB overlapping object 1 and 3
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 3 and 4
|
// AABB overlapping object 3 and 4
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 2
|
// AABB overlapping object 2
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
||||||
|
|
||||||
|
@ -297,44 +283,44 @@ class TestDynamicAABBTree : public Test {
|
||||||
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
||||||
|
|
||||||
// AABB overlapping nothing
|
// AABB overlapping nothing
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping everything
|
// AABB overlapping everything
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 1 and 3
|
// AABB overlapping object 1 and 3
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 3 and 4
|
// AABB overlapping object 3 and 4
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping object 2
|
// AABB overlapping object 2
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// ---- Move objects 2 and 3 ----- //
|
// ---- Move objects 2 and 3 ----- //
|
||||||
|
|
||||||
|
@ -345,20 +331,20 @@ class TestDynamicAABBTree : public Test {
|
||||||
tree.updateObject(object3Id, newAABB3, Vector3::zero());
|
tree.updateObject(object3Id, newAABB3, Vector3::zero());
|
||||||
|
|
||||||
// AABB overlapping object 3
|
// AABB overlapping object 3
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(6, -10, -2), Vector3(8, 5, 3)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(6, -10, -2), Vector3(8, 5, 3)), overlappingNodes);
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
// AABB overlapping objects 1, 2
|
// AABB overlapping objects 1, 2
|
||||||
mOverlapCallback.reset();
|
overlappingNodes.clear();
|
||||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-8, 5, -3), Vector3(-2, 11, 3)), mOverlapCallback);
|
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-8, 5, -3), Vector3(-2, 11, 3)), overlappingNodes);
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
#ifdef IS_PROFILING_ACTIVE
|
||||||
delete profiler;
|
delete profiler;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user