sandbox
Loading...
Searching...
No Matches
rigidbody.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_PHYSICS_RIGIDBODY_HPP_
3#define LIBSBX_PHYSICS_RIGIDBODY_HPP_
4
5#include <cmath>
6
7#include <libsbx/units/mass.hpp>
8
9#include <libsbx/math/vector3.hpp>
10#include <libsbx/math/matrix3x3.hpp>
11#include <libsbx/math/quaternion.hpp>
12
13namespace sbx::physics {
14
15class rigidbody {
16
17public:
18
19 rigidbody(const std::float_t mass = 1.0f) {
20 set_mass(mass);
21 }
22
23 auto mass() const noexcept -> std::float_t {
24 if (_inverse_mass <= std::numeric_limits<std::float_t>::epsilon()) {
25 return std::numeric_limits<std::float_t>::infinity();
26 }
27
28 return 1.0f / _inverse_mass;
29 }
30
31 auto set_mass(const std::float_t mass) noexcept -> void {
32 if (mass <= std::numeric_limits<std::float_t>::epsilon()) {
33 _inverse_mass = 0.0f;
34 _is_static = true;
35
36 _inverse_inertia_tensor = math::matrix3x3::zero;
37 _inverse_inertia_tensor_world = math::matrix3x3::zero;
38 } else {
39 _inverse_mass = 1.0f / mass;
40 _is_static = false;
41 }
42 }
43
44 auto inverse_mass() const noexcept -> std::float_t {
45 return _inverse_mass;
46 }
47
48 auto is_static() const noexcept -> bool {
49 return _is_static;
50 }
51
52 auto set_is_static(const bool is_static) noexcept -> void {
53 _is_static = is_static;
54
55 if (_is_static) {
56 _inverse_mass = 0.0f;
57 _velocity = math::vector3::zero;
58 _angular_velocity = math::vector3::zero;
59 _inverse_inertia_tensor = math::matrix3x3::zero;
60 _inverse_inertia_tensor_world = math::matrix3x3::zero;
61 }
62 }
63
64 auto linear_damping() const noexcept -> std::float_t {
65 return _linear_damping;
66 }
67
68 auto set_linear_damping(std::float_t damping) noexcept -> void {
69 _linear_damping = damping;
70 }
71
72 auto angular_damping() const noexcept -> std::float_t {
73 return _angular_damping;
74 }
75
76 auto set_angular_damping(std::float_t damping) noexcept -> void {
77 _angular_damping = damping;
78 }
79
80 auto velocity() const noexcept -> const math::vector3& {
81 return _velocity;
82 }
83
84 auto set_velocity(const math::vector3& velocity) noexcept -> void {
85 _velocity = velocity;
86 }
87
88 auto add_velocity(const math::vector3& delta) noexcept -> void {
89 _velocity += delta;
90 }
91
92 auto angular_velocity() const noexcept -> const math::vector3& {
93 return _angular_velocity;
94 }
95
96 auto set_angular_velocity(const math::vector3& velocity) noexcept -> void {
97 _angular_velocity = velocity;
98 }
99
100 auto add_angular_velocity(const math::vector3& delta) noexcept -> void {
101 _angular_velocity += delta;
102 }
103
104 auto add_force(const math::vector3& force) noexcept -> void {
105 _force_accumulator += force;
106 }
107
108 auto add_force_at_point(const math::vector3& force, const math::vector3& point, const math::vector3& center_of_mass) noexcept -> void {
109 const auto arm = point - center_of_mass;
110 _force_accumulator += force;
111 _torque_accumulator += math::vector3::cross(arm, force);
112 }
113
114 auto constant_forces() const noexcept -> const math::vector3& {
115 return _constant_forces;
116 }
117
118 auto set_constant_forces(const math::vector3& forces) noexcept -> void {
119 _constant_forces = forces;
120 }
121
122 auto add_constant_forces(const math::vector3& forces) noexcept -> void {
123 _constant_forces += forces;
124 }
125
126 auto add_acceleration(const math::vector3& acceleration) noexcept -> void {
127 if (_is_static) {
128 return;
129 }
130
131 const auto m = 1.0f / _inverse_mass;
132
133 _force_accumulator += acceleration * m;
134 }
135
136 auto add_constant_acceleration(const math::vector3& acceleration) noexcept -> void {
137 if (_is_static) {
138 return;
139 }
140
141 const auto m = 1.0f / _inverse_mass;
142
143 _constant_forces += acceleration * m;
144 }
145
146 auto set_constant_acceleration(const math::vector3& acceleration) noexcept -> void {
147 if (_is_static) {
148 _constant_forces = math::vector3::zero;
149 return;
150 }
151
152 const auto m = 1.0f / _inverse_mass;
153
154 _constant_forces = acceleration * m;
155 }
156
157 auto dynamic_forces() const noexcept -> const math::vector3& {
158 return _force_accumulator;
159 }
160
161 auto clear_dynamic_forces() noexcept -> void {
162 _force_accumulator = math::vector3::zero;
163 }
164
165 auto add_torque(const math::vector3& torque) noexcept -> void {
166 _torque_accumulator += torque;
167 }
168
169 auto torque() const noexcept -> const math::vector3& {
170 return _torque_accumulator;
171 }
172
173 auto clear_torque() noexcept -> void {
174 _torque_accumulator = math::vector3::zero;
175 }
176
177 auto inverse_inertia_tensor() const noexcept -> const math::matrix3x3& {
178 return _inverse_inertia_tensor;
179 }
180
181 auto set_inverse_inertia_tensor(const math::matrix3x3& inverse_tensor) noexcept -> void {
182 if (_is_static) {
183 _inverse_inertia_tensor = math::matrix3x3::zero;
184 } else {
185 _inverse_inertia_tensor = inverse_tensor;
186 }
187 }
188
189 auto inverse_inertia_tensor_world() const noexcept -> const math::matrix3x3& {
190 return _inverse_inertia_tensor_world;
191 }
192
193 auto update_inertia_tensor_world(const math::matrix3x3& rotation) noexcept -> void {
194 _inverse_inertia_tensor_world = rotation * _inverse_inertia_tensor * math::matrix3x3::transposed(rotation);
195 }
196
197private:
198
199 std::float_t _inverse_mass{1.0f};
200 bool _is_static{false};
201
202 std::float_t _linear_damping{0.01f};
203 std::float_t _angular_damping{0.05f};
204
205 math::vector3 _velocity{math::vector3::zero};
206 math::vector3 _angular_velocity{math::vector3::zero};
207
208 math::vector3 _force_accumulator{math::vector3::zero};
209 math::vector3 _torque_accumulator{math::vector3::zero};
210
211 math::vector3 _constant_forces{math::vector3::zero};
212
213 math::matrix3x3 _inverse_inertia_tensor{math::matrix3x3::zero};
214 math::matrix3x3 _inverse_inertia_tensor_world{math::matrix3x3::zero};
215
216}; // class rigidbody
217
218} // namespace sbx::physics
219
220#endif // LIBSBX_PHYSICS_RIGIDBODY_HPP_
Definition: matrix3x3.hpp:26
Definition: vector3.hpp:23
Definition: rigidbody.hpp:15