Fix issues, work on HalfEdgeStructure and add unit tests
This commit is contained in:
parent
7a656aedc9
commit
6a01abfae8
|
@ -463,7 +463,7 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
|
||||||
// Make sure the shape with the smallest collision shape type comes first
|
// Make sure the shape with the smallest collision shape type comes first
|
||||||
const uint shape1TypeIndex = static_cast<const uint>(shape1->getCollisionShape()->getType());
|
const uint shape1TypeIndex = static_cast<const uint>(shape1->getCollisionShape()->getType());
|
||||||
const uint shape2TypeIndex = static_cast<const uint>(shape2->getCollisionShape()->getType());
|
const uint shape2TypeIndex = static_cast<const uint>(shape2->getCollisionShape()->getType());
|
||||||
if (shape2TypeIndex > shape1TypeIndex) {
|
if (shape1TypeIndex > shape2TypeIndex) {
|
||||||
|
|
||||||
// Swap the two shapes
|
// Swap the two shapes
|
||||||
ProxyShape* temp = shape1;
|
ProxyShape* temp = shape1;
|
||||||
|
|
|
@ -179,12 +179,6 @@ class CollisionDetection {
|
||||||
/// Compute the collision detection
|
/// Compute the collision detection
|
||||||
void computeCollisionDetection();
|
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
|
/// Ray casting method
|
||||||
void raycast(RaycastCallback* raycastCallback, const Ray& ray,
|
void raycast(RaycastCallback* raycastCallback, const Ray& ray,
|
||||||
unsigned short raycastWithCategoryMaskBits) const;
|
unsigned short raycastWithCategoryMaskBits) const;
|
||||||
|
@ -210,12 +204,6 @@ class CollisionDetection {
|
||||||
/// Allow the broadphase to notify the collision detection about an overlapping pair.
|
/// Allow the broadphase to notify the collision detection about an overlapping pair.
|
||||||
void broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2);
|
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
|
/// Return a pointer to the world
|
||||||
CollisionWorld* getWorld();
|
CollisionWorld* getWorld();
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ void HalfEdgeStructure::init(std::vector<Vector3> vertices, std::vector<std::vec
|
||||||
std::map<edgeKey, edgeKey> nextEdges;
|
std::map<edgeKey, edgeKey> nextEdges;
|
||||||
std::map<edgeKey, uint> mapEdgeToStartVertex;
|
std::map<edgeKey, uint> mapEdgeToStartVertex;
|
||||||
std::map<edgeKey, uint> mapEdgeToIndex;
|
std::map<edgeKey, uint> mapEdgeToIndex;
|
||||||
|
std::map<uint, edgeKey> mapEdgeIndexToKey;
|
||||||
|
std::map<uint, edgeKey> mapFaceIndexToEdgeKey;
|
||||||
|
|
||||||
// For each vertices
|
// For each vertices
|
||||||
for (uint v=0; v<vertices.size(); v++) {
|
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(pairV1V2, v1Index));
|
||||||
mapEdgeToStartVertex.insert(std::make_pair(pairV2V1, v2Index));
|
mapEdgeToStartVertex.insert(std::make_pair(pairV2V1, v2Index));
|
||||||
|
|
||||||
|
mapFaceIndexToEdgeKey.insert(std::make_pair(f, pairV1V2));
|
||||||
|
|
||||||
auto itEdge = edges.find(pairV2V1);
|
auto itEdge = edges.find(pairV2V1);
|
||||||
if (itEdge != edges.end()) {
|
if (itEdge != edges.end()) {
|
||||||
|
|
||||||
const uint edgeIndex = mEdges.size();
|
const uint edgeIndex = mEdges.size();
|
||||||
mEdges.push_back(itEdge->second);
|
|
||||||
mEdges.push_back(edge);
|
|
||||||
|
|
||||||
itEdge->second.twinEdgeIndex = edgeIndex + 1;
|
itEdge->second.twinEdgeIndex = edgeIndex + 1;
|
||||||
|
|
||||||
edge.twinEdgeIndex = edgeIndex;
|
edge.twinEdgeIndex = edgeIndex;
|
||||||
|
|
||||||
mVertices[v1Index].edgeIndex = edgeIndex;
|
mapEdgeIndexToKey[edgeIndex] = pairV2V1;
|
||||||
mVertices[v2Index].edgeIndex = edgeIndex + 1;
|
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(pairV1V2, edgeIndex + 1));
|
||||||
mapEdgeToIndex.insert(std::make_pair(pairV2V1, edgeIndex));
|
mapEdgeToIndex.insert(std::make_pair(pairV2V1, edgeIndex));
|
||||||
|
|
||||||
face.edgeIndex = edgeIndex + 1;
|
mEdges.push_back(itEdge->second);
|
||||||
|
mEdges.push_back(edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentFaceEdges.push_back(pairV1V2);
|
currentFaceEdges.push_back(pairV1V2);
|
||||||
|
@ -111,8 +116,12 @@ void HalfEdgeStructure::init(std::vector<Vector3> vertices, std::vector<std::vec
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set next edges
|
// Set next edges
|
||||||
std::map<edgeKey, Edge>::iterator it;
|
for (uint i=0; i < mEdges.size(); i++) {
|
||||||
for (it = edges.begin(); it != edges.end(); ++it) {
|
mEdges[i].nextEdgeIndex = mapEdgeToIndex[nextEdges[mapEdgeIndexToKey[i]]];
|
||||||
it->second.nextEdgeIndex = mapEdgeToIndex[nextEdges[it->first]];
|
}
|
||||||
|
|
||||||
|
// Set face edge
|
||||||
|
for (uint f=0; f < faces.size(); f++) {
|
||||||
|
mFaces[f].edgeIndex = mapEdgeToIndex[mapFaceIndexToEdgeKey[f]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ class HalfEdgeStructure {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Edge {
|
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 twinEdgeIndex; // Index of the twin edge
|
||||||
uint faceIndex; // Adjacent face index of the edge
|
uint faceIndex; // Adjacent face index of the edge
|
||||||
uint nextEdgeIndex; // Index of the next edge
|
uint nextEdgeIndex; // Index of the next edge
|
||||||
|
@ -86,8 +86,8 @@ class HalfEdgeStructure {
|
||||||
/// Return the number of faces
|
/// Return the number of faces
|
||||||
uint getNbFaces() const;
|
uint getNbFaces() const;
|
||||||
|
|
||||||
/// Return the number of edges
|
/// Return the number of half-edges
|
||||||
uint getNbEdges() const;
|
uint getNbHalfEdges() const;
|
||||||
|
|
||||||
/// Return the number of vertices
|
/// Return the number of vertices
|
||||||
uint getNbVertices() const;
|
uint getNbVertices() const;
|
||||||
|
@ -109,7 +109,7 @@ inline uint HalfEdgeStructure::getNbFaces() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the number of edges
|
// Return the number of edges
|
||||||
inline uint HalfEdgeStructure::getNbEdges() const {
|
inline uint HalfEdgeStructure::getNbHalfEdges() const {
|
||||||
return mEdges.size();
|
return mEdges.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ decimal reactphysics3d::computePlaneSegmentIntersection(const Vector3& segA, con
|
||||||
decimal nDotAB = planeNormal.dot(ab);
|
decimal nDotAB = planeNormal.dot(ab);
|
||||||
|
|
||||||
// If the segment is not parallel to the plane
|
// If the segment is not parallel to the plane
|
||||||
if (nDotAB > parallelEpsilon) {
|
if (std::abs(nDotAB) > parallelEpsilon) {
|
||||||
t = (planeD - planeNormal.dot(segA)) / nDotAB;
|
t = (planeD - planeNormal.dot(segA)) / nDotAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "tests/collision/TestCollisionWorld.h"
|
#include "tests/collision/TestCollisionWorld.h"
|
||||||
#include "tests/collision/TestAABB.h"
|
#include "tests/collision/TestAABB.h"
|
||||||
#include "tests/collision/TestDynamicAABBTree.h"
|
#include "tests/collision/TestDynamicAABBTree.h"
|
||||||
|
#include "tests/collision/TestHalfEdgeStructure.h"
|
||||||
|
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ int main() {
|
||||||
testSuite.addTest(new TestRaycast("Raycasting"));
|
testSuite.addTest(new TestRaycast("Raycasting"));
|
||||||
testSuite.addTest(new TestCollisionWorld("CollisionWorld"));
|
testSuite.addTest(new TestCollisionWorld("CollisionWorld"));
|
||||||
testSuite.addTest(new TestDynamicAABBTree("DynamicAABBTree"));
|
testSuite.addTest(new TestDynamicAABBTree("DynamicAABBTree"));
|
||||||
|
testSuite.addTest(new TestHalfEdgeStructure("HalfEdgeStructure"));
|
||||||
|
|
||||||
// Run the tests
|
// Run the tests
|
||||||
testSuite.run();
|
testSuite.run();
|
||||||
|
|
|
@ -72,7 +72,7 @@ class TestAABB : public Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~TestAABB() {
|
virtual ~TestAABB() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,6 @@ class TestCollisionWorld : public Test {
|
||||||
CollisionBody* mBoxBody;
|
CollisionBody* mBoxBody;
|
||||||
CollisionBody* mSphere1Body;
|
CollisionBody* mSphere1Body;
|
||||||
CollisionBody* mSphere2Body;
|
CollisionBody* mSphere2Body;
|
||||||
CollisionBody* mCylinderBody;
|
|
||||||
|
|
||||||
// Collision shapes
|
// Collision shapes
|
||||||
BoxShape* mBoxShape;
|
BoxShape* mBoxShape;
|
||||||
|
@ -113,7 +112,6 @@ class TestCollisionWorld : public Test {
|
||||||
ProxyShape* mBoxProxyShape;
|
ProxyShape* mBoxProxyShape;
|
||||||
ProxyShape* mSphere1ProxyShape;
|
ProxyShape* mSphere1ProxyShape;
|
||||||
ProxyShape* mSphere2ProxyShape;
|
ProxyShape* mSphere2ProxyShape;
|
||||||
ProxyShape* mCylinderProxyShape;
|
|
||||||
|
|
||||||
// Collision callback class
|
// Collision callback class
|
||||||
WorldCollisionCallback mCollisionCallback;
|
WorldCollisionCallback mCollisionCallback;
|
||||||
|
@ -147,16 +145,14 @@ class TestCollisionWorld : public Test {
|
||||||
mBoxProxyShape->setCollisionCategoryBits(CATEGORY_1);
|
mBoxProxyShape->setCollisionCategoryBits(CATEGORY_1);
|
||||||
mSphere1ProxyShape->setCollisionCategoryBits(CATEGORY_1);
|
mSphere1ProxyShape->setCollisionCategoryBits(CATEGORY_1);
|
||||||
mSphere2ProxyShape->setCollisionCategoryBits(CATEGORY_2);
|
mSphere2ProxyShape->setCollisionCategoryBits(CATEGORY_2);
|
||||||
mCylinderProxyShape->setCollisionCategoryBits(CATEGORY_3);
|
|
||||||
|
|
||||||
mCollisionCallback.boxBody = mBoxBody;
|
mCollisionCallback.boxBody = mBoxBody;
|
||||||
mCollisionCallback.sphere1Body = mSphere1Body;
|
mCollisionCallback.sphere1Body = mSphere1Body;
|
||||||
mCollisionCallback.sphere2Body = mSphere2Body;
|
mCollisionCallback.sphere2Body = mSphere2Body;
|
||||||
mCollisionCallback.cylinderBody = mCylinderBody;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~TestCollisionWorld() {
|
virtual ~TestCollisionWorld() {
|
||||||
delete mBoxShape;
|
delete mBoxShape;
|
||||||
delete mSphereShape;
|
delete mSphereShape;
|
||||||
}
|
}
|
||||||
|
@ -175,17 +171,12 @@ class TestCollisionWorld : public Test {
|
||||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||||
|
|
||||||
test(mWorld->testAABBOverlap(mBoxBody, mSphere1Body));
|
test(mWorld->testAABBOverlap(mBoxBody, mSphere1Body));
|
||||||
test(mWorld->testAABBOverlap(mBoxBody, mCylinderBody));
|
|
||||||
test(!mWorld->testAABBOverlap(mSphere1Body, mCylinderBody));
|
|
||||||
test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body));
|
test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body));
|
||||||
|
|
||||||
test(mBoxProxyShape->testAABBOverlap(mSphere1ProxyShape->getWorldAABB()));
|
test(mBoxProxyShape->testAABBOverlap(mSphere1ProxyShape->getWorldAABB()));
|
||||||
test(mBoxProxyShape->testAABBOverlap(mCylinderProxyShape->getWorldAABB()));
|
|
||||||
test(!mSphere1ProxyShape->testAABBOverlap(mCylinderProxyShape->getWorldAABB()));
|
|
||||||
test(!mSphere1ProxyShape->testAABBOverlap(mSphere2ProxyShape->getWorldAABB()));
|
test(!mSphere1ProxyShape->testAABBOverlap(mSphere2ProxyShape->getWorldAABB()));
|
||||||
|
|
||||||
mCollisionCallback.reset();
|
mCollisionCallback.reset();
|
||||||
mWorld->testCollision(mCylinderBody, &mCollisionCallback);
|
|
||||||
test(!mCollisionCallback.boxCollideWithSphere1);
|
test(!mCollisionCallback.boxCollideWithSphere1);
|
||||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||||
|
|
||||||
|
@ -195,7 +186,6 @@ class TestCollisionWorld : public Test {
|
||||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||||
|
|
||||||
mCollisionCallback.reset();
|
mCollisionCallback.reset();
|
||||||
mWorld->testCollision(mBoxBody, mCylinderBody, &mCollisionCallback);
|
|
||||||
test(!mCollisionCallback.boxCollideWithSphere1);
|
test(!mCollisionCallback.boxCollideWithSphere1);
|
||||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||||
|
|
||||||
|
@ -213,7 +203,6 @@ class TestCollisionWorld : public Test {
|
||||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||||
|
|
||||||
mCollisionCallback.reset();
|
mCollisionCallback.reset();
|
||||||
mWorld->testCollision(mBoxBody, mCylinderBody, &mCollisionCallback);
|
|
||||||
test(!mCollisionCallback.boxCollideWithSphere1);
|
test(!mCollisionCallback.boxCollideWithSphere1);
|
||||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||||
|
|
||||||
|
@ -224,7 +213,6 @@ class TestCollisionWorld : public Test {
|
||||||
|
|
||||||
mCollisionCallback.reset();
|
mCollisionCallback.reset();
|
||||||
mBoxBody->setIsActive(false);
|
mBoxBody->setIsActive(false);
|
||||||
mCylinderBody->setIsActive(false);
|
|
||||||
mSphere1Body->setIsActive(false);
|
mSphere1Body->setIsActive(false);
|
||||||
mSphere2Body->setIsActive(false);
|
mSphere2Body->setIsActive(false);
|
||||||
mWorld->testCollision(&mCollisionCallback);
|
mWorld->testCollision(&mCollisionCallback);
|
||||||
|
@ -232,17 +220,12 @@ class TestCollisionWorld : public Test {
|
||||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||||
|
|
||||||
test(!mWorld->testAABBOverlap(mBoxBody, mSphere1Body));
|
test(!mWorld->testAABBOverlap(mBoxBody, mSphere1Body));
|
||||||
test(!mWorld->testAABBOverlap(mBoxBody, mCylinderBody));
|
|
||||||
test(!mWorld->testAABBOverlap(mSphere1Body, mCylinderBody));
|
|
||||||
test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body));
|
test(!mWorld->testAABBOverlap(mSphere1Body, mSphere2Body));
|
||||||
|
|
||||||
test(!mBoxProxyShape->testAABBOverlap(mSphere1ProxyShape->getWorldAABB()));
|
test(!mBoxProxyShape->testAABBOverlap(mSphere1ProxyShape->getWorldAABB()));
|
||||||
test(!mBoxProxyShape->testAABBOverlap(mCylinderProxyShape->getWorldAABB()));
|
|
||||||
test(!mSphere1ProxyShape->testAABBOverlap(mCylinderProxyShape->getWorldAABB()));
|
|
||||||
test(!mSphere1ProxyShape->testAABBOverlap(mSphere2ProxyShape->getWorldAABB()));
|
test(!mSphere1ProxyShape->testAABBOverlap(mSphere2ProxyShape->getWorldAABB()));
|
||||||
|
|
||||||
mBoxBody->setIsActive(true);
|
mBoxBody->setIsActive(true);
|
||||||
mCylinderBody->setIsActive(true);
|
|
||||||
mSphere1Body->setIsActive(true);
|
mSphere1Body->setIsActive(true);
|
||||||
mSphere2Body->setIsActive(true);
|
mSphere2Body->setIsActive(true);
|
||||||
|
|
||||||
|
@ -251,7 +234,6 @@ class TestCollisionWorld : public Test {
|
||||||
mBoxProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_3);
|
mBoxProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_3);
|
||||||
mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_2);
|
mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_2);
|
||||||
mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_1);
|
mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_1);
|
||||||
mCylinderProxyShape->setCollideWithMaskBits(CATEGORY_1);
|
|
||||||
|
|
||||||
mCollisionCallback.reset();
|
mCollisionCallback.reset();
|
||||||
mWorld->testCollision(&mCollisionCallback);
|
mWorld->testCollision(&mCollisionCallback);
|
||||||
|
@ -269,7 +251,6 @@ class TestCollisionWorld : public Test {
|
||||||
mBoxProxyShape->setCollideWithMaskBits(CATEGORY_2);
|
mBoxProxyShape->setCollideWithMaskBits(CATEGORY_2);
|
||||||
mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_2);
|
mSphere1ProxyShape->setCollideWithMaskBits(CATEGORY_2);
|
||||||
mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_3);
|
mSphere2ProxyShape->setCollideWithMaskBits(CATEGORY_3);
|
||||||
mCylinderProxyShape->setCollideWithMaskBits(CATEGORY_1);
|
|
||||||
|
|
||||||
mCollisionCallback.reset();
|
mCollisionCallback.reset();
|
||||||
mWorld->testCollision(&mCollisionCallback);
|
mWorld->testCollision(&mCollisionCallback);
|
||||||
|
@ -282,7 +263,6 @@ class TestCollisionWorld : public Test {
|
||||||
mBoxProxyShape->setCollideWithMaskBits(0xFFFF);
|
mBoxProxyShape->setCollideWithMaskBits(0xFFFF);
|
||||||
mSphere1ProxyShape->setCollideWithMaskBits(0xFFFF);
|
mSphere1ProxyShape->setCollideWithMaskBits(0xFFFF);
|
||||||
mSphere2ProxyShape->setCollideWithMaskBits(0xFFFF);
|
mSphere2ProxyShape->setCollideWithMaskBits(0xFFFF);
|
||||||
mCylinderProxyShape->setCollideWithMaskBits(0xFFFF);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
245
test/tests/collision/TestHalfEdgeStructure.h
Normal file
245
test/tests/collision/TestHalfEdgeStructure.h
Normal 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
|
|
@ -171,7 +171,7 @@ class TestPointInside : public Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~TestPointInside() {
|
virtual ~TestPointInside() {
|
||||||
delete mBoxShape;
|
delete mBoxShape;
|
||||||
delete mSphereShape;
|
delete mSphereShape;
|
||||||
delete mCapsuleShape;
|
delete mCapsuleShape;
|
||||||
|
|
|
@ -109,7 +109,6 @@ class TestRaycast : public Test {
|
||||||
CollisionBody* mBoxBody;
|
CollisionBody* mBoxBody;
|
||||||
CollisionBody* mSphereBody;
|
CollisionBody* mSphereBody;
|
||||||
CollisionBody* mCapsuleBody;
|
CollisionBody* mCapsuleBody;
|
||||||
CollisionBody* mConeBody;
|
|
||||||
CollisionBody* mConvexMeshBody;
|
CollisionBody* mConvexMeshBody;
|
||||||
CollisionBody* mConvexMeshBodyEdgesInfo;
|
CollisionBody* mConvexMeshBodyEdgesInfo;
|
||||||
CollisionBody* mCylinderBody;
|
CollisionBody* mCylinderBody;
|
||||||
|
@ -138,12 +137,10 @@ class TestRaycast : public Test {
|
||||||
ProxyShape* mBoxProxyShape;
|
ProxyShape* mBoxProxyShape;
|
||||||
ProxyShape* mSphereProxyShape;
|
ProxyShape* mSphereProxyShape;
|
||||||
ProxyShape* mCapsuleProxyShape;
|
ProxyShape* mCapsuleProxyShape;
|
||||||
ProxyShape* mConeProxyShape;
|
|
||||||
ProxyShape* mConvexMeshProxyShape;
|
ProxyShape* mConvexMeshProxyShape;
|
||||||
ProxyShape* mConvexMeshProxyShapeEdgesInfo;
|
ProxyShape* mConvexMeshProxyShapeEdgesInfo;
|
||||||
ProxyShape* mCylinderProxyShape;
|
|
||||||
ProxyShape* mCompoundSphereProxyShape;
|
ProxyShape* mCompoundSphereProxyShape;
|
||||||
ProxyShape* mCompoundCylinderProxyShape;
|
ProxyShape* mCompoundCapsuleProxyShape;
|
||||||
ProxyShape* mTriangleProxyShape;
|
ProxyShape* mTriangleProxyShape;
|
||||||
ProxyShape* mConcaveMeshProxyShape;
|
ProxyShape* mConcaveMeshProxyShape;
|
||||||
ProxyShape* mHeightFieldProxyShape;
|
ProxyShape* mHeightFieldProxyShape;
|
||||||
|
@ -177,7 +174,6 @@ class TestRaycast : public Test {
|
||||||
mBoxBody = mWorld->createCollisionBody(mBodyTransform);
|
mBoxBody = mWorld->createCollisionBody(mBodyTransform);
|
||||||
mSphereBody = mWorld->createCollisionBody(mBodyTransform);
|
mSphereBody = mWorld->createCollisionBody(mBodyTransform);
|
||||||
mCapsuleBody = mWorld->createCollisionBody(mBodyTransform);
|
mCapsuleBody = mWorld->createCollisionBody(mBodyTransform);
|
||||||
mConeBody = mWorld->createCollisionBody(mBodyTransform);
|
|
||||||
mConvexMeshBody = mWorld->createCollisionBody(mBodyTransform);
|
mConvexMeshBody = mWorld->createCollisionBody(mBodyTransform);
|
||||||
mConvexMeshBodyEdgesInfo = mWorld->createCollisionBody(mBodyTransform);
|
mConvexMeshBodyEdgesInfo = mWorld->createCollisionBody(mBodyTransform);
|
||||||
mCylinderBody = 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);
|
Quaternion orientationShape2(-3 *PI / 8, 1.5 * PI/ 3, PI / 13);
|
||||||
Transform shapeTransform2(positionShape2, orientationShape2);
|
Transform shapeTransform2(positionShape2, orientationShape2);
|
||||||
mLocalShape2ToWorld = mBodyTransform * shapeTransform2;
|
mLocalShape2ToWorld = mBodyTransform * shapeTransform2;
|
||||||
mCompoundCylinderProxyShape = mCompoundBody->addCollisionShape(mCapsuleShape, mShapeTransform);
|
mCompoundCapsuleProxyShape = mCompoundBody->addCollisionShape(mCapsuleShape, mShapeTransform);
|
||||||
mCompoundSphereProxyShape = mCompoundBody->addCollisionShape(mSphereShape, shapeTransform2);
|
mCompoundSphereProxyShape = mCompoundBody->addCollisionShape(mSphereShape, shapeTransform2);
|
||||||
|
|
||||||
// Concave Mesh shape
|
// Concave Mesh shape
|
||||||
|
@ -302,19 +298,17 @@ class TestRaycast : public Test {
|
||||||
mBoxProxyShape->setCollisionCategoryBits(CATEGORY1);
|
mBoxProxyShape->setCollisionCategoryBits(CATEGORY1);
|
||||||
mSphereProxyShape->setCollisionCategoryBits(CATEGORY1);
|
mSphereProxyShape->setCollisionCategoryBits(CATEGORY1);
|
||||||
mCapsuleProxyShape->setCollisionCategoryBits(CATEGORY1);
|
mCapsuleProxyShape->setCollisionCategoryBits(CATEGORY1);
|
||||||
mConeProxyShape->setCollisionCategoryBits(CATEGORY2);
|
|
||||||
mConvexMeshProxyShape->setCollisionCategoryBits(CATEGORY2);
|
mConvexMeshProxyShape->setCollisionCategoryBits(CATEGORY2);
|
||||||
mConvexMeshProxyShapeEdgesInfo->setCollisionCategoryBits(CATEGORY2);
|
mConvexMeshProxyShapeEdgesInfo->setCollisionCategoryBits(CATEGORY2);
|
||||||
mCylinderProxyShape->setCollisionCategoryBits(CATEGORY2);
|
|
||||||
mCompoundSphereProxyShape->setCollisionCategoryBits(CATEGORY2);
|
mCompoundSphereProxyShape->setCollisionCategoryBits(CATEGORY2);
|
||||||
mCompoundCylinderProxyShape->setCollisionCategoryBits(CATEGORY2);
|
mCompoundCapsuleProxyShape->setCollisionCategoryBits(CATEGORY2);
|
||||||
mTriangleProxyShape->setCollisionCategoryBits(CATEGORY1);
|
mTriangleProxyShape->setCollisionCategoryBits(CATEGORY1);
|
||||||
mConcaveMeshProxyShape->setCollisionCategoryBits(CATEGORY2);
|
mConcaveMeshProxyShape->setCollisionCategoryBits(CATEGORY2);
|
||||||
mHeightFieldProxyShape->setCollisionCategoryBits(CATEGORY2);
|
mHeightFieldProxyShape->setCollisionCategoryBits(CATEGORY2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~TestRaycast() {
|
virtual ~TestRaycast() {
|
||||||
delete mBoxShape;
|
delete mBoxShape;
|
||||||
delete mSphereShape;
|
delete mSphereShape;
|
||||||
delete mCapsuleShape;
|
delete mCapsuleShape;
|
||||||
|
@ -1647,7 +1641,7 @@ class TestRaycast : public Test {
|
||||||
Ray ray15(mLocalShapeToWorld * Vector3(0, -9, 1), mLocalShapeToWorld * Vector3(0, 30, 1));
|
Ray ray15(mLocalShapeToWorld * Vector3(0, -9, 1), mLocalShapeToWorld * Vector3(0, 30, 1));
|
||||||
Ray ray16(mLocalShapeToWorld * Vector3(-1, 2, -7), mLocalShapeToWorld * Vector3(-1, 2, 30));
|
Ray ray16(mLocalShapeToWorld * Vector3(-1, 2, -7), mLocalShapeToWorld * Vector3(-1, 2, 30));
|
||||||
|
|
||||||
mCallback.shapeToTest = mCompoundCylinderProxyShape;
|
mCallback.shapeToTest = mCompoundCapsuleProxyShape;
|
||||||
|
|
||||||
test(mCompoundBody->raycast(ray11, raycastInfo));
|
test(mCompoundBody->raycast(ray11, raycastInfo));
|
||||||
mCallback.reset();
|
mCallback.reset();
|
||||||
|
|
|
@ -150,7 +150,7 @@ class TestMathematicsFunctions : public Test {
|
||||||
test(approxEqual(closestSeg2.z, 0.0, 0.000001));
|
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);
|
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.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(closestSeg1.z, -5.0, 0.000001));
|
||||||
test(approxEqual(closestSeg2.x, 1.0, 0.000001));
|
test(approxEqual(closestSeg2.x, 1.0, 0.000001));
|
||||||
test(approxEqual(closestSeg2.y, 5.0, 0.000001));
|
test(approxEqual(closestSeg2.y, 5.0, 0.000001));
|
||||||
|
@ -162,7 +162,7 @@ class TestMathematicsFunctions : public Test {
|
||||||
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, 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));
|
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));
|
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 computeDistancePointToLineDistance()
|
||||||
test(approxEqual(computeDistancePointToLineDistance(Vector3(6, 0, 0), Vector3(14, 0, 0), Vector3(5, 3, 0)), 3.0, 0.000001));
|
test(approxEqual(computeDistancePointToLineDistance(Vector3(6, 0, 0), Vector3(14, 0, 0), Vector3(5, 3, 0)), 3.0, 0.000001));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user