4#include <glm/gtc/constants.hpp>
5#include <glm/gtc/quaternion.hpp>
6#include <glm/gtx/matrix_operation.hpp>
19inline glm::mat3 boxInertiaLocal(
float mass,
const glm::vec3& halfExtents) {
20 if (mass <= 0.0f)
return glm::mat3(0.0f);
22 const glm::vec3 full = halfExtents * 2.0f;
23 const float k = mass / 12.0f;
24 const float ix = k * (full.y * full.y + full.z * full.z);
25 const float iy = k * (full.x * full.x + full.z * full.z);
26 const float iz = k * (full.x * full.x + full.y * full.y);
27 if (ix <= 0.0f || iy <= 0.0f || iz <= 0.0f)
return glm::mat3(0.0f);
29 return glm::diagonal3x3(glm::vec3(ix, iy, iz));
43inline glm::mat3 capsuleInertiaLocal(
float mass,
float radius,
float halfHeight) {
44 if (mass <= 0.0f || radius <= 0.0f)
return glm::mat3(0.0f);
46 const float h = glm::max(halfHeight, 0.0f) * 2.0f;
47 const float r2 = radius * radius;
48 const float cylinderVolume = glm::pi<float>() * r2 * h;
49 const float capsVolume = (4.0f / 3.0f) * glm::pi<float>() * r2 * radius;
50 const float total = cylinderVolume + capsVolume;
51 if (total <= 0.0f)
return glm::mat3(0.0f);
53 const float cylinderMass = mass * (cylinderVolume / total);
54 const float capsMass = mass * (capsVolume / total);
57 const float axial = cylinderMass * r2 * 0.5f + capsMass * (2.0f / 5.0f) * r2;
58 const float perp = cylinderMass * (h * h / 12.0f + r2 * 0.25f)
59 + capsMass * ((2.0f / 5.0f) * r2 + h * h * 0.25f + 3.0f * h * radius / 8.0f);
60 if (axial <= 0.0f || perp <= 0.0f)
return glm::mat3(0.0f);
62 return glm::diagonal3x3(glm::vec3(perp, axial, perp));
75inline glm::mat3 parallelAxisShift(
const glm::mat3& inertia,
float mass,
const glm::vec3& offset) {
76 const float d2 = glm::dot(offset, offset);
77 return inertia + mass * (glm::mat3(d2) - glm::outerProduct(offset, offset));
89inline glm::mat3 inverseInertiaWorld(
const glm::mat3& invInertiaLocal,
const glm::quat& rotation) {
90 const glm::mat3 r = glm::mat3_cast(rotation);
91 return r * invInertiaLocal * glm::transpose(r);