Make possible to create a ConvexMeshShape using a TriangleVertexArray
This commit is contained in:
parent
8be408ccec
commit
a12703b86d
|
@ -100,10 +100,6 @@ class ConcaveMeshRaycastCallback : public DynamicAABBTreeRaycastCallback {
|
|||
}
|
||||
};
|
||||
|
||||
// TODO : Implement raycasting with this collision shape
|
||||
|
||||
// TODO : Make possible for the user to have a scaling factor on the mesh
|
||||
|
||||
// Class ConcaveMeshShape
|
||||
/**
|
||||
* This class represents a concave mesh shape. Note that collision detection
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor to initialize with a array of 3D vertices.
|
||||
// Constructor to initialize with an array of 3D vertices.
|
||||
/// This method creates an internal copy of the input vertices.
|
||||
/**
|
||||
* @param arrayVertices Array with the vertices of the convex mesh
|
||||
|
@ -58,6 +58,77 @@ ConvexMeshShape::ConvexMeshShape(const decimal* arrayVertices, uint nbVertices,
|
|||
recalculateBounds();
|
||||
}
|
||||
|
||||
// Constructor to initialize with a triangle mesh
|
||||
/// This method creates an internal copy of the input vertices.
|
||||
/**
|
||||
* @param triangleVertexArray Array with the vertices and indices of the vertices and triangles of the mesh
|
||||
* @param isEdgesInformationUsed True if you want to use edges information for collision detection (faster but requires more memory)
|
||||
* @param margin Collision margin (in meters) around the collision shape
|
||||
*/
|
||||
ConvexMeshShape::ConvexMeshShape(TriangleVertexArray* triangleVertexArray, bool isEdgesInformationUsed, decimal margin)
|
||||
: ConvexShape(CONVEX_MESH, margin), mMinBounds(0, 0, 0),
|
||||
mMaxBounds(0, 0, 0), mIsEdgesInformationUsed(isEdgesInformationUsed) {
|
||||
|
||||
TriangleVertexArray::VertexDataType vertexType = triangleVertexArray->getVertexDataType();
|
||||
TriangleVertexArray::IndexDataType indexType = triangleVertexArray->getIndexDataType();
|
||||
unsigned char* verticesStart = triangleVertexArray->getVerticesStart();
|
||||
unsigned char* indicesStart = triangleVertexArray->getIndicesStart();
|
||||
int vertexStride = triangleVertexArray->getVerticesStride();
|
||||
int indexStride = triangleVertexArray->getIndicesStride();
|
||||
|
||||
// For each vertex of the mesh
|
||||
for (int v = 0; v < triangleVertexArray->getNbVertices(); v++) {
|
||||
|
||||
// Get the vertices components of the triangle
|
||||
if (vertexType == TriangleVertexArray::VERTEX_FLOAT_TYPE) {
|
||||
const float* vertices = (float*)(verticesStart + v * vertexStride);
|
||||
|
||||
Vector3 vertex(vertices[0], vertices[1], vertices[2] );
|
||||
vertex = vertex * mScaling;
|
||||
mVertices.push_back(vertex);
|
||||
}
|
||||
else if (vertexType == TriangleVertexArray::VERTEX_DOUBLE_TYPE) {
|
||||
const double* vertices = (double*)(verticesStart + v * vertexStride);
|
||||
|
||||
Vector3 vertex(vertices[0], vertices[1], vertices[2] );
|
||||
vertex = vertex * mScaling;
|
||||
mVertices.push_back(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
// If we need to use the edges information of the mesh
|
||||
if (mIsEdgesInformationUsed) {
|
||||
|
||||
// For each triangle of the mesh
|
||||
for (int triangleIndex=0; triangleIndex<triangleVertexArray->getNbTriangles(); triangleIndex++) {
|
||||
|
||||
void* vertexIndexPointer = (indicesStart + triangleIndex * 3 * indexStride);
|
||||
|
||||
uint vertexIndex[3];
|
||||
|
||||
// For each vertex of the triangle
|
||||
for (int k=0; k < 3; k++) {
|
||||
|
||||
// Get the index of the current vertex in the triangle
|
||||
if (indexType == TriangleVertexArray::INDEX_INTEGER_TYPE) {
|
||||
vertexIndex[k] = ((uint*)vertexIndexPointer)[k];
|
||||
}
|
||||
else if (indexType == TriangleVertexArray::INDEX_SHORT_TYPE) {
|
||||
vertexIndex[k] = ((unsigned short*)vertexIndexPointer)[k];
|
||||
}
|
||||
}
|
||||
|
||||
// Add information about the edges
|
||||
addEdge(vertexIndex[0], vertexIndex[1]);
|
||||
addEdge(vertexIndex[0], vertexIndex[2]);
|
||||
addEdge(vertexIndex[1], vertexIndex[2]);
|
||||
}
|
||||
}
|
||||
|
||||
mNbVertices = mVertices.size();
|
||||
recalculateBounds();
|
||||
}
|
||||
|
||||
// Constructor.
|
||||
/// If you use this constructor, you will need to set the vertices manually one by one using
|
||||
/// the addVertex() method.
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "ConvexShape.h"
|
||||
#include "engine/CollisionWorld.h"
|
||||
#include "mathematics/mathematics.h"
|
||||
#include "collision/TriangleMesh.h"
|
||||
#include "collision/narrowphase/GJK/GJKAlgorithm.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
@ -64,8 +65,6 @@ class CollisionWorld;
|
|||
*/
|
||||
class ConvexMeshShape : public ConvexShape {
|
||||
|
||||
// TODO : Implement method setLocalScaling() here
|
||||
|
||||
protected :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
@ -121,10 +120,14 @@ class ConvexMeshShape : public ConvexShape {
|
|||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor to initialize with a array of 3D vertices.
|
||||
/// Constructor to initialize with an array of 3D vertices.
|
||||
ConvexMeshShape(const decimal* arrayVertices, uint nbVertices, int stride,
|
||||
decimal margin = OBJECT_MARGIN);
|
||||
|
||||
/// Constructor to initialize with a triangle vertex array
|
||||
ConvexMeshShape(TriangleVertexArray* triangleVertexArray, bool isEdgesInformationUsed = true,
|
||||
decimal margin = OBJECT_MARGIN);
|
||||
|
||||
/// Constructor.
|
||||
ConvexMeshShape(decimal margin = OBJECT_MARGIN);
|
||||
|
||||
|
@ -215,9 +218,6 @@ inline void ConvexMeshShape::addVertex(const Vector3& vertex) {
|
|||
*/
|
||||
inline void ConvexMeshShape::addEdge(uint v1, uint v2) {
|
||||
|
||||
assert(v1 >= 0);
|
||||
assert(v2 >= 0);
|
||||
|
||||
// If the entry for vertex v1 does not exist in the adjacency list
|
||||
if (mEdgesAdjacencyList.count(v1) == 0) {
|
||||
mEdgesAdjacencyList.insert(std::make_pair(v1, std::set<uint>()));
|
||||
|
|
|
@ -132,6 +132,9 @@ struct Vector2 {
|
|||
/// Overloaded operator
|
||||
Vector2& operator=(const Vector2& vector);
|
||||
|
||||
/// Overloaded less than operator for ordering to be used inside std::set for instance
|
||||
bool operator<(const Vector2& vector) const;
|
||||
|
||||
/// Return a vector taking the minimum components of two vectors
|
||||
static Vector2 min(const Vector2& vector1, const Vector2& vector2);
|
||||
|
||||
|
@ -313,6 +316,11 @@ inline Vector2& Vector2::operator=(const Vector2& vector) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
// Overloaded less than operator for ordering to be used inside std::set for instance
|
||||
inline bool Vector2::operator<(const Vector2& vector) const {
|
||||
return (x == vector.x ? y < vector.y : x < vector.x);
|
||||
}
|
||||
|
||||
// Return a vector taking the minimum components of two vectors
|
||||
inline Vector2 Vector2::min(const Vector2& vector1, const Vector2& vector2) {
|
||||
return Vector2(std::min(vector1.x, vector2.x),
|
||||
|
|
|
@ -144,6 +144,9 @@ struct Vector3 {
|
|||
/// Overloaded operator
|
||||
Vector3& operator=(const Vector3& vector);
|
||||
|
||||
/// Overloaded less than operator for ordering to be used inside std::set for instance
|
||||
bool operator<(const Vector3& vector) const;
|
||||
|
||||
/// Return a vector taking the minimum components of two vectors
|
||||
static Vector3 min(const Vector3& vector1, const Vector3& vector2);
|
||||
|
||||
|
@ -341,6 +344,11 @@ inline Vector3& Vector3::operator=(const Vector3& vector) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
// Overloaded less than operator for ordering to be used inside std::set for instance
|
||||
inline bool Vector3::operator<(const Vector3& vector) const {
|
||||
return (x == vector.x ? (y == vector.y ? z < vector.z : y < vector.y) : x < vector.x);
|
||||
}
|
||||
|
||||
// Return a vector taking the minimum components of two vectors
|
||||
inline Vector3 Vector3::min(const Vector3& vector1, const Vector3& vector2) {
|
||||
return Vector3(std::min(vector1.x, vector2.x),
|
||||
|
|
|
@ -131,7 +131,7 @@ class TestPointInside : public Test {
|
|||
mConeShape = new ConeShape(2, 6, 0);
|
||||
mConeProxyShape = mConeBody->addCollisionShape(mConeShape, mShapeTransform);
|
||||
|
||||
mConvexMeshShape = new ConvexMeshShape(0); // Box of dimension (2, 3, 4)
|
||||
mConvexMeshShape = new ConvexMeshShape(0.0); // Box of dimension (2, 3, 4)
|
||||
mConvexMeshShape->addVertex(Vector3(-2, -3, -4));
|
||||
mConvexMeshShape->addVertex(Vector3(2, -3, -4));
|
||||
mConvexMeshShape->addVertex(Vector3(2, -3, 4));
|
||||
|
@ -142,7 +142,7 @@ class TestPointInside : public Test {
|
|||
mConvexMeshShape->addVertex(Vector3(-2, 3, 4));
|
||||
mConvexMeshProxyShape = mConvexMeshBody->addCollisionShape(mConvexMeshShape, mShapeTransform);
|
||||
|
||||
mConvexMeshShapeBodyEdgesInfo = new ConvexMeshShape(0);
|
||||
mConvexMeshShapeBodyEdgesInfo = new ConvexMeshShape(0.0);
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(-2, -3, -4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(2, -3, -4));
|
||||
mConvexMeshShapeBodyEdgesInfo->addVertex(Vector3(2, -3, 4));
|
||||
|
|
|
@ -207,7 +207,7 @@ class TestRaycast : public Test {
|
|||
mConeShape = new ConeShape(2, 6, 0);
|
||||
mConeProxyShape = mConeBody->addCollisionShape(mConeShape, mShapeTransform);
|
||||
|
||||
mConvexMeshShape = new ConvexMeshShape(0); // Box of dimension (2, 3, 4)
|
||||
mConvexMeshShape = new ConvexMeshShape(0.0); // Box of dimension (2, 3, 4)
|
||||
mConvexMeshShape->addVertex(Vector3(-2, -3, -4));
|
||||
mConvexMeshShape->addVertex(Vector3(2, -3, -4));
|
||||
mConvexMeshShape->addVertex(Vector3(2, -3, 4));
|
||||
|
@ -218,7 +218,7 @@ class TestRaycast : public Test {
|
|||
mConvexMeshShape->addVertex(Vector3(-2, 3, 4));
|
||||
mConvexMeshProxyShape = mConvexMeshBody->addCollisionShape(mConvexMeshShape, mShapeTransform);
|
||||
|
||||
mConvexMeshShapeEdgesInfo = new ConvexMeshShape(0);
|
||||
mConvexMeshShapeEdgesInfo = new ConvexMeshShape(0.0);
|
||||
mConvexMeshShapeEdgesInfo->addVertex(Vector3(-2, -3, -4));
|
||||
mConvexMeshShapeEdgesInfo->addVertex(Vector3(2, -3, -4));
|
||||
mConvexMeshShapeEdgesInfo->addVertex(Vector3(2, -3, 4));
|
||||
|
|
|
@ -22,9 +22,6 @@ FILE(COPY "meshes/" DESTINATION "${EXECUTABLE_OUTPUT_PATH}/meshes/")
|
|||
# Copy the fonts used for the GUI into the build directory
|
||||
FILE(COPY "imgui/DroidSans.ttf" DESTINATION "${EXECUTABLE_OUTPUT_PATH}")
|
||||
|
||||
# Enable C++11 features
|
||||
SET(CMAKE_CXX_FLAGS "-Wall -std=c++0x")
|
||||
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES("src/" ${GLEW_INCLUDE_PATH} "opengl-framework/src/" "glfw/include/" "common/" "scenes/" "imgui/")
|
||||
|
||||
|
@ -95,5 +92,9 @@ SET(SCENES_SOURCES
|
|||
# Create the executable
|
||||
ADD_EXECUTABLE(testbed ${TESTBED_SOURCES} ${SCENES_SOURCES} ${COMMON_SOURCES} ${IMGUI_SOURCES})
|
||||
|
||||
# Enable C++11 features
|
||||
set_property(TARGET testbed PROPERTY CXX_STANDARD 11)
|
||||
set_property(TARGET testbed PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Link with libraries
|
||||
TARGET_LINK_LIBRARIES(testbed reactphysics3d openglframework glfw ${GLFW_LIBRARIES})
|
||||
|
|
|
@ -46,36 +46,17 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position,
|
|||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4::identity();
|
||||
|
||||
// Convert the vertices array to the rp3d::decimal type
|
||||
rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()];
|
||||
for (int i=0; i < mVertices.size(); i++) {
|
||||
vertices[3 * i] = static_cast<rp3d::decimal>(mVertices[i].x);
|
||||
vertices[3 * i + 1] = static_cast<rp3d::decimal>(mVertices[i].y);
|
||||
vertices[3 * i + 2] = static_cast<rp3d::decimal>(mVertices[i].z);
|
||||
}
|
||||
|
||||
// Vertex and Indices array for the triangle mesh (data in shared and not copied)
|
||||
mPhysicsTriangleVertexArray =
|
||||
new rp3d::TriangleVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
|
||||
getNbFaces(0), &(mIndices[0][0]), sizeof(int),
|
||||
rp3d::TriangleVertexArray::VERTEX_FLOAT_TYPE,
|
||||
rp3d::TriangleVertexArray::INDEX_INTEGER_TYPE);
|
||||
|
||||
// Create the collision shape for the rigid body (convex mesh shape) and
|
||||
// do not forget to delete it at the end
|
||||
mConvexShape = new rp3d::ConvexMeshShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal));
|
||||
|
||||
delete[] vertices;
|
||||
|
||||
// Add the edges information of the mesh into the convex mesh collision shape.
|
||||
// This is optional but it really speed up the convex mesh collision detection at the
|
||||
// cost of some additional memory to store the edges inside the collision shape.
|
||||
for (unsigned int i=0; i<getNbFaces(); i++) { // For each triangle face of the mesh
|
||||
|
||||
// Get the three vertex IDs of the vertices of the face
|
||||
unsigned int v1 = getVertexIndexInFace(i, 0);
|
||||
unsigned int v2 = getVertexIndexInFace(i, 1);
|
||||
unsigned int v3 = getVertexIndexInFace(i, 2);
|
||||
|
||||
// Add the three edges into the collision shape
|
||||
mConvexShape->addEdge(v1, v2);
|
||||
mConvexShape->addEdge(v1, v3);
|
||||
mConvexShape->addEdge(v2, v3);
|
||||
}
|
||||
mConvexShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges
|
||||
mConvexShape = new rp3d::ConvexMeshShape(mPhysicsTriangleVertexArray);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
|
@ -116,36 +97,16 @@ ConvexMesh::ConvexMesh(const openglframework::Vector3 &position, float mass,
|
|||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4::identity();
|
||||
|
||||
// Convert the vertices array to the rp3d::decimal type
|
||||
rp3d::decimal* vertices = new rp3d::decimal[3 * mVertices.size()];
|
||||
for (int i=0; i < mVertices.size(); i++) {
|
||||
vertices[3 * i] = static_cast<rp3d::decimal>(mVertices[i].x);
|
||||
vertices[3 * i + 1] = static_cast<rp3d::decimal>(mVertices[i].y);
|
||||
vertices[3 * i + 2] = static_cast<rp3d::decimal>(mVertices[i].z);
|
||||
}
|
||||
// Vertex and Indices array for the triangle mesh (data in shared and not copied)
|
||||
mPhysicsTriangleVertexArray =
|
||||
new rp3d::TriangleVertexArray(getNbVertices(), &(mVertices[0]), sizeof(openglframework::Vector3),
|
||||
getNbFaces(0), &(mIndices[0][0]), sizeof(int),
|
||||
rp3d::TriangleVertexArray::VERTEX_FLOAT_TYPE,
|
||||
rp3d::TriangleVertexArray::INDEX_INTEGER_TYPE);
|
||||
|
||||
// Create the collision shape for the rigid body (convex mesh shape) and do
|
||||
// not forget to delete it at the end
|
||||
mConvexShape = new rp3d::ConvexMeshShape(vertices, mVertices.size(), 3 * sizeof(rp3d::decimal));
|
||||
|
||||
delete[] vertices;
|
||||
|
||||
// Add the edges information of the mesh into the convex mesh collision shape.
|
||||
// This is optional but it really speed up the convex mesh collision detection at the
|
||||
// cost of some additional memory to store the edges inside the collision shape.
|
||||
for (unsigned int i=0; i<getNbFaces(); i++) { // For each triangle face of the mesh
|
||||
|
||||
// Get the three vertex IDs of the vertices of the face
|
||||
unsigned int v1 = getVertexIndexInFace(i, 0);
|
||||
unsigned int v2 = getVertexIndexInFace(i, 1);
|
||||
unsigned int v3 = getVertexIndexInFace(i, 2);
|
||||
|
||||
// Add the three edges into the collision shape
|
||||
mConvexShape->addEdge(v1, v2);
|
||||
mConvexShape->addEdge(v1, v3);
|
||||
mConvexShape->addEdge(v2, v3);
|
||||
}
|
||||
mConvexShape->setIsEdgesInformationUsed(true);// Enable the fast collision detection with edges
|
||||
mConvexShape = new rp3d::ConvexMeshShape(mPhysicsTriangleVertexArray);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
|
@ -179,6 +140,7 @@ ConvexMesh::~ConvexMesh() {
|
|||
mVBOTextureCoords.destroy();
|
||||
mVAO.destroy();
|
||||
|
||||
delete mPhysicsTriangleVertexArray;
|
||||
delete mConvexShape;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ class ConvexMesh : public openglframework::Mesh, public PhysicsObject {
|
|||
/// Previous transform (for interpolation)
|
||||
rp3d::Transform mPreviousTransform;
|
||||
|
||||
rp3d::TriangleVertexArray* mPhysicsTriangleVertexArray;
|
||||
|
||||
/// Collision shape
|
||||
rp3d::ConvexMeshShape* mConvexShape;
|
||||
rp3d::ProxyShape* mProxyShape;
|
||||
|
|
Loading…
Reference in New Issue
Block a user