Convert rigidbody conversion to looptri.
Patch D1417 by Martin Felke, with minor edits thanks!
This commit is contained in:
parent
a597a380bb
commit
23a4f547e7
Notes:
blender-bot
2023-02-14 08:52:15 +01:00
Referenced by issue #45474, Deprecate legacy MFace data storage
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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++;
|
||||
if (mvert && lt) {
|
||||
for (i = 0; i < tottri; i++) {
|
||||
/* add first triangle - verts 1,2,3 */
|
||||
const MLoopTri *lt = <[i];
|
||||
int index[3];
|
||||
|
||||
/* 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++;
|
||||
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 */
|
||||
|
|
Loading…
Reference in New Issue