Line data Source code
1 : /*
2 : * Copyright (C) 2025 aeml
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 : */
17 :
18 : #pragma once
19 :
20 : #include <algorithm>
21 : #include <cstdint>
22 :
23 : namespace physics
24 : {
25 : struct TransformComponent
26 : {
27 : float x{0.0f};
28 : float y{0.0f};
29 : float rotation{0.0f};
30 : };
31 :
32 : struct RigidBodyComponent
33 : {
34 : float vx{0.0f};
35 : float vy{0.0f};
36 : float lastX{0.0f}; // For PBD
37 : float lastY{0.0f}; // For PBD
38 : float lastAngle{0.0f};
39 : float mass{1.0f};
40 : float invMass{1.0f}; // 1.0 / mass, 0.0 for static bodies
41 : float inertia{1.0f};
42 : float invInertia{1.0f};
43 : float restitution{0.5f}; // Bounciness [0, 1]
44 : float friction{0.5f}; // Friction coefficient [0, 1]
45 : float angularVelocity{0.0f};
46 : float torque{0.0f};
47 : float angularFriction{0.5f};
48 : float angularDrag{0.0f};
49 : };
50 :
51 : // Simple environment-wide forces for weather-like simulations.
52 : struct EnvironmentForces
53 : {
54 : float gravityY{-9.81f}; // downward acceleration
55 : float windX{0.0f}; // horizontal wind
56 : float windY{0.0f}; // vertical wind / updrafts
57 : float drag{0.0f}; // linear drag coefficient
58 : };
59 :
60 : struct DistanceJointComponent
61 : {
62 : std::uint32_t entityA;
63 : std::uint32_t entityB;
64 : float targetDistance;
65 : float compliance{0.0f}; // 0 = rigid, >0 = soft (inverse stiffness)
66 : };
67 :
68 : // Axis-aligned bounding box for simple collision tests.
69 : struct AABBComponent
70 : {
71 : float minX{0.0f};
72 : float minY{0.0f};
73 : float maxX{0.0f};
74 : float maxY{0.0f};
75 : };
76 :
77 : struct CircleColliderComponent
78 : {
79 : float radius{1.0f};
80 : float offsetX{0.0f};
81 : float offsetY{0.0f};
82 : };
83 :
84 1908 : inline void ConfigureCircleInertia(RigidBodyComponent& body, float radius)
85 : {
86 1908 : if (body.mass <= 0.0f || radius <= 0.0f)
87 : {
88 0 : body.inertia = 0.0f;
89 0 : body.invInertia = 0.0f;
90 0 : return;
91 : }
92 1908 : const float r = radius;
93 1908 : body.inertia = 0.5f * body.mass * r * r;
94 1908 : body.invInertia = body.inertia > 0.0f ? 1.0f / body.inertia : 0.0f;
95 : }
96 :
97 324 : inline void ConfigureBoxInertia(RigidBodyComponent& body, float width, float height)
98 : {
99 324 : if (body.mass <= 0.0f)
100 : {
101 0 : body.inertia = 0.0f;
102 0 : body.invInertia = 0.0f;
103 0 : return;
104 : }
105 324 : const float w = width;
106 324 : const float h = height;
107 324 : body.inertia = (body.mass / 12.0f) * (w * w + h * h);
108 324 : body.invInertia = body.inertia > 0.0f ? 1.0f / body.inertia : 0.0f;
109 : }
110 : }
|