reactphysics3d
reactphysics3d copied to clipboard
Cylinder and cone shapes
Are there any plans to have more collision shapes like cylinder and cone?
For example Jitter physics provides cylinder, cone and minkowski sum shapes, each of them being just few lines of code.
Hello. Thanks for your feedback.
I currently don't plan to add those shapes in a near future. It is currently possible to approximate those shapes with a tessellated mesh and using a ConvexMeshShape in ReactPhysics3D.
However, if many people are interested in this feature. I can reconsider this of course.
Yeah, I am also looking forward to a cylinder shape since I am working on a dice simulation software. Maybe currently I have to resort to a tessellated mesh even though it looks a bit odd.
Yeah, I am also looking forward to a cylinder shape since I am working on a dice simulation software. Maybe currently I have to resort to a tessellated mesh even though it looks a bit odd.
I hope so for I need to do the same work haha.
@Dorbmon I have successfully used a ConvexMeshShape
to approximate the cylinder shape though the speed is not satisfactory.
Here is the main code:
// ====== Create a Cylinder ======
// Use ConvexMeshShape to approximate a cylinder.
// Be cafeful to set vertices of a face as counter clockwise
// order as seen from the outside of your convex mesh.
RigidBody* body = world->createRigidBody(transform);
const int cylinderSides = 1000; // number of side faces
const float cylinderR = 5; // radius [m]
const float cylinderH = 4; // height [m]
// Array with the vertices coordinates of the convex mesh
float vertices[6 * cylinderSides]; // 2 * cylinderSides * 3
for (int i = 0; i != cylinderSides; i++) {
vertices[3 * i] = cylinderR * std::cos(2 * 3.14159265358979 * i / cylinderSides);
vertices[3 * i + 1] = -cylinderH / 2;
vertices[3 * i + 2] = cylinderR * std::sin(2 * 3.14159265358979 * i / cylinderSides);
vertices[3 * (cylinderSides + i)] = vertices[3 * i];
vertices[3 * (cylinderSides + i) + 1] = cylinderH / 2;
vertices[3 * (cylinderSides + i) + 2] = vertices[3 * i + 2];
}
// Array with the vertices indices for each face of the mesh
int indices[6 * cylinderSides]; // 4 * cylinderSides + cylinderSides * 2
for (int i = 0; i != cylinderSides - 1; i++) {
// side face
indices[4 * i ] = i;
indices[4 * i + 1] = i + 1;
indices[4 * i + 2] = cylinderSides + i + 1;
indices[4 * i + 3] = cylinderSides + i;
// top and bottom face
indices[4 * cylinderSides + i] = cylinderSides - i - 1;
indices[5 * cylinderSides + i] = cylinderSides + i;
}
indices[4 * cylinderSides - 4] = cylinderSides - 1;
indices[4 * cylinderSides - 3] = 0;
indices[4 * cylinderSides - 2] = cylinderSides;
indices[4 * cylinderSides - 1] = 2 * cylinderSides - 1;
indices[5 * cylinderSides - 1] = 0;
indices[6 * cylinderSides - 1] = 2 * cylinderSides - 1;
// Description of the (cylinderSides + 2) faces of the convex mesh
PolygonVertexArray::PolygonFace polygonFaces[cylinderSides + 2];
// PolygonVertexArray::PolygonFace* face = polygonFaces;
for (int f = 0; f != cylinderSides; f++) { // first for side faces
// First vertex of the face in the indices array
polygonFaces[f].indexBase = f * 4;
// Number of vertices in the face
polygonFaces[f].nbVertices = 4;
}
polygonFaces[cylinderSides].indexBase = cylinderSides * 4;
polygonFaces[cylinderSides].nbVertices = cylinderSides;
polygonFaces[cylinderSides + 1].indexBase = cylinderSides * 5;
polygonFaces[cylinderSides + 1].nbVertices = cylinderSides;
// Create the polygon vertex array
PolygonVertexArray * polygonVertexArray = new PolygonVertexArray(
2 * cylinderSides, vertices, 3 * sizeof(float), indices,
sizeof(int), cylinderSides + 2 , polygonFaces,
PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
// Create the polyhedron mesh
PolyhedronMesh* polyhedronMesh = physicsCommon.createPolyhedronMesh(polygonVertexArray);
// Create the convex mesh collision shape
ConvexMeshShape* cylinderShape = physicsCommon.createConvexMeshShape(polyhedronMesh);
body->addCollider(cylinderShape, Transform::identity());
The full code is in this file of repo Dice Simulation.
@Teddy-van-Jerry Hello, I tried your cylinder code but it seems to fall straight through my floor?
@patrikpatrik Hi, it is quite a long time since I wrote this code. At that time, it was version 0.8.0
. I am not sure whether this method is broken for 0.9.0
.
Have you tried this simple code where there is also a floor to collide with. Some settings for the floor:
// Create a rigid body in the world
Vector3 position(0, 20, 0);
Vector3 floorPosition(0, -100, 0);
Quaternion orientation = Quaternion::identity();
Transform transform(position, orientation);
Transform floorTransform(floorPosition, orientation);
RigidBody* floor = world->createRigidBody(floorTransform);
floor->setType(BodyType::STATIC);
// Half extents of the box in the x, y and z directions
const Vector3 floorSize (100000, 100, 100000);
/* other code */
BoxShape* floorShape = physicsCommon.createBoxShape(floorSize);
Transform transform0 = Transform::identity();
floor->addCollider(floorShape, transform0);
Yeah I've tried creating a ground. I got it to work on the default convex cube method on the user manual page and a 3 sided equilateral triangle. Here is a snapshot of the cylinder in action. I turned down the cylinderSides
count to 100 for testing, the camera is looking slightly down as the cylinder just passed through the floor. I had the debug lines enabled to see it. I also noticed there seems to be no mesh on the top and bottom ? Or maybe its just one big piece.
https://ibb.co/LS67jC6
I've had this problem before where some of my objects passed through, could it be the winding order?
I am not quite sure where the problem lies since in my code snippet vertices of each face are defined clockwise so as to satisfy the requirement.
About the mesh line on the top and bottom, I am not quite sure why. But according to the code itself, there are $N+2$ faces added to the cylinder, where $N$ is the number of cylinderSides
.
Sorry I am not familiar with the graphic interface provided by the library (including how debug lines work). Probably the logic there is a bit different from doing the simulation from the terminal.
P.S. I am just about to sleep, so there can be delay of response. :-)
Clockwise? But in the user manual @ 11.1.4 Convex Mesh Shape it states:
When you specify the vertices for each face of your convex mesh, be careful with their order. The vertices of a face must be specified in counter clockwise order as seen from the outside of your convex mesh.
Oops, sorry, I mean counter clockwise.
I reckon the idea behind the code snippet is relatively clear. Each face is built first, and then faces are added to the mesh according to the sequence of $N$ sides, top side and bottom side.
Proper non-hacky cylinder support would be appreciated