From 23a4f547e7cf22a5ea7a4ee9bf7de78e1eb41de1 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Sun, 19 Jul 2015 19:10:41 +0200 Subject: Convert rigidbody conversion to looptri. Patch D1417 by Martin Felke, with minor edits thanks! --- source/blender/blenkernel/BKE_mesh.h | 4 +- source/blender/blenkernel/intern/mesh_evaluate.c | 62 ++++++------------- source/blender/blenkernel/intern/rigidbody.c | 78 ++++++++++++------------ 3 files changed, 59 insertions(+), 85 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index afe6fda48ed..bed73469b5c 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -273,8 +273,8 @@ bool BKE_mesh_center_centroid(const struct Mesh *me, float r_cent[3]); void BKE_mesh_calc_volume( const struct MVert *mverts, const int numVerts, - const struct MFace *mfaces, const int numFaces, - float *r_vol, float *r_com); + const struct MLoopTri *mlooptri, const int numTris, + const struct MLoop *mloop, float *r_vol, float *r_com); /* tessface */ void BKE_mesh_loops_to_mface_corners( diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index d0706990352..73aba74c7f0 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -2047,24 +2047,22 @@ bool BKE_mesh_center_centroid(const Mesh *me, float r_cent[3]) static bool mesh_calc_center_centroid_ex( const MVert *mverts, int UNUSED(numVerts), - const MFace *mfaces, int numFaces, - float r_center[3]) + const MLoopTri *lt, int numTris, + const MLoop *mloop, float r_center[3]) { float totweight; - int f; + int t; zero_v3(r_center); - if (numFaces == 0) + if (numTris == 0) return false; totweight = 0.0f; - for (f = 0; f < numFaces; ++f) { - const MFace *face = &mfaces[f]; - const MVert *v1 = &mverts[face->v1]; - const MVert *v2 = &mverts[face->v2]; - const MVert *v3 = &mverts[face->v3]; - const MVert *v4 = &mverts[face->v4]; + for (t = 0; t < numTris; t++, lt++) { + const MVert *v1 = &mverts[mloop[lt->tri[0]].v]; + const MVert *v2 = &mverts[mloop[lt->tri[1]].v]; + const MVert *v3 = &mverts[mloop[lt->tri[2]].v]; float area; area = area_tri_v3(v1->co, v2->co, v3->co); @@ -2072,14 +2070,6 @@ static bool mesh_calc_center_centroid_ex( madd_v3_v3fl(r_center, v2->co, area); madd_v3_v3fl(r_center, v3->co, area); totweight += area; - - if (face->v4) { - area = area_tri_v3(v3->co, v4->co, v1->co); - madd_v3_v3fl(r_center, v3->co, area); - madd_v3_v3fl(r_center, v4->co, area); - madd_v3_v3fl(r_center, v1->co, area); - totweight += area; - } } if (totweight == 0.0f) return false; @@ -2089,10 +2079,9 @@ static bool mesh_calc_center_centroid_ex( return true; } -void BKE_mesh_calc_volume( - const MVert *mverts, const int numVerts, - const MFace *mfaces, const int numFaces, - float *r_vol, float *r_com) +void BKE_mesh_calc_volume(const MVert *mverts, const int numVerts, + const MLoopTri *lt, const int numTris, + const MLoop *mloop, float *r_vol, float *r_com) { float center[3]; float totvol; @@ -2101,19 +2090,17 @@ void BKE_mesh_calc_volume( if (r_vol) *r_vol = 0.0f; if (r_com) zero_v3(r_com); - if (numFaces == 0) + if (numTris == 0) return; - if (!mesh_calc_center_centroid_ex(mverts, numVerts, mfaces, numFaces, center)) + if (!mesh_calc_center_centroid_ex(mverts, numVerts, lt, numTris, mloop, center)) return; totvol = 0.0f; - for (f = 0; f < numFaces; ++f) { - const MFace *face = &mfaces[f]; - const MVert *v1 = &mverts[face->v1]; - const MVert *v2 = &mverts[face->v2]; - const MVert *v3 = &mverts[face->v3]; - const MVert *v4 = &mverts[face->v4]; + for (f = 0; f < numTris; f++, lt++) { + const MVert *v1 = &mverts[mloop[lt->tri[0]].v]; + const MVert *v2 = &mverts[mloop[lt->tri[1]].v]; + const MVert *v3 = &mverts[mloop[lt->tri[2]].v]; float vol; vol = volume_tetrahedron_signed_v3(center, v1->co, v2->co, v3->co); @@ -2127,21 +2114,6 @@ void BKE_mesh_calc_volume( madd_v3_v3fl(r_com, v2->co, vol); madd_v3_v3fl(r_com, v3->co, vol); } - - if (face->v4) { - vol = volume_tetrahedron_signed_v3(center, v3->co, v4->co, v1->co); - - if (r_vol) { - totvol += vol; - } - if (r_com) { - /* averaging factor 1/4 is applied in the end */ - madd_v3_v3fl(r_com, center, vol); // XXX could extract this - madd_v3_v3fl(r_com, v3->co, vol); - madd_v3_v3fl(r_com, v4->co, vol); - madd_v3_v3fl(r_com, v1->co, vol); - } - } } /* Note: Depending on arbitrary centroid position, diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index ff9e1a2b831..fb96738449a 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -274,57 +274,55 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) if (ob->type == OB_MESH) { DerivedMesh *dm = NULL; MVert *mvert; - MFace *mface; + const MLoopTri *lt = NULL; int totvert; - int totface; - int tottris = 0; - int triangle_index = 0; - + int tottri = 0; + const MLoop *mloop = NULL; + dm = rigidbody_get_mesh(ob); /* ensure mesh validity, then grab data */ if (dm == NULL) return NULL; - DM_ensure_tessface(dm); + DM_ensure_looptri(dm); mvert = dm->getVertArray(dm); totvert = dm->getNumVerts(dm); - mface = dm->getTessFaceArray(dm); - totface = dm->getNumTessFaces(dm); + lt = dm->getLoopTriArray(dm); + tottri = dm->getNumLoopTri(dm); + mloop = dm->getLoopArray(dm); /* sanity checking - potential case when no data will be present */ - if ((totvert == 0) || (totface == 0)) { + if ((totvert == 0) || (tottri == 0)) { printf("WARNING: no geometry data converted for Mesh Collision Shape (ob = %s)\n", ob->id.name + 2); } else { rbMeshData *mdata; int i; - - /* count triangles */ - for (i = 0; i < totface; i++) { - (mface[i].v4) ? (tottris += 2) : (tottris += 1); - } /* init mesh data for collision shape */ - mdata = RB_trimesh_data_new(tottris, totvert); + mdata = RB_trimesh_data_new(tottri, totvert); RB_trimesh_add_vertices(mdata, (float *)mvert, totvert, sizeof(MVert)); /* 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 */ - RB_trimesh_add_triangle_indices(mdata, triangle_index, mface->v1, mface->v2, mface->v3); - triangle_index++; - - /* add second triangle if needed - verts 1,3,4 */ - if (mface->v4) { - RB_trimesh_add_triangle_indices(mdata, triangle_index, mface->v1, mface->v3, mface->v4); - triangle_index++; + if (mvert && lt) { + for (i = 0; i < tottri; i++) { + /* add first triangle - verts 1,2,3 */ + const MLoopTri *lt = <[i]; + int index[3]; + + index[0] = (&mloop[lt->tri[0]])->v; + index[1] = (&mloop[lt->tri[1]])->v; + index[2] = (&mloop[lt->tri[2]])->v; + + RB_trimesh_add_triangle_indices(mdata, i, UNPACK3(index)); } } + RB_trimesh_finish(mdata); /* construct collision shape @@ -512,22 +510,24 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) if (ob->type == OB_MESH) { DerivedMesh *dm = rigidbody_get_mesh(ob); MVert *mvert; - MFace *mface; - int totvert, totface; + const MLoopTri *lt = NULL; + int totvert, tottri = 0; + const MLoop *mloop = NULL; /* ensure mesh validity, then grab data */ if (dm == NULL) return; - DM_ensure_tessface(dm); + DM_ensure_looptri(dm); mvert = dm->getVertArray(dm); totvert = dm->getNumVerts(dm); - mface = dm->getTessFaceArray(dm); - totface = dm->getNumTessFaces(dm); + lt = dm->getLoopTriArray(dm); + tottri = dm->getNumLoopTri(dm); + mloop = dm->getLoopArray(dm); - if (totvert > 0 && totface > 0) { - BKE_mesh_calc_volume(mvert, totvert, mface, totface, &volume, NULL); + if (totvert > 0 && tottri > 0) { + BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL); } /* cleanup temp data */ @@ -595,22 +595,24 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_com[3]) if (ob->type == OB_MESH) { DerivedMesh *dm = rigidbody_get_mesh(ob); MVert *mvert; - MFace *mface; - int totvert, totface; + const MLoopTri* lt = NULL; + int totvert, tottri = 0; + const MLoop* mloop = NULL; /* ensure mesh validity, then grab data */ if (dm == NULL) return; - DM_ensure_tessface(dm); + DM_ensure_looptri(dm); mvert = dm->getVertArray(dm); totvert = dm->getNumVerts(dm); - mface = dm->getTessFaceArray(dm); - totface = dm->getNumTessFaces(dm); + lt = dm->getLoopTriArray(dm); + tottri = dm->getNumLoopTri(dm); + mloop = dm->getLoopArray(dm); - if (totvert > 0 && totface > 0) { - BKE_mesh_calc_volume(mvert, totvert, mface, totface, NULL, r_com); + if (totvert > 0 && tottri > 0) { + BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, NULL, r_com); } /* cleanup temp data */ -- cgit v1.2.3