[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59232] branches/soc-2013-rigid_body_sim: rigidbody: Add convex decomposition collision shape
Sergej Reich
sergej.reich at googlemail.com
Sun Aug 18 14:29:25 CEST 2013
Revision: 59232
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59232
Author: sergof
Date: 2013-08-18 12:29:24 +0000 (Sun, 18 Aug 2013)
Log Message:
-----------
rigidbody: Add convex decomposition collision shape
Uses HACD to break concave meshes into convex chunks and stores them in
a compound shape.
There is a lot of room for optimization. Right now performing convex
decomposition can be very slow for complex meshes.
Modified Paths:
--------------
branches/soc-2013-rigid_body_sim/intern/rigidbody/CMakeLists.txt
branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h
branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp
branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c
branches/soc-2013-rigid_body_sim/source/blender/editors/physics/rigidbody_object.c
branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h
branches/soc-2013-rigid_body_sim/source/blender/makesrna/intern/rna_rigidbody.c
branches/soc-2013-rigid_body_sim/source/creator/CMakeLists.txt
Modified: branches/soc-2013-rigid_body_sim/intern/rigidbody/CMakeLists.txt
===================================================================
--- branches/soc-2013-rigid_body_sim/intern/rigidbody/CMakeLists.txt 2013-08-18 12:29:22 UTC (rev 59231)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/CMakeLists.txt 2013-08-18 12:29:24 UTC (rev 59232)
@@ -25,6 +25,7 @@
.
../../source/blender/gpu
../../extern/bullet2/src
+ ../../extern/HACD
)
set(INC_SYS
Modified: branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h
===================================================================
--- branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h 2013-08-18 12:29:22 UTC (rev 59231)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h 2013-08-18 12:29:24 UTC (rev 59232)
@@ -62,6 +62,7 @@
/* Mesh Data (for Collision Shapes of Meshes) */
typedef struct rbMeshData rbMeshData;
+typedef struct rbHACDMeshData rbHACDMeshData;
/* Constraint */
typedef struct rbConstraint rbConstraint;
@@ -236,6 +237,12 @@
/* 2b - GImpact Meshes */
extern rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh);
+
+extern rbHACDMeshData *RB_hacd_mesh_new(int num_tris, int num_verts);
+extern void RB_hacd_mesh_add_triangle(rbHACDMeshData *mesh, const float v1[3], const float v2[3], const float v3[3]);
+
+extern rbCollisionShape *RB_shape_new_convex_decomp(rbHACDMeshData *mesh);
+
/* Compound Shapes ------------------- */
extern void RB_shape_add_compound_child(rbRigidBody *parent, rbCollisionShape *child, float child_pos[3], float child_orn[4]);
Modified: branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp
===================================================================
--- branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp 2013-08-18 12:29:22 UTC (rev 59231)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp 2013-08-18 12:29:24 UTC (rev 59232)
@@ -75,6 +75,8 @@
#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
+#include "hacdHACD.h"
+
struct rbDynamicsWorld {
btDiscreteDynamicsWorld *dynamicsWorld;
btDefaultCollisionConfiguration *collisionConfiguration;
@@ -860,6 +862,73 @@
return shape;
}
+struct rbHACDMeshData {
+ std::vector< HACD::Vec3<HACD::Real> > verts;
+ std::vector< HACD::Vec3<long> > tris;
+};
+
+rbHACDMeshData *RB_hacd_mesh_new(int num_tris, int num_verts)
+{
+ rbHACDMeshData *mesh = new rbHACDMeshData;
+
+ mesh->verts.reserve(num_verts);
+ mesh->tris.reserve(num_tris);
+
+ return mesh;
+}
+
+void RB_hacd_mesh_add_triangle(rbHACDMeshData *mesh, const float v1[3], const float v2[3], const float v3[3])
+{
+ mesh->tris.push_back(HACD::Vec3<long>(mesh->verts.size(), mesh->verts.size()+1, mesh->verts.size()+2));
+ mesh->verts.push_back(HACD::Vec3<HACD::Real>(v1[0], v1[1], v1[2]));
+ mesh->verts.push_back(HACD::Vec3<HACD::Real>(v2[0], v2[1], v2[2]));
+ mesh->verts.push_back(HACD::Vec3<HACD::Real>(v3[0], v3[1], v3[2]));
+}
+
+rbCollisionShape *RB_shape_new_convex_decomp(rbHACDMeshData *mesh)
+{
+ rbCollisionShape *shape = new rbCollisionShape;
+ btCompoundShape *compound = new btCompoundShape();
+
+ HACD::HACD hacd;
+ hacd.SetPoints(&mesh->verts[0]);
+ hacd.SetNPoints(mesh->verts.size());
+ hacd.SetTriangles(&mesh->tris[0]);
+ hacd.SetNTriangles(mesh->tris.size());
+
+ hacd.Compute();
+
+ int num_clusters = hacd.GetNClusters();
+
+ for (int i = 0; i < num_clusters; i++) {
+ int num_verts = hacd.GetNPointsCH(i);
+ int num_tris = hacd.GetNTrianglesCH(i);
+ HACD::Vec3<HACD::Real> verts[num_verts];
+ HACD::Vec3<long> tris[num_tris];
+ hacd.GetCH(i, verts, tris);
+
+ btVector3 hull_verts[num_verts];
+ for (int i = 0; i < num_verts; i++) {
+ hull_verts[i].setX(verts[i].X());
+ hull_verts[i].setY(verts[i].Y());
+ hull_verts[i].setZ(verts[i].Z());
+ }
+
+ btTransform transform;
+ transform.setIdentity();
+ btConvexHullShape *hull = new btConvexHullShape(&hull_verts[0].getX(), num_verts);
+ compound->addChildShape(transform, hull);
+ }
+
+ shape->mesh = NULL;
+ shape->compound = compound;
+ shape->cshape = compound;
+
+ delete mesh;
+
+ return shape;
+}
+
void RB_shape_add_compound_child(rbRigidBody *parent, rbCollisionShape *child, float child_pos[3], float child_orn[4])
{
btCompoundShape *compound = (btCompoundShape*)parent->body->getCollisionShape();
@@ -882,7 +951,8 @@
}
if (shape->mesh)
delete shape->mesh;
- delete shape->cshape;
+ if (shape->cshape != shape->compound)
+ delete shape->cshape;
delete shape->compound;
delete shape;
}
Modified: branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c 2013-08-18 12:29:22 UTC (rev 59231)
+++ branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c 2013-08-18 12:29:24 UTC (rev 59232)
@@ -341,6 +341,79 @@
return shape;
}
+/* create collision shape of mesh - convex decomposition
+ * returns NULL if creation fails.
+ */
+static rbCollisionShape *rigidbody_get_shape_convex_decomp_from_mesh(Object *ob)
+{
+ rbCollisionShape *shape = NULL;
+
+ if (ob->type == OB_MESH) {
+ DerivedMesh *dm = ob->derivedDeform;
+
+ MVert *mvert;
+ MFace *mface;
+ int totvert;
+ int totface;
+ int tottris = 0;
+
+ /* ensure mesh validity, then grab data */
+ BLI_assert(dm!= NULL); // RB_TODO need to make sure there's no case where deform derived mesh doesn't exist
+ DM_ensure_tessface(dm);
+
+ mvert = (dm) ? dm->getVertArray(dm) : NULL;
+ totvert = (dm) ? dm->getNumVerts(dm) : 0;
+ mface = (dm) ? dm->getTessFaceArray(dm) : NULL;
+ totface = (dm) ? dm->getNumTessFaces(dm) : 0;
+
+ /* sanity checking - potential case when no data will be present */
+ if ((totvert == 0) || (totface == 0)) {
+ printf("WARNING: no geometry data converted for Mesh Collision Shape (ob = %s)\n", ob->id.name + 2);
+ }
+ else {
+ rbHACDMeshData *mdata;
+ int i;
+
+ /* count triangles */
+ for (i = 0; (i < totface) && (mface); i++) {
+ (mface->v4) ? (tottris += 2) : (tottris += 1);
+ }
+
+ /* init mesh data for collision shape */
+ mdata = RB_hacd_mesh_new(tottris, totvert);
+
+ /* loop over all faces, adding them as triangles to the collision shape
+ * (so for some faces, more than triangle will get added)
+ */
+ for (i = 0; (i < totface) && (mface) && (mvert); i++, mface++) {
+ /* add first triangle - verts 1,2,3 */
+ {
+ MVert *va = (mface->v1 < totvert) ? (mvert + mface->v1) : (mvert);
+ MVert *vb = (mface->v2 < totvert) ? (mvert + mface->v2) : (mvert);
+ MVert *vc = (mface->v3 < totvert) ? (mvert + mface->v3) : (mvert);
+
+ RB_hacd_mesh_add_triangle(mdata, va->co, vb->co, vc->co);
+ }
+
+ /* add second triangle if needed - verts 1,3,4 */
+ if (mface->v4) {
+ MVert *va = (mface->v1 < totvert) ? (mvert + mface->v1) : (mvert);
+ MVert *vb = (mface->v3 < totvert) ? (mvert + mface->v3) : (mvert);
+ MVert *vc = (mface->v4 < totvert) ? (mvert + mface->v4) : (mvert);
+
+ RB_hacd_mesh_add_triangle(mdata, va->co, vb->co, vc->co);
+ }
+ }
+ shape = RB_shape_new_convex_decomp(mdata);
+ }
+ }
+ else {
+ printf("ERROR: cannot make Triangular Mesh collision shape for non-Mesh object\n");
+ }
+
+ return shape;
+}
+
/* check parent child relationships to construct compound shapes */
static void rigidbody_prepare_compounds(RigidBodyWorld *rbw)
{
@@ -486,6 +559,9 @@
case RB_SHAPE_TRIMESH:
new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
break;
+ case RB_SHAPE_APPROX:
+ new_shape = rigidbody_get_shape_convex_decomp_from_mesh(ob);
+ break;
}
/* assign new collision shape if creation was successful */
if (new_shape) {
Modified: branches/soc-2013-rigid_body_sim/source/blender/editors/physics/rigidbody_object.c
===================================================================
--- branches/soc-2013-rigid_body_sim/source/blender/editors/physics/rigidbody_object.c 2013-08-18 12:29:22 UTC (rev 59231)
+++ branches/soc-2013-rigid_body_sim/source/blender/editors/physics/rigidbody_object.c 2013-08-18 12:29:24 UTC (rev 59232)
@@ -535,6 +535,7 @@
*/
case RB_SHAPE_CONVEXH:
case RB_SHAPE_TRIMESH:
+ case RB_SHAPE_APPROX:
volume = size[0] * size[1] * size[2];
break;
Modified: branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h
===================================================================
--- branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h 2013-08-18 12:29:22 UTC (rev 59231)
+++ branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h 2013-08-18 12:29:24 UTC (rev 59232)
@@ -171,9 +171,8 @@
RB_SHAPE_CONVEXH,
/* triangulated mesh */
RB_SHAPE_TRIMESH,
-
- /* concave mesh approximated using primitives */
- //RB_SHAPE_COMPOUND,
+ /* concave mesh approximated using convex hulls */
+ RB_SHAPE_APPROX
} eRigidBody_Shape;
/* ******************************** */
Modified: branches/soc-2013-rigid_body_sim/source/blender/makesrna/intern/rna_rigidbody.c
===================================================================
--- branches/soc-2013-rigid_body_sim/source/blender/makesrna/intern/rna_rigidbody.c 2013-08-18 12:29:22 UTC (rev 59231)
+++ branches/soc-2013-rigid_body_sim/source/blender/makesrna/intern/rna_rigidbody.c 2013-08-18 12:29:24 UTC (rev 59232)
@@ -60,6 +60,8 @@
"fewer vertices)"},
{RB_SHAPE_TRIMESH, "MESH", ICON_MESH_MONKEY, "Mesh",
"Mesh consisting of triangles only, allowing for more detailed interactions than convex hulls"},
+ {RB_SHAPE_APPROX, "APPROX", ICON_MESH_MONKEY, "Approx",
+ "Approximation of the mesh using convex decomposition"},
{0, NULL, 0, NULL, NULL}};
/* collision shapes of constraints in rigid body sim */
Modified: branches/soc-2013-rigid_body_sim/source/creator/CMakeLists.txt
===================================================================
--- branches/soc-2013-rigid_body_sim/source/creator/CMakeLists.txt 2013-08-18 12:29:22 UTC (rev 59231)
+++ branches/soc-2013-rigid_body_sim/source/creator/CMakeLists.txt 2013-08-18 12:29:24 UTC (rev 59232)
@@ -1010,6 +1010,7 @@
if(WITH_BULLET)
list_insert_after(BLENDER_SORTED_LIBS "bf_blenkernel" "bf_intern_rigidbody")
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list