Advertisement
Guest User

Mesh Volume Integration

a guest
Feb 5th, 2016
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.87 KB | None | 0 0
  1. void b3MeshShape::ComputeInertia(b3Inertia* inertia, r32 density) const {
  2.     b3Vec3 center(0.0f, 0.0f, 0.0f);
  3.     r32 volume = 0.0f;
  4.     b3Mat33 I;
  5.     I.SetZero();
  6.  
  7.     // Pick reference point.
  8.     b3Vec3 v1(0.0f, 0.0f, 0.0f);
  9.  
  10.     const r32 inv4 = 0.25f;
  11.     const r32 inv6 = 1.0f / 6.0f;
  12.     const r32 inv60 = 1.0f / 60.0f;
  13.     const r32 inv120 = 1.0f / 120.0f;
  14.  
  15.     b3Vec3 diag(0.0f, 0.0f, 0.0f);
  16.     b3Vec3 offDiag(0.0f, 0.0f, 0.0f);
  17.  
  18.     for (u32 i = 0; i < m_mesh->triangleCount; ++i) {
  19.         const b3Triangle* f = m_mesh->triangles + i;
  20.  
  21.         b3Vec3 v2 = m_mesh->vertices[f->indices[0]];
  22.         b3Vec3 v3 = m_mesh->vertices[f->indices[1]];
  23.         b3Vec3 v4 = m_mesh->vertices[f->indices[2]];
  24.         b3Vec3 tetraCenter = inv4 * (v1 + v2 + v3 + v4);
  25.  
  26.         b3Vec3 e1 = v2 - v1;
  27.         b3Vec3 e2 = v3 - v1;
  28.         b3Vec3 e3 = v4 - v1;
  29.         r32 det = b3Det(e1, e2, e3);
  30.         r32 tetraVolume = inv6 * det;
  31.  
  32.         // Volume weighted center of mass
  33.         center += tetraVolume * tetraCenter;
  34.         volume += tetraVolume;
  35.  
  36.         // Volume weighted inertia tensor
  37.         // https://github.com/melax/sandbox
  38.         for (u32 j = 0; j < 3; ++j) {
  39.             u32 j1 = (j + 1) % 3;
  40.             u32 j2 = (j + 2) % 3;
  41.  
  42.             diag[j] += inv60 * det *
  43.                 (e1[j] * e2[j] + e2[j] * e3[j] + e3[j] * e1[j] +
  44.                     e1[j] * e1[j] + e2[j] * e2[j] + e3[j] * e3[j]);
  45.  
  46.             offDiag[j] += inv120 * det  *
  47.                 (e1[j1] * e2[j2] + e2[j1] * e3[j2] + e3[j1] * e1[j2] +
  48.                     e1[j1] * e3[j2] + e2[j1] * e1[j2] + e3[j1] * e2[j2] +
  49.                     e1[j1] * e1[j2] * 2.0f + e2[j1] * e2[j2] * 2.0f + e3[j1] * e3[j2] * 2.0f);
  50.         }
  51.     }
  52.  
  53.     b3Assert(volume > B3_EPSILON);
  54.  
  55.     r32 invVolume = 1.0f / volume;
  56.  
  57.     diag = invVolume * diag;
  58.     offDiag = invVolume * offDiag;
  59.  
  60.     I.x.Set(diag.y + diag.z, -offDiag.z, -offDiag.y);
  61.     I.y.Set(-offDiag.z, diag.x + diag.z, -offDiag.x);
  62.     I.z.Set(-offDiag.y, -offDiag.x, diag.x + diag.y);
  63.  
  64.     inertia->center = invVolume * center;
  65.     inertia->mass = density * volume;
  66.     inertia->I = inertia->mass * I;
  67. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement