2017-02-20 15:11:13 +00:00
|
|
|
#ifndef TEST_HALF_EDGE_STRUCTURE_H
|
|
|
|
#define TEST_HALF_EDGE_STRUCTURE_H
|
|
|
|
|
|
|
|
// Libraries
|
|
|
|
#include "reactphysics3d.h"
|
|
|
|
#include "Test.h"
|
2018-08-05 14:10:13 +00:00
|
|
|
#include <vector>
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
/// Reactphysics3D namespace
|
|
|
|
namespace reactphysics3d {
|
|
|
|
|
|
|
|
|
|
|
|
// Class TestHalfEdgeStructure
|
|
|
|
/**
|
|
|
|
* Unit test for the HalfEdgeStructure class.
|
|
|
|
*/
|
|
|
|
class TestHalfEdgeStructure : public Test {
|
|
|
|
|
|
|
|
private :
|
|
|
|
|
|
|
|
// ---------- Atributes ---------- //
|
|
|
|
|
2017-12-27 19:53:09 +00:00
|
|
|
/// Memory allocator
|
|
|
|
DefaultAllocator mAllocator;
|
|
|
|
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
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
|
2017-12-27 19:53:09 +00:00
|
|
|
rp3d::HalfEdgeStructure cubeStructure(mAllocator, 6, 8, 24);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
2017-03-22 18:07:31 +00:00
|
|
|
rp3d::Vector3 vertices[8] = {
|
|
|
|
rp3d::Vector3(-0.5, -0.5, 0.5),
|
|
|
|
rp3d::Vector3(0.5, -0.5, 0.5),
|
|
|
|
rp3d::Vector3(0.5, 0.5, 0.5),
|
|
|
|
rp3d::Vector3(-0.5, 0.5, 0.5),
|
|
|
|
rp3d::Vector3(-0.5, -0.5, -0.5),
|
|
|
|
rp3d::Vector3(0.5, -0.5, -0.5),
|
|
|
|
rp3d::Vector3(0.5, 0.5, -0.5),
|
|
|
|
rp3d::Vector3(-0.5, 0.5, -0.5)
|
|
|
|
};
|
|
|
|
|
2017-02-20 15:11:13 +00:00
|
|
|
// Vertices
|
2017-03-22 18:07:31 +00:00
|
|
|
cubeStructure.addVertex(0);
|
|
|
|
cubeStructure.addVertex(1);
|
|
|
|
cubeStructure.addVertex(2);
|
|
|
|
cubeStructure.addVertex(3);
|
|
|
|
cubeStructure.addVertex(4);
|
|
|
|
cubeStructure.addVertex(5);
|
|
|
|
cubeStructure.addVertex(6);
|
|
|
|
cubeStructure.addVertex(7);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Faces
|
2017-12-27 19:53:09 +00:00
|
|
|
List<uint> face0(mAllocator, 4);
|
|
|
|
face0.add(0); face0.add(1); face0.add(2); face0.add(3);
|
|
|
|
List<uint> face1(mAllocator, 4);
|
|
|
|
face1.add(1); face1.add(5); face1.add(6); face1.add(2);
|
|
|
|
List<uint> face2(mAllocator, 4);
|
|
|
|
face2.add(5); face2.add(4); face2.add(7); face2.add(6);
|
|
|
|
List<uint> face3(mAllocator, 4);
|
|
|
|
face3.add(4); face3.add(0); face3.add(3); face3.add(7);
|
|
|
|
List<uint> face4(mAllocator, 4);
|
|
|
|
face4.add(0); face4.add(4); face4.add(5); face4.add(1);
|
|
|
|
List<uint> face5(mAllocator, 4);
|
|
|
|
face5.add(2); face5.add(6); face5.add(7); face5.add(3);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
2017-03-22 18:07:31 +00:00
|
|
|
cubeStructure.addFace(face0);
|
|
|
|
cubeStructure.addFace(face1);
|
|
|
|
cubeStructure.addFace(face2);
|
|
|
|
cubeStructure.addFace(face3);
|
|
|
|
cubeStructure.addFace(face4);
|
|
|
|
cubeStructure.addFace(face5);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
2017-03-22 18:07:31 +00:00
|
|
|
cubeStructure.init();
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// --- Test that the half-edge structure of the cube is valid --- //
|
|
|
|
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(cubeStructure.getNbFaces() == 6);
|
|
|
|
rp3d_test(cubeStructure.getNbVertices() == 8);
|
|
|
|
rp3d_test(cubeStructure.getNbHalfEdges() == 24);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Test vertices
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(0).vertexPointIndex].x == -0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(0).vertexPointIndex].y == -0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(0).vertexPointIndex].z == 0.5);
|
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getVertex(0).edgeIndex).vertexIndex == 0);
|
|
|
|
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(1).vertexPointIndex].x == 0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(1).vertexPointIndex].y == -0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(1).vertexPointIndex].z == 0.5);
|
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getVertex(1).edgeIndex).vertexIndex == 1);
|
|
|
|
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(2).vertexPointIndex].x == 0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(2).vertexPointIndex].y == 0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(2).vertexPointIndex].z == 0.5);
|
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getVertex(2).edgeIndex).vertexIndex == 2);
|
|
|
|
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(3).vertexPointIndex].x == -0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(3).vertexPointIndex].y == 0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(3).vertexPointIndex].z == 0.5);
|
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getVertex(3).edgeIndex).vertexIndex == 3);
|
|
|
|
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(4).vertexPointIndex].x == -0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(4).vertexPointIndex].y == -0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(4).vertexPointIndex].z == -0.5);
|
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getVertex(4).edgeIndex).vertexIndex == 4);
|
|
|
|
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(5).vertexPointIndex].x == 0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(5).vertexPointIndex].y == -0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(5).vertexPointIndex].z == -0.5);
|
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getVertex(5).edgeIndex).vertexIndex == 5);
|
|
|
|
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(6).vertexPointIndex].x == 0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(6).vertexPointIndex].y == 0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(6).vertexPointIndex].z == -0.5);
|
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getVertex(6).edgeIndex).vertexIndex == 6);
|
|
|
|
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(7).vertexPointIndex].x == -0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(7).vertexPointIndex].y == 0.5);
|
|
|
|
rp3d_test(vertices[cubeStructure.getVertex(7).vertexPointIndex].z == -0.5);
|
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getVertex(7).edgeIndex).vertexIndex == 7);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Test faces
|
|
|
|
for (uint f=0; f<6; f++) {
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(cubeStructure.getHalfEdge(cubeStructure.getFace(f).edgeIndex).faceIndex == f);
|
2017-02-20 15:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(cubeStructure.getHalfEdge(edge.twinEdgeIndex).twinEdgeIndex == edgeIndex);
|
|
|
|
rp3d_test(edge.faceIndex == f);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Go to the next edge
|
|
|
|
edgeIndex = edge.nextEdgeIndex;
|
|
|
|
}
|
|
|
|
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(firstEdgeIndex == edgeIndex);
|
2017-02-20 15:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void testTetrahedron() {
|
|
|
|
|
|
|
|
// Create the half-edge structure for a tetrahedron
|
|
|
|
std::vector<std::vector<uint>> faces;
|
2017-12-27 19:53:09 +00:00
|
|
|
rp3d::HalfEdgeStructure tetrahedron(mAllocator, 4, 4, 12);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Vertices
|
2017-03-22 18:07:31 +00:00
|
|
|
rp3d::Vector3 vertices[4] = {
|
|
|
|
rp3d::Vector3(1, -1, -1),
|
|
|
|
rp3d::Vector3(-1, -1, -1),
|
|
|
|
rp3d::Vector3(0, -1, 1),
|
|
|
|
rp3d::Vector3(0, 1, 0)
|
|
|
|
};
|
|
|
|
|
|
|
|
tetrahedron.addVertex(0);
|
|
|
|
tetrahedron.addVertex(1);
|
|
|
|
tetrahedron.addVertex(2);
|
|
|
|
tetrahedron.addVertex(3);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Faces
|
2017-12-27 19:53:09 +00:00
|
|
|
List<uint> face0(mAllocator, 3);
|
|
|
|
face0.add(0); face0.add(1); face0.add(2);
|
|
|
|
List<uint> face1(mAllocator, 3);
|
|
|
|
face1.add(0); face1.add(3); face1.add(1);
|
|
|
|
List<uint> face2(mAllocator, 3);
|
|
|
|
face2.add(1); face2.add(3); face2.add(2);
|
|
|
|
List<uint> face3(mAllocator, 3);
|
|
|
|
face3.add(0); face3.add(2); face3.add(3);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
2017-03-22 18:07:31 +00:00
|
|
|
tetrahedron.addFace(face0);
|
|
|
|
tetrahedron.addFace(face1);
|
|
|
|
tetrahedron.addFace(face2);
|
|
|
|
tetrahedron.addFace(face3);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
2017-03-22 18:07:31 +00:00
|
|
|
tetrahedron.init();
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// --- Test that the half-edge structure of the tetrahedron is valid --- //
|
|
|
|
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(tetrahedron.getNbFaces() == 4);
|
|
|
|
rp3d_test(tetrahedron.getNbVertices() == 4);
|
|
|
|
rp3d_test(tetrahedron.getNbHalfEdges() == 12);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Test vertices
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(0).vertexPointIndex].x == 1);
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(0).vertexPointIndex].y == -1);
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(0).vertexPointIndex].z == -1);
|
|
|
|
rp3d_test(tetrahedron.getHalfEdge(tetrahedron.getVertex(0).edgeIndex).vertexIndex == 0);
|
|
|
|
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(1).vertexPointIndex].x == -1);
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(1).vertexPointIndex].y == -1);
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(1).vertexPointIndex].z == -1);
|
|
|
|
rp3d_test(tetrahedron.getHalfEdge(tetrahedron.getVertex(1).edgeIndex).vertexIndex == 1);
|
|
|
|
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(2).vertexPointIndex].x == 0);
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(2).vertexPointIndex].y == -1);
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(2).vertexPointIndex].z == 1);
|
|
|
|
rp3d_test(tetrahedron.getHalfEdge(tetrahedron.getVertex(2).edgeIndex).vertexIndex == 2);
|
|
|
|
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(3).vertexPointIndex].x == 0);
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(3).vertexPointIndex].y == 1);
|
|
|
|
rp3d_test(vertices[tetrahedron.getVertex(3).vertexPointIndex].z == 0);
|
|
|
|
rp3d_test(tetrahedron.getHalfEdge(tetrahedron.getVertex(3).edgeIndex).vertexIndex == 3);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Test faces
|
|
|
|
for (uint f=0; f<4; f++) {
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(tetrahedron.getHalfEdge(tetrahedron.getFace(f).edgeIndex).faceIndex == f);
|
2017-02-20 15:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(tetrahedron.getHalfEdge(edge.twinEdgeIndex).twinEdgeIndex == edgeIndex);
|
|
|
|
rp3d_test(edge.faceIndex == f);
|
2017-02-20 15:11:13 +00:00
|
|
|
|
|
|
|
// Go to the next edge
|
|
|
|
edgeIndex = edge.nextEdgeIndex;
|
|
|
|
}
|
|
|
|
|
2018-08-05 14:10:13 +00:00
|
|
|
rp3d_test(firstEdgeIndex == edgeIndex);
|
2017-02-20 15:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|