tile2d
Loading...
Searching...
No Matches
body.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "math.hpp"
4
11T2D_NAMESPACE_BEGIN
12
13template<class TileData>
14class World;
15
19enum class BodyType : uint8_t {
20 Tile,
21 Bullet,
22 Invalid
23};
24
30class WorldBody {
31 template<class TileData>
32 friend class World;
33 friend class ResolveMethods;
34public:
41 WorldBody(uint32_t id, BodyType bodyType)
42 : m_id(id), m_bodyType(bodyType) {}
43
48 uint32_t id() const {
49 return m_id;
50 }
51
56 BodyType bodyType() const {
57 return m_bodyType;
58 }
59
65 return m_transform;
66 }
67
72 const Transform& transform() const {
73 return m_transform;
74 }
75
81 void moveBy(const vec2& amount) {
82 m_flags[NEEDS_REINSERT] = true;
83 m_transform.pos += amount;
84 }
85
91 void rotateBy(Float amount) {
92 m_flags[NEEDS_REINSERT] = true;
93 m_transform.rot += amount;
94 m_transform.update();
95 }
96
102 void setPos(const vec2& pos) {
103 m_flags[NEEDS_REINSERT] = true;
104 m_transform.pos = pos;
105 }
106
112 void setRot(Float rot) {
113 m_flags[NEEDS_REINSERT] = true;
114 m_transform.rot = rot;
115 m_transform.update();
116 }
117
123 virtual void integrate(Float dt) = 0;
124
125 enum FlagIndexes {
126 NEEDS_REINSERT = 0, // needs to be reinserted into the spatial tree or grid.
127 IS_STATIC = 1 // the body is static
128 };
129
135 bool isStatic() const {
136 return m_flags[IS_STATIC];
137 }
138
144 virtual void setStatic(bool static_) {
145 m_flags[IS_STATIC] = static_;
146 }
147
153 virtual vec2 getWorldPoint(const vec2& localPoint) const {
154 return m_transform.getWorldPoint(localPoint);
155 }
156
162 virtual vec2 getLocalPoint(const vec2& worldPoint) const {
163 return m_transform.getLocalPoint(worldPoint);
164 }
165
171 virtual vec2 getWorldPos() {
172 return m_transform.pos;
173 }
174
180 void addLinearVel(const vec2& vel) {
181 m_linearVelocity += vel * (Float)!m_flags[IS_STATIC];
182 }
183
189 Float mass() const {
190 return m_mass;
191 }
192
198 Float inverseMass() const {
199 return m_inverseMass;
200 }
201
207 virtual AABB<Float> getAABB() const = 0;
208
209 // get the local AABB (of the entire object) in the localSpace of spaceTransform
210 inline AABB<Float> getAABB(const Transform& spaceTransform, const vec2& localOffset = { Float(0.5f), Float(0.5f) }) const {
211 return getAABB(getAABB(), spaceTransform, localOffset);
212 }
213
214 // get the some local AABB in the localSpace of spaceTransform
215 inline AABB<Float> getAABB(const AABB<Float>& localAABB, const Transform& spaceTransform, const vec2& localOffset = { Float(0.5f), Float(0.5f) }) const {
216 vec2 relPos = spaceTransform.getLocalPoint(getWorldPoint(localAABB.midpoint()), localOffset);
217 return AABB<Float>(relPos, localAABB.width() * 0.5f, localAABB.height() * 0.5f).rotate(spaceTransform.sincos - m_transform.sincos);
218 }
219
220protected:
221 Transform m_transform;
222 Float m_mass = 0.0f;
223 Float m_inverseMass = 0;
224 vec2 m_linearVelocity = { 0.0f, 0.0f };
225
226protected:
227 std::bitset<4> m_flags;
228 BodyType m_bodyType = BodyType::Invalid;
229private:
230 uint32_t m_id = 0;
231};
232
238class Body : public WorldBody {
239 friend class ImpulseMethod;
240 template<class TileData>
241 friend class World;
242
243public:
250 Body(uint32_t id, BodyType type)
251 : WorldBody(id, type) {}
252
253 virtual void integrate(Float dt) override {
254 assert(isValid());
255
256 // Using the semi implicit euler method
257
258 // A(v) = force / mass
259 // V = v + A(v) * dt
260 // P = p + V * dt;
261 m_linearVelocity = m_linearVelocity + m_force * m_inverseMass * dt;
262 vec2 newPos = m_transform.pos + m_linearVelocity * dt;
263 m_force = { 0.0f, 0.0f };
264
265 m_angularVelocity = m_angularVelocity + m_torque * m_inverseI * dt;
266 Float rot = m_transform.rot + m_angularVelocity * dt;
267 m_torque = 0.0f;
268
269 m_transform.update();
270
271 if(!nearlyEqual(newPos, m_transform.pos, 0.1f) || !nearlyEqual(rot, m_transform.rot, 0.05f))
272 m_flags[NEEDS_REINSERT] = true;
273
274 m_transform.pos = newPos;
275 m_transform.rot = rot;
276 }
277
278 virtual vec2 getWorldPoint(const vec2& localPoint) const override {
279 return m_transform.getWorldPoint(localPoint, m_com);
280 }
281
282 virtual vec2 getLocalPoint(const vec2& worldPoint) const override {
283 return m_transform.getLocalPoint(worldPoint, m_com);
284 }
285
286 virtual vec2 getWorldPos() override {
287 return m_transform.pos + m_com;
288 }
289
290 virtual void setStatic(bool static_) override {
291 WorldBody::setStatic(static_);
292
293 if (static_) {
294 m_inverseI = 0;
295 m_inverseMass = 0;
296 m_linearVelocity = vec2(0);
297 m_angularVelocity = 0;
298 m_com = { 0, 0 };
299 }
300 else {
301 m_inverseI = (Float)1 / m_I;
302 m_inverseMass = (Float)1 / m_mass;
303 m_com = m_unweightedCom * m_inverseMass;
304 }
305 }
306
312 void addAngularVel(const Float& vel) {
313 m_angularVelocity = vel * (Float)!m_flags[IS_STATIC];
314 }
315
321 const vec2& com() const {
322 return m_com;
323 }
324
330 const vec2& centroid() const {
331 return m_centroid;
332 }
333
339 Float rotationalInertia() const {
340 return m_I;
341 }
342
343protected:
344 Float m_inverseI = 0;
345
346 vec2 m_centroid = { 0.0f, 0.0f };
347 vec2 m_com = { 0.0f, 0.0f };
348 Float m_I = 0.0f;
349 vec2 m_unweightedCom = { 0.0f, 0.0f };
350 vec2 m_unweightedCentroid = { 0.0f, 0.0f };
351
352 vec2 m_force = { 0.0f, 0.0f };
353 Float m_angularVelocity = 0.0f;
354 Float m_torque = 0.0f;
355};
356
357class BulletBody : public WorldBody {
358public:
359 BulletBody(uint32_t id, Float radius)
360 : WorldBody(id, BodyType::Bullet), m_radius(radius) {}
361
362 virtual void integrate(Float dt) override {
363 m_transform.pos = m_transform.pos + m_linearVelocity * dt;
364 }
365
366 virtual AABB<Float> getAABB() const {
367 const Float m_aabbRadius = m_radius * sqrt<Float>(2.0f);
368
369 return AABB<Float>(m_transform.pos, m_aabbRadius, m_aabbRadius);
370 }
371
372private:
373 Float m_radius;
374 Float m_mass = 0.0f;
375};
376
377T2D_NAMESPACE_END
Extends the functionality of WorldBody to allow for things such as angular velocity.
Definition body.hpp:238
virtual vec2 getLocalPoint(const vec2 &worldPoint) const override
Gets a world position thats space of this body and transforms into the local space of this body.
Definition body.hpp:282
const vec2 & com() const
Returns the center of mass of this body.
Definition body.hpp:321
const vec2 & centroid() const
Returns the centroid of this body.
Definition body.hpp:330
virtual void integrate(Float dt) override
Integerates this body, meaning the linear velocity and angular velocity will be integrated into the p...
Definition body.hpp:253
Body(uint32_t id, BodyType type)
constructs a new WorldBody
Definition body.hpp:250
virtual vec2 getWorldPos() override
Returns the world position of this body.
Definition body.hpp:286
void addAngularVel(const Float &vel)
Applies an angular velocity to this body.
Definition body.hpp:312
virtual vec2 getWorldPoint(const vec2 &localPoint) const override
Gets a local position thats within the local space of this body and transforms into the world space.
Definition body.hpp:278
virtual void setStatic(bool static_) override
Either make the body static or dynamic.
Definition body.hpp:290
Float rotationalInertia() const
Returns rotational inertia scalar of this body.
Definition body.hpp:339
Definition body.hpp:357
virtual AABB< Float > getAABB() const
Returns the AABB of this body.
Definition body.hpp:366
virtual void integrate(Float dt) override
Integerates this body, meaning the linear velocity and angular velocity will be integrated into the p...
Definition body.hpp:362
The abstract base class of all Rigid Bodies that defines essential methods and members to be used in ...
Definition body.hpp:30
virtual void setStatic(bool static_)
Either make the body static or dynamic.
Definition body.hpp:144
void addLinearVel(const vec2 &vel)
applies a linear velocity to this body
Definition body.hpp:180
virtual vec2 getLocalPoint(const vec2 &worldPoint) const
Gets a world position thats space of this body and transforms into the local space of this body.
Definition body.hpp:162
Transform & transform()
Returns the REFERENCE transform of this body.
Definition body.hpp:64
const Transform & transform() const
Returns the CONST REFERENCE transform of this body.
Definition body.hpp:72
Float inverseMass() const
Returns the inverse mass of this body.
Definition body.hpp:198
void rotateBy(Float amount)
Rotates the body by amount.
Definition body.hpp:91
virtual vec2 getWorldPoint(const vec2 &localPoint) const
Gets a local position thats within the local space of this body and transforms into the world space.
Definition body.hpp:153
void setPos(const vec2 &pos)
Sets the position of this body to pos.
Definition body.hpp:102
BodyType bodyType() const
Returns the bodyType of this body, see enum BodyType.
Definition body.hpp:56
WorldBody(uint32_t id, BodyType bodyType)
constructs a new WorldBody
Definition body.hpp:41
virtual AABB< Float > getAABB() const =0
Returns the AABB of this body.
bool isStatic() const
Returns if the body is static, meaning it cannot be moved by forces or other bodies.
Definition body.hpp:135
virtual void integrate(Float dt)=0
Integerates this body, meaning the linear velocity and angular velocity will be integrated into the p...
void moveBy(const vec2 &amount)
Moves the body by amount.
Definition body.hpp:81
uint32_t id() const
Returns the id assigned to this body the physics world.
Definition body.hpp:48
void setRot(Float rot)
Sets the rotation of this body to rot.
Definition body.hpp:112
Float mass() const
Returns the mass of this body.
Definition body.hpp:189
virtual vec2 getWorldPos()
Returns the world position of this body.
Definition body.hpp:171
Allows collisions between different bodies to occur.
Definition world.hpp:188
contains various functions and classes that are used for both convience and/or functionality that may...
Definition math.hpp:203
Resolves the collision between two bodies using the impulse method.
Definition collide.hpp:397
Definition math.hpp:142