Fix issues, work on HalfEdgeStructure and add unit tests

This commit is contained in:
Daniel Chappuis 2017-02-20 17:11:13 +02:00
parent 7a656aedc9
commit 6a01abfae8
12 changed files with 286 additions and 68 deletions

View File

@ -463,7 +463,7 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
// Make sure the shape with the smallest collision shape type comes first
const uint shape1TypeIndex = static_cast<const uint>(shape1->getCollisionShape()->getType());
const uint shape2TypeIndex = static_cast<const uint>(shape2->getCollisionShape()->getType());
if (shape2TypeIndex > shape1TypeIndex) {
if (shape1TypeIndex > shape2TypeIndex) {
// Swap the two shapes
ProxyShape* temp = shape1;

View File

@ -179,12 +179,6 @@ class CollisionDetection {
/// Compute the collision detection
void computeCollisionDetection();
// TODO : Remove this method
/// Report collision between two sets of shapes
//void reportCollisionBetweenShapes(CollisionCallback* callback,
// const std::set<uint>& shapes1,
// const std::set<uint>& shapes2) ;
/// Ray casting method
void raycast(RaycastCallback* raycastCallback, const Ray& ray,
unsigned short raycastWithCategoryMaskBits) const;
@ -210,12 +204,6 @@ class CollisionDetection {
/// Allow the broadphase to notify the collision detection about an overlapping pair.
void broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2);
// TODO : Remove this method
/// Compute the narrow-phase collision detection
//void computeNarrowPhaseBetweenShapes(CollisionCallback* callback,
// const std::set<uint>& shapes1,
// const std::set<uint>& shapes2);
/// Return a pointer to the world
CollisionWorld* getWorld();

View File

@ -38,6 +38,8 @@ void HalfEdgeStructure::init(std::vector<Vector3> vertices, std::vector<std::vec
std::map<edgeKey, edgeKey> nextEdges;
std::map<edgeKey, uint> mapEdgeToStartVertex;
std::map<edgeKey, uint> mapEdgeToIndex;
std::map<uint, edgeKey> mapEdgeIndexToKey;
std::map<uint, edgeKey> mapFaceIndexToEdgeKey;
// For each vertices
for (uint v=0; v<vertices.size(); v++) {
@ -86,24 +88,27 @@ void HalfEdgeStructure::init(std::vector<Vector3> vertices, std::vector<std::vec
mapEdgeToStartVertex.insert(std::make_pair(pairV1V2, v1Index));
mapEdgeToStartVertex.insert(std::make_pair(pairV2V1, v2Index));
mapFaceIndexToEdgeKey.insert(std::make_pair(f, pairV1V2));
auto itEdge = edges.find(pairV2V1);
if (itEdge != edges.end()) {
const uint edgeIndex = mEdges.size();
mEdges.push_back(itEdge->second);
mEdges.push_back(edge);
itEdge->second.twinEdgeIndex = edgeIndex + 1;
edge.twinEdgeIndex = edgeIndex;
mVertices[v1Index].edgeIndex = edgeIndex;
mVertices[v2Index].edgeIndex = edgeIndex + 1;
mapEdgeIndexToKey[edgeIndex] = pairV2V1;
mapEdgeIndexToKey[edgeIndex + 1] = pairV1V2;
mVertices[v1Index].edgeIndex = edgeIndex + 1;
mVertices[v2Index].edgeIndex = edgeIndex;
mapEdgeToIndex.insert(std::make_pair(pairV1V2, edgeIndex + 1));
mapEdgeToIndex.insert(std::make_pair(pairV2V1, edgeIndex));
face.edgeIndex = edgeIndex + 1;
mEdges.push_back(itEdge->second);
mEdges.push_back(edge);
}
currentFaceEdges.push_back(pairV1V2);
@ -111,8 +116,12 @@ void HalfEdgeStructure::init(std::vector<Vector3> vertices, std::vector<std::vec
}
// Set next edges
std::map<edgeKey, Edge>::iterator it;
for (it = edges.begin(); it != edges.end(); ++it) {
it->second.nextEdgeIndex = mapEdgeToIndex[nextEdges[it->first]];
for (uint i=0; i < mEdges.size(); i++) {
mEdges[i].nextEdgeIndex = mapEdgeToIndex[nextEdges[mapEdgeIndexToKey[i]]];
}
// Set face edge
for (uint f=0; f < faces.size(); f++) {
mFaces[f].edgeIndex = mapEdgeToIndex[mapFaceIndexToEdgeKey[f]];
}
}

View File

@ -43,7 +43,7 @@ class HalfEdgeStructure {
public:
struct Edge {
uint vertexIndex; // Index of the vertex at the end of the edge
uint vertexIndex; // Index of the vertex at the beginning of the edge
uint twinEdgeIndex; // Index of the twin edge
uint faceIndex; // Adjacent face index of the edge
uint nextEdgeIndex; // Index of the next edge
@ -54,7 +54,7 @@ class HalfEdgeStructure {
};
struct Vertex {
Vector3 point; // Coordinates of the vertex
Vector3 point; // Coordinates of the vertex
uint edgeIndex; // Index of one edge emanting from this vertex
/// Constructor
@ -86,8 +86,8 @@ class HalfEdgeStructure {
/// Return the number of faces
uint getNbFaces() const;
/// Return the number of edges
uint getNbEdges() const;
/// Return the number of half-edges
uint getNbHalfEdges() const;
/// Return the number of vertices
uint getNbVertices() const;
@ -109,7 +109,7 @@ inline uint HalfEdgeStructure::getNbFaces() const {
}
// Return the number of edges
inline uint HalfEdgeStructure::getNbEdges() const {
inline uint HalfEdgeStructure::getNbHalfEdges() const {
return mEdges.size();
}

View File

@ -171,16 +171,16 @@ void reactphysics3d::computeClosestPointBetweenTwoSegments(const Vector3& seg1Po
// there is no intersection between the plane and the segment.
decimal reactphysics3d::computePlaneSegmentIntersection(const Vector3& segA, const Vector3& segB, const decimal planeD, const Vector3& planeNormal) {
const decimal parallelEpsilon = decimal(0.0001);
const decimal parallelEpsilon = decimal(0.0001);
decimal t = decimal(-1);
// Segment AB
const Vector3 ab = segB - segA;
decimal nDotAB = planeNormal.dot(ab);
decimal nDotAB = planeNormal.dot(ab);
// If the segment is not parallel to the plane
if (nDotAB > parallelEpsilon) {
if (std::abs(nDotAB) > parallelEpsilon) {
t = (planeD - planeNormal.dot(segA)) / nDotAB;
}

View File

@ -37,6 +37,7 @@
#include "tests/collision/TestCollisionWorld.h"
#include "tests/collision/TestAABB.h"
#include "tests/collision/TestDynamicAABBTree.h"
#include "tests/collision/TestHalfEdgeStructure.h"
using namespace reactphysics3d;
@ -61,6 +62,7 @@ int main() {
testSuite.addTest(new TestRaycast("Raycasting"));
testSuite.addTest(new TestCollisionWorld("CollisionWorld"));
testSuite.addTest(new TestDynamicAABBTree("DynamicAABBTree"));
testSuite.addTest(new TestHalfEdgeStructure("HalfEdgeStructure"));
// Run the tests
testSuite.run();

View File

@ -72,7 +72,7 @@ class TestAABB : public Test {
}
/// Destructor
~TestAABB() {
virtual ~TestAABB() {
}

View File

@ -103,7 +103,6 @@ class TestCollisionWorld : public Test {
CollisionBody* mBoxBody;
CollisionBody* mSphere1Body;
CollisionBody* mSphere2Body;
CollisionBody* mCylinderBody;
// Collision shapes
BoxShape* mBoxShape;
@ -113,7 +112,6 @@ class TestCollisionWorld : public Test {
ProxyShape* mBoxProxyShape;
ProxyShape* mSphere1ProxyShape;
ProxyShape* mSphere2ProxyShape;
ProxyShape* mCylinderProxyShape;
// Collision callback class
WorldCollisionCallback mCollisionCallback;
@ -147,16 +145,14 @@ class TestCollisionWorld : public Test {
mBoxProxyShape->setCollisionCategoryBits(CATEGORY_1);
mSphere1ProxyShape->setCollisionCategoryBits(CATEGORY_1);
mSphere2ProxyShape->setCollisionCategoryBits(CATEGORY_2);
mCylinderProxyShape->setCollisionCategoryBits(CATEGORY_3);
mCollisionCallback.boxBody = mBoxBody;
mCollisionCallback.sphere1Body = mSphere1Body;
mCollisionCallback.sphere2Body = mSphere2Body;
mCollisionCallback.cylinderBody = mCylinderBody;
}
/// Destructor
~TestCollisionWorld() {
virtual ~TestCollisionWorld() {
delete mBoxShape;
delete mSphereShape;
}
@ -175,17 +171,12 @@ class TestCollisionWorld : public Test {
test(!mCollisionCallback.sphere1CollideWithSphere2);
test(mWorld->testAABBOverlap(mBoxBody, mSphere1Body));
test(mWorld->testAABBOverlap(mBoxBody, mCylinderBody));
test(!mWorld->testAABBOverlap(mSphere1Body, mCylinderBody));
test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body));
test(mBoxProxyShape->testAABBOverlap(mSphere1ProxyShape->getWorldAABB()));
test(mBoxProxyShape->testAABBOverlap(mCylinderProxyShape->getWorldAABB()));
test(!mSphere1ProxyShape->testAABBOverlap(mCylinderProxyShape->getWorldAABB()));
test(!mSphere1ProxyShape->testAABBOverlap(mSphere2ProxyShape->getWorldAABB()));
mCollisionCallback.reset();
mWorld->testCollision(mCylinderBody, &mCollisionCallback);
test(!mCollisionCallback.boxCollideWithSphere1);
test(!mCollisionCallback.sphere1CollideWithSphere2);
@ -195,7 +186,6 @@ class TestCollisionWorld : public Test {
test(!mCollisionCallback.sphere1CollideWithSphere2);
mCollisionCallback.reset();
mWorld->testCollision(mBoxBody, mCylinderBody, &mCollisionCallback);
test(!mCollisionCallback.boxCollideWithSphere1);
test(!mCollisionCallback.sphere1CollideWithSphere2);
@ -213,7 +203,6 @@ class TestCollisionWorld : public Test {
test(!mCollisionCallback.sphere1CollideWithSphere2);
mCollisionCallback.reset();
mWorld->testCollision(mBoxBody, mCylinderBody, &mCollisionCallback);
test(!mCollisionCallback.boxCollideWithSphere1);
test(!mCollisionCallback.sphere1CollideWithSphere2);
@ -224,7 +213,6 @@ class TestCollisionWorld : public Test {
mCollisionCallback.reset();
mBoxBody->setIsActive(false);
mCylinderBody->setIsActive(false);
mSphere1Body->setIsActive(false);
mSphere2Body->setIsActive(false);
mWorld->testCollision(&mCollisionCallback);
@ -232,17 +220,12 @@ class TestCollisionWorld : public Test {
test(!mCollisionCallback.sphere1CollideWithSphere2);
test(!mWorld->testAABBOverlap(mBoxBody, mSphere1Body));
test(!mWorld->testAABBOverlap(mBoxBody, mCylinderBody));
test(!mWorld->testAABBOverlap(mSphere1Body, mCylinderBody));
test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body));
test(!mBoxProxyShape->testAABBOverlap(mSphere1ProxyShape->getWorldAABB()));
test(!mBoxProxyShape->testAABBOverlap(mCylinderProxyShape->getWorldAABB()));
test(!mSphere1ProxyShape->testAABBOverlap(mCylinderProxyShape->getWorldAABB()));
test(!mSphere1ProxyShape->testAABBOverlap(mSphere2ProxyShape->getWorldAABB()));
mBoxBody->setIsActive(true);
mCylinderBody->setIsActive(true);
mSphere1Body->setIsActive(true);
mSphere2Body->setIsActive(true);
@ -251,7 +234,6 @@ class TestCollisionWorld : public Test {
mBoxProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_3);
mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_2);
mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_1);
mCylinderProxyShape->setCollideWithMaskBits(CATEGORY_1);
mCollisionCallback.reset();
mWorld->testCollision(&mCollisionCallback);
@ -269,7 +251,6 @@ class TestCollisionWorld : public Test {
mBoxProxyShape->setCollideWithMaskBits(CATEGORY_2);
mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_2);
mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_3);
mCylinderProxyShape->setCollideWithMaskBits(CATEGORY_1);
mCollisionCallback.reset();
mWorld->testCollision(&mCollisionCallback);
@ -282,7 +263,6 @@ class TestCollisionWorld : public Test {
mBoxProxyShape->setCollideWithMaskBits(0xFFFF);
mSphere1ProxyShape->setCollideWithMaskBits(0xFFFF);
mSphere2ProxyShape->setCollideWithMaskBits(0xFFFF);
mCylinderProxyShape->setCollideWithMaskBits(0xFFFF);
}
};

View File

@ -0,0 +1,245 @@
#ifndef TEST_HALF_EDGE_STRUCTURE_H
#define TEST_HALF_EDGE_STRUCTURE_H
// Libraries
#include "reactphysics3d.h"
#include "Test.h"
/// Reactphysics3D namespace
namespace reactphysics3d {
// Class TestHalfEdgeStructure
/**
* Unit test for the HalfEdgeStructure class.
*/
class TestHalfEdgeStructure : public Test {
private :
// ---------- Atributes ---------- //
public :
// ---------- Methods ---------- //
/// Constructor
TestHalfEdgeStructure(const std::string& name) : Test(name) {
}
/// Destructor
virtual ~TestHalfEdgeStructure() {
}
/// Run the tests
void run() {
testCube();
testTetrahedron();
}
void testCube() {
// Create the half-edge structure for a cube
std::vector<rp3d::Vector3> vertices;
std::vector<std::vector<uint>> faces;
rp3d::HalfEdgeStructure cubeStructure;
// Vertices
vertices.push_back(rp3d::Vector3(-0.5, -0.5, 0.5));
vertices.push_back(rp3d::Vector3(0.5, -0.5, 0.5));
vertices.push_back(rp3d::Vector3(0.5, 0.5, 0.5));
vertices.push_back(rp3d::Vector3(-0.5, 0.5, 0.5));
vertices.push_back(rp3d::Vector3(-0.5, -0.5, -0.5));
vertices.push_back(rp3d::Vector3(0.5, -0.5, -0.5));
vertices.push_back(rp3d::Vector3(0.5, 0.5, -0.5));
vertices.push_back(rp3d::Vector3(-0.5, 0.5, -0.5));
// Faces
std::vector<uint> face0;
face0.push_back(0); face0.push_back(1); face0.push_back(2); face0.push_back(3);
std::vector<uint> face1;
face1.push_back(1); face1.push_back(5); face1.push_back(6); face1.push_back(2);
std::vector<uint> face2;
face2.push_back(5); face2.push_back(4); face2.push_back(7); face2.push_back(6);
std::vector<uint> face3;
face3.push_back(4); face3.push_back(0); face3.push_back(3); face3.push_back(7);
std::vector<uint> face4;
face4.push_back(0); face4.push_back(4); face4.push_back(5); face4.push_back(1);
std::vector<uint> face5;
face5.push_back(2); face5.push_back(6); face5.push_back(7); face5.push_back(3);
faces.push_back(face0);
faces.push_back(face1);
faces.push_back(face2);
faces.push_back(face3);
faces.push_back(face4);
faces.push_back(face5);
cubeStructure.init(vertices, faces);
// --- Test that the half-edge structure of the cube is valid --- //
test(cubeStructure.getNbFaces() == 6);
test(cubeStructure.getNbVertices() == 8);
test(cubeStructure.getNbHalfEdges() == 24);
// Test vertices
test(cubeStructure.getVertex(0).point.x == -0.5);
test(cubeStructure.getVertex(0).point.y == -0.5);
test(cubeStructure.getVertex(0).point.z == 0.5);
test(cubeStructure.getHalfEdge(cubeStructure.getVertex(0).edgeIndex).vertexIndex == 0);
test(cubeStructure.getVertex(1).point.x == 0.5);
test(cubeStructure.getVertex(1).point.y == -0.5);
test(cubeStructure.getVertex(1).point.z == 0.5);
test(cubeStructure.getHalfEdge(cubeStructure.getVertex(1).edgeIndex).vertexIndex == 1);
test(cubeStructure.getVertex(2).point.x == 0.5);
test(cubeStructure.getVertex(2).point.y == 0.5);
test(cubeStructure.getVertex(2).point.z == 0.5);
test(cubeStructure.getHalfEdge(cubeStructure.getVertex(2).edgeIndex).vertexIndex == 2);
test(cubeStructure.getVertex(3).point.x == -0.5);
test(cubeStructure.getVertex(3).point.y == 0.5);
test(cubeStructure.getVertex(3).point.z == 0.5);
test(cubeStructure.getHalfEdge(cubeStructure.getVertex(3).edgeIndex).vertexIndex == 3);
test(cubeStructure.getVertex(4).point.x == -0.5);
test(cubeStructure.getVertex(4).point.y == -0.5);
test(cubeStructure.getVertex(4).point.z == -0.5);
test(cubeStructure.getHalfEdge(cubeStructure.getVertex(4).edgeIndex).vertexIndex == 4);
test(cubeStructure.getVertex(5).point.x == 0.5);
test(cubeStructure.getVertex(5).point.y == -0.5);
test(cubeStructure.getVertex(5).point.z == -0.5);
test(cubeStructure.getHalfEdge(cubeStructure.getVertex(5).edgeIndex).vertexIndex == 5);
test(cubeStructure.getVertex(6).point.x == 0.5);
test(cubeStructure.getVertex(6).point.y == 0.5);
test(cubeStructure.getVertex(6).point.z == -0.5);
test(cubeStructure.getHalfEdge(cubeStructure.getVertex(6).edgeIndex).vertexIndex == 6);
test(cubeStructure.getVertex(7).point.x == -0.5);
test(cubeStructure.getVertex(7).point.y == 0.5);
test(cubeStructure.getVertex(7).point.z == -0.5);
test(cubeStructure.getHalfEdge(cubeStructure.getVertex(7).edgeIndex).vertexIndex == 7);
// Test faces
for (uint f=0; f<6; f++) {
test(cubeStructure.getHalfEdge(cubeStructure.getFace(f).edgeIndex).faceIndex == f);
}
// Test edges
for (uint f=0; f<6; f++) {
uint edgeIndex = cubeStructure.getFace(f).edgeIndex;
const uint firstEdgeIndex = edgeIndex;
// For each half-edge of the face
for (uint e=0; e<4; e++) {
rp3d::HalfEdgeStructure::Edge edge = cubeStructure.getHalfEdge(edgeIndex);
test(cubeStructure.getHalfEdge(edge.twinEdgeIndex).twinEdgeIndex == edgeIndex);
test(edge.faceIndex == f);
// Go to the next edge
edgeIndex = edge.nextEdgeIndex;
}
test(firstEdgeIndex == edgeIndex);
}
}
void testTetrahedron() {
// Create the half-edge structure for a tetrahedron
std::vector<rp3d::Vector3> vertices;
std::vector<std::vector<uint>> faces;
rp3d::HalfEdgeStructure tetrahedron;
// Vertices
vertices.push_back(rp3d::Vector3(1, -1, -1));
vertices.push_back(rp3d::Vector3(-1, -1, -1));
vertices.push_back(rp3d::Vector3(0, -1, 1));
vertices.push_back(rp3d::Vector3(0, 1, 0));
// Faces
std::vector<uint> face0;
face0.push_back(0); face0.push_back(1); face0.push_back(2);
std::vector<uint> face1;
face1.push_back(0); face1.push_back(3); face1.push_back(1);
std::vector<uint> face2;
face2.push_back(1); face2.push_back(3); face2.push_back(2);
std::vector<uint> face3;
face3.push_back(0); face3.push_back(2); face3.push_back(3);
faces.push_back(face0);
faces.push_back(face1);
faces.push_back(face2);
faces.push_back(face3);
tetrahedron.init(vertices, faces);
// --- Test that the half-edge structure of the tetrahedron is valid --- //
test(tetrahedron.getNbFaces() == 4);
test(tetrahedron.getNbVertices() == 4);
test(tetrahedron.getNbHalfEdges() == 12);
// Test vertices
test(tetrahedron.getVertex(0).point.x == 1);
test(tetrahedron.getVertex(0).point.y == -1);
test(tetrahedron.getVertex(0).point.z == -1);
test(tetrahedron.getHalfEdge(tetrahedron.getVertex(0).edgeIndex).vertexIndex == 0);
test(tetrahedron.getVertex(1).point.x == -1);
test(tetrahedron.getVertex(1).point.y == -1);
test(tetrahedron.getVertex(1).point.z == -1);
test(tetrahedron.getHalfEdge(tetrahedron.getVertex(1).edgeIndex).vertexIndex == 1);
test(tetrahedron.getVertex(2).point.x == 0);
test(tetrahedron.getVertex(2).point.y == -1);
test(tetrahedron.getVertex(2).point.z == 1);
test(tetrahedron.getHalfEdge(tetrahedron.getVertex(2).edgeIndex).vertexIndex == 2);
test(tetrahedron.getVertex(3).point.x == 0);
test(tetrahedron.getVertex(3).point.y == 1);
test(tetrahedron.getVertex(3).point.z == 0);
test(tetrahedron.getHalfEdge(tetrahedron.getVertex(3).edgeIndex).vertexIndex == 3);
// Test faces
for (uint f=0; f<4; f++) {
test(tetrahedron.getHalfEdge(tetrahedron.getFace(f).edgeIndex).faceIndex == f);
}
// Test edges
for (uint f=0; f<4; f++) {
uint edgeIndex = tetrahedron.getFace(f).edgeIndex;
const uint firstEdgeIndex = edgeIndex;
// For each half-edge of the face
for (uint e=0; e<3; e++) {
rp3d::HalfEdgeStructure::Edge edge = tetrahedron.getHalfEdge(edgeIndex);
test(tetrahedron.getHalfEdge(edge.twinEdgeIndex).twinEdgeIndex == edgeIndex);
test(edge.faceIndex == f);
// Go to the next edge
edgeIndex = edge.nextEdgeIndex;
}
test(firstEdgeIndex == edgeIndex);
}
}
};
}
#endif

View File

@ -171,7 +171,7 @@ class TestPointInside : public Test {
}
/// Destructor
~TestPointInside() {
virtual ~TestPointInside() {
delete mBoxShape;
delete mSphereShape;
delete mCapsuleShape;

View File

@ -109,7 +109,6 @@ class TestRaycast : public Test {
CollisionBody* mBoxBody;
CollisionBody* mSphereBody;
CollisionBody* mCapsuleBody;
CollisionBody* mConeBody;
CollisionBody* mConvexMeshBody;
CollisionBody* mConvexMeshBodyEdgesInfo;
CollisionBody* mCylinderBody;
@ -138,12 +137,10 @@ class TestRaycast : public Test {
ProxyShape* mBoxProxyShape;
ProxyShape* mSphereProxyShape;
ProxyShape* mCapsuleProxyShape;
ProxyShape* mConeProxyShape;
ProxyShape* mConvexMeshProxyShape;
ProxyShape* mConvexMeshProxyShapeEdgesInfo;
ProxyShape* mCylinderProxyShape;
ProxyShape* mCompoundSphereProxyShape;
ProxyShape* mCompoundCylinderProxyShape;
ProxyShape* mCompoundCapsuleProxyShape;
ProxyShape* mTriangleProxyShape;
ProxyShape* mConcaveMeshProxyShape;
ProxyShape* mHeightFieldProxyShape;
@ -177,7 +174,6 @@ class TestRaycast : public Test {
mBoxBody = mWorld->createCollisionBody(mBodyTransform);
mSphereBody = mWorld->createCollisionBody(mBodyTransform);
mCapsuleBody = mWorld->createCollisionBody(mBodyTransform);
mConeBody = mWorld->createCollisionBody(mBodyTransform);
mConvexMeshBody = mWorld->createCollisionBody(mBodyTransform);
mConvexMeshBodyEdgesInfo = mWorld->createCollisionBody(mBodyTransform);
mCylinderBody = mWorld->createCollisionBody(mBodyTransform);
@ -253,7 +249,7 @@ class TestRaycast : public Test {
Quaternion orientationShape2(-3 *PI / 8, 1.5 * PI/ 3, PI / 13);
Transform shapeTransform2(positionShape2, orientationShape2);
mLocalShape2ToWorld = mBodyTransform * shapeTransform2;
mCompoundCylinderProxyShape = mCompoundBody->addCollisionShape(mCapsuleShape, mShapeTransform);
mCompoundCapsuleProxyShape = mCompoundBody->addCollisionShape(mCapsuleShape, mShapeTransform);
mCompoundSphereProxyShape = mCompoundBody->addCollisionShape(mSphereShape, shapeTransform2);
// Concave Mesh shape
@ -284,7 +280,7 @@ class TestRaycast : public Test {
new TriangleVertexArray(8, &(mConcaveMeshVertices[0]), sizeof(Vector3),
12, &(mConcaveMeshIndices[0]), sizeof(uint),
vertexType,
TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
// Add the triangle vertex array of the subpart to the triangle mesh
@ -302,19 +298,17 @@ class TestRaycast : public Test {
mBoxProxyShape->setCollisionCategoryBits(CATEGORY1);
mSphereProxyShape->setCollisionCategoryBits(CATEGORY1);
mCapsuleProxyShape->setCollisionCategoryBits(CATEGORY1);
mConeProxyShape->setCollisionCategoryBits(CATEGORY2);
mConvexMeshProxyShape->setCollisionCategoryBits(CATEGORY2);
mConvexMeshProxyShapeEdgesInfo->setCollisionCategoryBits(CATEGORY2);
mCylinderProxyShape->setCollisionCategoryBits(CATEGORY2);
mCompoundSphereProxyShape->setCollisionCategoryBits(CATEGORY2);
mCompoundCylinderProxyShape->setCollisionCategoryBits(CATEGORY2);
mCompoundCapsuleProxyShape->setCollisionCategoryBits(CATEGORY2);
mTriangleProxyShape->setCollisionCategoryBits(CATEGORY1);
mConcaveMeshProxyShape->setCollisionCategoryBits(CATEGORY2);
mHeightFieldProxyShape->setCollisionCategoryBits(CATEGORY2);
}
/// Destructor
~TestRaycast() {
virtual ~TestRaycast() {
delete mBoxShape;
delete mSphereShape;
delete mCapsuleShape;
@ -1647,7 +1641,7 @@ class TestRaycast : public Test {
Ray ray15(mLocalShapeToWorld * Vector3(0, -9, 1), mLocalShapeToWorld * Vector3(0, 30, 1));
Ray ray16(mLocalShapeToWorld * Vector3(-1, 2, -7), mLocalShapeToWorld * Vector3(-1, 2, 30));
mCallback.shapeToTest = mCompoundCylinderProxyShape;
mCallback.shapeToTest = mCompoundCapsuleProxyShape;
test(mCompoundBody->raycast(ray11, raycastInfo));
mCallback.reset();

View File

@ -150,19 +150,19 @@ class TestMathematicsFunctions : public Test {
test(approxEqual(closestSeg2.z, 0.0, 0.000001));
computeClosestPointBetweenTwoSegments(Vector3(1, -4, -5), Vector3(1, 4, -5), Vector3(-6, 5, -5), Vector3(6, 5, -5), closestSeg1, closestSeg2);
test(approxEqual(closestSeg1.x, 1.0, 0.000001));
test(approxEqual(closestSeg1.y, 5.0, 0.000001));
test(approxEqual(closestSeg1.y, 4.0, 0.000001));
test(approxEqual(closestSeg1.z, -5.0, 0.000001));
test(approxEqual(closestSeg2.x, 1.0, 0.000001));
test(approxEqual(closestSeg2.y, 5.0, 0.000001));
test(approxEqual(closestSeg2.z, -5.0, 0.000001));
// Test computePlaneSegmentIntersection();
test(approxEqual(computePlaneSegmentIntersection(Vector3(-6, 3, 0), Vector3(6, 3, 0), 0.0, Vector3(-1, 0, 0)), 0.5, 0.000001));
test(approxEqual(computePlaneSegmentIntersection(Vector3(-6, 3, 0), Vector3(6, 3, 0), 0.0, Vector3(-1, 0, 0)), 0.5, 0.000001));
test(approxEqual(computePlaneSegmentIntersection(Vector3(-6, 3, 0), Vector3(6, 3, 0), 0.0, Vector3(1, 0, 0)), 0.5, 0.000001));
test(approxEqual(computePlaneSegmentIntersection(Vector3(5, 12, 0), Vector3(5, 4, 0), 6, Vector3(0, 1, 0)), 0.75, 0.000001));
test(approxEqual(computePlaneSegmentIntersection(Vector3(5, 4, 8), Vector3(9, 14, 8), 4, Vector3(0, 1, 0)), 0.0, 0.000001));
decimal tIntersect = computePlaneSegmentIntersection(Vector3(5, 4, 0), Vector3(9, 4, 0), 4, Vector3(0, 1, 0));
test(tIntersect < 0.0 && tIntersect > 1.0);
test(tIntersect < 0.0 || tIntersect > 1.0);
// Test computeDistancePointToLineDistance()
test(approxEqual(computeDistancePointToLineDistance(Vector3(6, 0, 0), Vector3(14, 0, 0), Vector3(5, 3, 0)), 3.0, 0.000001));