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/CollisionDetection.h"
|
||||
"src/collision/ContactManifold.h"
|
||||
"src/collision/MiddlePhaseTriangleCallback.h"
|
||||
"src/constraint/BallAndSocketJoint.h"
|
||||
"src/constraint/ContactPoint.h"
|
||||
"src/constraint/FixedJoint.h"
|
||||
|
@ -213,7 +212,6 @@ SET (REACTPHYSICS3D_SOURCES
|
|||
"src/collision/HalfEdgeStructure.cpp"
|
||||
"src/collision/CollisionDetection.cpp"
|
||||
"src/collision/ContactManifold.cpp"
|
||||
"src/collision/MiddlePhaseTriangleCallback.cpp"
|
||||
"src/constraint/BallAndSocketJoint.cpp"
|
||||
"src/constraint/ContactPoint.cpp"
|
||||
"src/constraint/FixedJoint.cpp"
|
||||
|
|
|
@ -90,7 +90,7 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, con
|
|||
AABB(localBoundsMin, localBoundsMax),
|
||||
transform, collisionShape, decimal(1), 0x0001, 0xFFFF);
|
||||
bool isActive = mWorld.mCollisionBodyComponents.getIsActive(mEntity);
|
||||
mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, isActive, proxyShapeComponent);
|
||||
mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, !isActive, proxyShapeComponent);
|
||||
|
||||
mWorld.mCollisionBodyComponents.addProxyShapeToBody(mEntity, proxyShapeEntity);
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "body/RigidBody.h"
|
||||
#include "configuration.h"
|
||||
#include "collision/CollisionCallback.h"
|
||||
#include "collision/MiddlePhaseTriangleCallback.h"
|
||||
#include "collision/OverlapCallback.h"
|
||||
#include "collision/narrowphase/NarrowPhaseInfoBatch.h"
|
||||
#include "collision/ContactManifold.h"
|
||||
|
@ -289,26 +288,28 @@ void CollisionDetection::computeMiddlePhase(OverlappingPairMap& overlappingPairs
|
|||
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
|
||||
NarrowPhaseInput& narrowPhaseInput) {
|
||||
|
||||
RP3D_PROFILE("CollisionDetection::computeConvexVsConcaveMiddlePhase()", mProfiler);
|
||||
|
||||
ProxyShape* shape1 = pair->getShape1();
|
||||
ProxyShape* shape2 = pair->getShape2();
|
||||
|
||||
ProxyShape* convexProxyShape;
|
||||
ProxyShape* concaveProxyShape;
|
||||
const ConvexShape* convexShape;
|
||||
const ConcaveShape* concaveShape;
|
||||
ConvexShape* convexShape;
|
||||
ConcaveShape* concaveShape;
|
||||
|
||||
// Collision shape 1 is convex, collision shape 2 is concave
|
||||
if (shape1->getCollisionShape()->isConvex()) {
|
||||
convexProxyShape = shape1;
|
||||
convexShape = static_cast<const ConvexShape*>(shape1->getCollisionShape());
|
||||
convexShape = static_cast<ConvexShape*>(shape1->getCollisionShape());
|
||||
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
|
||||
convexProxyShape = shape2;
|
||||
convexShape = static_cast<const ConvexShape*>(shape2->getCollisionShape());
|
||||
convexShape = static_cast<ConvexShape*>(shape2->getCollisionShape());
|
||||
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
|
||||
|
@ -317,25 +318,48 @@ void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair
|
|||
|
||||
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
|
||||
const Transform convexToConcaveTransform = concaveProxyShape->getLocalToWorldTransform().getInverse() *
|
||||
convexProxyShape->getLocalToWorldTransform();
|
||||
AABB aabb;
|
||||
convexShape->computeAABB(aabb, convexToConcaveTransform);
|
||||
|
||||
// Call the convex vs triangle callback for each triangle of the concave shape
|
||||
concaveShape->testAllTriangles(middlePhaseCallback, aabb);
|
||||
// Compute the concave shape triangles that are overlapping with the convex mesh 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
|
||||
|
|
|
@ -65,21 +65,13 @@ struct ContactPointInfo {
|
|||
/// Contact point of body 2 in local space of body 2
|
||||
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 -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ContactPointInfo(const Vector3& contactNormal, decimal penDepth,
|
||||
const Vector3& localPt1, const Vector3& localPt2)
|
||||
: normal(contactNormal), penetrationDepth(penDepth),
|
||||
localPoint1(localPt1), localPoint2(localPt2), next(nullptr), isUsed(false) {
|
||||
localPoint1(localPt1), localPoint2(localPt2) {
|
||||
|
||||
assert(contactNormal.lengthSquare() > decimal(0.8));
|
||||
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.
|
||||
// TODO : Do not use this method anymore. Use
|
||||
void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, DynamicAABBTreeOverlapCallback& callback) const {
|
||||
// Report all shapes overlapping with the AABB given in parameter.
|
||||
void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const {
|
||||
|
||||
// Create a stack with the nodes to visit
|
||||
Stack<int> stack(mAllocator, 64);
|
||||
|
@ -669,7 +668,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, Dynam
|
|||
if (nodeToVisit->isLeaf()) {
|
||||
|
||||
// Notify the broad-phase about a new potential overlapping pair
|
||||
callback.notifyOverlappingNode(nodeIDToVisit);
|
||||
overlappingNodes.add(nodeIDToVisit);
|
||||
}
|
||||
else { // If the node is not a leaf
|
||||
|
||||
|
@ -682,7 +681,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, Dynam
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ class DynamicAABBTree {
|
|||
size_t endIndex, List<Pair<int, int>>& outOverlappingNodes) const;
|
||||
|
||||
/// 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
|
||||
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
|
||||
void ConcaveMeshShape::getTriangleVertices(uint subPart, uint triangleIndex,
|
||||
Vector3* outTriangleVertices) const {
|
||||
void ConcaveMeshShape::getTriangleVertices(uint subPart, uint triangleIndex, Vector3* outTriangleVertices) const {
|
||||
|
||||
// Get the triangle vertex array of the current sub-part
|
||||
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
|
||||
void ConcaveMeshShape::testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const {
|
||||
// Compute all the triangles of the mesh that are overlapping with the AABB in parameter
|
||||
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
|
||||
// with the AABB of the convex shape.
|
||||
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(localAABB, overlapCallback);
|
||||
// For each overlapping node
|
||||
for (uint i=0; i < overlappingNodes.size(); i++) {
|
||||
|
||||
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
|
||||
|
|
|
@ -155,7 +155,7 @@ class ConcaveMeshShape : public ConcaveShape {
|
|||
/// Insert all the triangles into the dynamic AABB tree
|
||||
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;
|
||||
|
||||
/// 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
|
||||
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:
|
||||
|
||||
/// Constructor
|
||||
|
@ -187,9 +192,6 @@ class ConcaveMeshShape : public ConcaveShape {
|
|||
/// Return the local inertia tensor of the collision shape
|
||||
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
|
||||
virtual std::string to_string() const override;
|
||||
|
||||
|
|
|
@ -99,7 +99,9 @@ class ConcaveShape : public CollisionShape {
|
|||
virtual bool isPolyhedron() 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=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
|
||||
|
|
|
@ -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
|
||||
// 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.
|
||||
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
|
||||
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);
|
||||
|
||||
// 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
|
||||
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
|
||||
// vertices normal at the HeightFieldShape constructor but it will require extra memory to
|
||||
// store them.
|
||||
Vector3 verticesNormals1[3] = {triangle1Normal, triangle1Normal, triangle1Normal};
|
||||
triangleVerticesNormals.add(triangle1Normal);
|
||||
triangleVerticesNormals.add(triangle1Normal);
|
||||
triangleVerticesNormals.add(triangle1Normal);
|
||||
|
||||
// Test collision against the first triangle
|
||||
callback.testTriangle(trianglePoints, verticesNormals1, computeTriangleShapeId(i, j, 0));
|
||||
// Compute the shape ID
|
||||
shapeIds.add(computeTriangleShapeId(i, j, 0));
|
||||
|
||||
// Generate the second triangle for the current grid rectangle
|
||||
trianglePoints[0] = p3;
|
||||
trianglePoints[1] = p2;
|
||||
trianglePoints[2] = p4;
|
||||
triangleVertices.add(p3);
|
||||
triangleVertices.add(p2);
|
||||
triangleVertices.add(p4);
|
||||
|
||||
// Compute the triangle normal
|
||||
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
|
||||
// vertices normal at the HeightFieldShape constructor but it will require extra memory to
|
||||
// store them.
|
||||
Vector3 verticesNormals2[3] = {triangle2Normal, triangle2Normal, triangle2Normal};
|
||||
triangleVerticesNormals.add(triangle2Normal);
|
||||
triangleVerticesNormals.add(triangle2Normal);
|
||||
triangleVerticesNormals.add(triangle2Normal);
|
||||
|
||||
// Test collision against the second triangle
|
||||
callback.testTriangle(trianglePoints, verticesNormals2, computeTriangleShapeId(i, j, 1));
|
||||
// Compute the shape ID
|
||||
shapeIds.add(computeTriangleShapeId(i, j, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,22 +229,61 @@ bool HeightFieldShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxySh
|
|||
|
||||
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
|
||||
const Vector3 rayEnd = ray.point1 + ray.maxFraction * (ray.point2 - ray.point1);
|
||||
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
|
||||
|
@ -264,42 +311,6 @@ Vector3 HeightFieldShape::getVertexAt(int x, int y) const {
|
|||
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
|
||||
std::string HeightFieldShape::to_string() const {
|
||||
|
||||
|
|
|
@ -36,57 +36,6 @@ class HeightFieldShape;
|
|||
class Profiler;
|
||||
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
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/// 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
|
||||
virtual std::string to_string() const override;
|
||||
|
|
|
@ -180,6 +180,7 @@ class TriangleShape : public ConvexPolyhedronShape {
|
|||
friend class ConcaveMeshRaycastCallback;
|
||||
friend class TriangleOverlapCallback;
|
||||
friend class MiddlePhaseTriangleCallback;
|
||||
friend class HeightFieldShape;
|
||||
};
|
||||
|
||||
// Return the number of bytes used by the collision shape
|
||||
|
|
|
@ -117,7 +117,7 @@ void BroadPhaseSystem::updateProxyShape(Entity proxyShapeEntity) {
|
|||
uint32 index = mProxyShapesComponents.mMapEntityToComponentIndex[proxyShapeEntity];
|
||||
|
||||
// Update the proxy-shape component
|
||||
updateProxyShapesComponents(index, index + 1);
|
||||
updateProxyShapesComponents(index, 1);
|
||||
}
|
||||
|
||||
// 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
|
||||
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(endIndex <= mProxyShapesComponents.getNbComponents());
|
||||
assert(startIndex + nbItems <= mProxyShapesComponents.getNbComponents());
|
||||
|
||||
// Make sure we do not update disabled components
|
||||
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
|
||||
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 (uint32 i = startIndex; i < endIndex; i++) {
|
||||
for (uint32 i = startIndex; i < startIndex + nbItems; i++) {
|
||||
|
||||
const int broadPhaseId = mProxyShapesComponents.mBroadPhaseIds[i];
|
||||
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
|
||||
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);
|
||||
|
||||
/// Update the broad-phase state of some proxy-shapes components
|
||||
void updateProxyShapesComponents(uint32 startIndex, uint32 endIndex);
|
||||
void updateProxyShapesComponents(uint32 startIndex, uint32 nbItems);
|
||||
|
||||
public :
|
||||
|
||||
|
@ -182,9 +182,6 @@ class BroadPhaseSystem {
|
|||
/// step and that need to be tested again for broad-phase overlapping.
|
||||
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
|
||||
void computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int, int>>& overlappingNodes);
|
||||
|
||||
|
|
|
@ -31,32 +31,11 @@
|
|||
#include "collision/broadphase/DynamicAABBTree.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include <vector>
|
||||
|
||||
/// Reactphysics3D namespace
|
||||
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 {
|
||||
|
||||
public:
|
||||
|
@ -78,6 +57,7 @@ class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// Class TestDynamicAABBTree
|
||||
/**
|
||||
* Unit test for the dynamic AABB tree
|
||||
|
@ -88,8 +68,8 @@ class TestDynamicAABBTree : public Test {
|
|||
|
||||
// ---------- Atributes ---------- //
|
||||
|
||||
TestOverlapCallback mOverlapCallback;
|
||||
DynamicTreeRaycastCallback mRaycastCallback;
|
||||
PoolAllocator mAllocator;
|
||||
|
||||
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
|
||||
void run() {
|
||||
|
||||
|
@ -202,45 +186,47 @@ class TestDynamicAABBTree : public Test {
|
|||
|
||||
// ---------- Tests ---------- //
|
||||
|
||||
List<int> overlappingNodes(mAllocator);
|
||||
|
||||
// AABB overlapping nothing
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping everything
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
|
||||
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 1 and 3
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
|
||||
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 3 and 4
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 2
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
||||
|
||||
|
@ -250,44 +236,44 @@ class TestDynamicAABBTree : public Test {
|
|||
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
||||
|
||||
// AABB overlapping nothing
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping everything
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
|
||||
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 1 and 3
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
|
||||
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 3 and 4
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 2
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
||||
|
||||
|
@ -297,44 +283,44 @@ class TestDynamicAABBTree : public Test {
|
|||
tree.updateObject(object4Id, aabb4, Vector3::zero());
|
||||
|
||||
// AABB overlapping nothing
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping everything
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
|
||||
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 1 and 3
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
|
||||
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 3 and 4
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping object 2
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// ---- Move objects 2 and 3 ----- //
|
||||
|
||||
|
@ -345,20 +331,20 @@ class TestDynamicAABBTree : public Test {
|
|||
tree.updateObject(object3Id, newAABB3, Vector3::zero());
|
||||
|
||||
// AABB overlapping object 3
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(6, -10, -2), Vector3(8, 5, 3)), mOverlapCallback);
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(6, -10, -2), Vector3(8, 5, 3)), overlappingNodes);
|
||||
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
// AABB overlapping objects 1, 2
|
||||
mOverlapCallback.reset();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-8, 5, -3), Vector3(-2, 11, 3)), mOverlapCallback);
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
|
||||
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
|
||||
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
|
||||
overlappingNodes.clear();
|
||||
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-8, 5, -3), Vector3(-2, 11, 3)), overlappingNodes);
|
||||
rp3d_test(isOverlapping(object1Id, overlappingNodes));
|
||||
rp3d_test(isOverlapping(object2Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
|
||||
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
delete profiler;
|
||||
|
|
Loading…
Reference in New Issue
Block a user