group2 0.1.0
CSE 125 Group 2
Loading...
Searching...
No Matches
Inertia.hpp
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <glm/mat3x3.hpp>
12#include <glm/vec3.hpp>
13
15{
16
19[[nodiscard]] inline glm::mat3 boxInvInertia(float mass, glm::vec3 halfExtents) noexcept
20{
21 if (mass <= 0.0f)
22 return glm::mat3(0.0f); // static body
23 // I_xx = (1/12) m (h² + d²) where h = 2*hY, d = 2*hZ
24 // I_yy = (1/12) m (w² + d²)
25 // I_zz = (1/12) m (w² + h²)
26 const float w2 = (halfExtents.x * 2.0f) * (halfExtents.x * 2.0f);
27 const float h2 = (halfExtents.y * 2.0f) * (halfExtents.y * 2.0f);
28 const float d2 = (halfExtents.z * 2.0f) * (halfExtents.z * 2.0f);
29 const float k = 12.0f / mass;
30 return glm::mat3{
31 glm::vec3{k / (h2 + d2), 0.0f, 0.0f},
32 glm::vec3{0.0f, k / (w2 + d2), 0.0f},
33 glm::vec3{0.0f, 0.0f, k / (w2 + h2)},
34 };
35}
36
39[[nodiscard]] inline glm::mat3 sphereInvInertia(float mass, float radius) noexcept
40{
41 if (mass <= 0.0f)
42 return glm::mat3(0.0f);
43 const float i = (2.0f / 5.0f) * mass * radius * radius;
44 return glm::mat3{
45 glm::vec3{1.0f / i, 0.0f, 0.0f},
46 glm::vec3{0.0f, 1.0f / i, 0.0f},
47 glm::vec3{0.0f, 0.0f, 1.0f / i},
48 };
49}
50
54[[nodiscard]] inline glm::mat3 capsuleInvInertia(float mass, float radius, float halfHeight) noexcept
55{
56 if (mass <= 0.0f)
57 return glm::mat3(0.0f);
58
59 // Split mass proportionally by volume. Cylinder: π r² (2h).
60 // Hemispheres total: (4/3) π r³.
61 const float r = radius;
62 const float h = halfHeight;
63 const float vCyl = 2.0f * h * (r * r);
64 const float vSph = (4.0f / 3.0f) * (r * r * r);
65 const float vTot = vCyl + vSph;
66 if (vTot <= 0.0f)
67 return glm::mat3(0.0f);
68
69 const float mCyl = mass * (vCyl / vTot);
70 const float mSph = mass * (vSph / vTot);
71
72 // Cylinder inertia about its symmetry axis (Y):
73 // I_yy_cyl = (1/2) m r²
74 // I_xx_cyl = I_zz_cyl = (1/12) m (3 r² + (2h)²)
75 const float iYcyl = 0.5f * mCyl * r * r;
76 const float iXcyl = (1.0f / 12.0f) * mCyl * (3.0f * r * r + (2.0f * h) * (2.0f * h));
77
78 // Two hemispheres = full sphere (parallel-axis to caps offset by ±h):
79 // I_yy_sph = (2/5) m r²
80 // I_xx_sph = (2/5) m r² + m * h² (parallel-axis applied at cap centre)
81 const float iYsph = (2.0f / 5.0f) * mSph * r * r;
82 const float iXsph = iYsph + mSph * h * h;
83
84 const float iY = iYcyl + iYsph;
85 const float iX = iXcyl + iXsph;
86
87 return glm::mat3{
88 glm::vec3{1.0f / iX, 0.0f, 0.0f},
89 glm::vec3{0.0f, 1.0f / iY, 0.0f},
90 glm::vec3{0.0f, 0.0f, 1.0f / iX},
91 };
92}
93
94} // namespace physics::inertia
Definition Inertia.hpp:15
glm::mat3 sphereInvInertia(float mass, float radius) noexcept
Local-space inverse inertia tensor of a solid sphere of mass m and radius r.
Definition Inertia.hpp:39
glm::mat3 boxInvInertia(float mass, glm::vec3 halfExtents) noexcept
Local-space inverse inertia tensor of a solid box of mass m and full extents (= 2 * halfExtents).
Definition Inertia.hpp:19
glm::mat3 capsuleInvInertia(float mass, float radius, float halfHeight) noexcept
Local-space inverse inertia tensor of a capsule (cylinder + 2 hemispherical caps) with vertical axis ...
Definition Inertia.hpp:54