]> git.lizzy.rs Git - nothing.git/blob - src/game/level/rigid_bodies.c
0c2a0b93c3638a15123a5321218e249fe5f5b199
[nothing.git] / src / game / level / rigid_bodies.c
1 #include <stdlib.h>
2 #include <stdbool.h>
3
4 #include "system/lt.h"
5 #include "system/nth_alloc.h"
6 #include "system/stacktrace.h"
7 #include "game/camera.h"
8
9 #include "./rigid_bodies.h"
10
11 struct RigidBodies
12 {
13     Lt *lt;
14     size_t capacity;
15     size_t count;
16
17     Vec *positions;
18     Vec *velocities;
19     Vec *movements;
20     Vec *sizes;
21     Color *colors;
22     bool *grounded;
23     Vec *forces;
24 };
25
26 RigidBodies *create_rigid_bodies(size_t capacity)
27 {
28     Lt *lt = create_lt();
29     if (lt == NULL) {
30         return NULL;
31     }
32
33     RigidBodies *rigid_bodies = PUSH_LT(lt, nth_calloc(1, sizeof(RigidBodies)), free);
34     if (rigid_bodies == NULL) {
35         RETURN_LT(lt, NULL);
36     }
37     rigid_bodies->lt = lt;
38
39     rigid_bodies->capacity = capacity;
40     rigid_bodies->count = 0;
41
42     rigid_bodies->positions = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free);
43     if (rigid_bodies->positions == NULL) {
44         RETURN_LT(lt, NULL);
45     }
46
47     rigid_bodies->velocities = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free);
48     if (rigid_bodies->velocities == NULL) {
49         RETURN_LT(lt, NULL);
50     }
51
52     rigid_bodies->movements = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free);
53     if (rigid_bodies->movements == NULL) {
54         RETURN_LT(lt, NULL);
55     }
56
57     rigid_bodies->sizes = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free);
58     if (rigid_bodies->sizes == NULL) {
59         RETURN_LT(lt, NULL);
60     }
61
62     rigid_bodies->colors = PUSH_LT(lt, nth_calloc(capacity, sizeof(Color)), free);
63     if (rigid_bodies->colors == NULL) {
64         RETURN_LT(lt, NULL);
65     }
66
67     rigid_bodies->grounded = PUSH_LT(lt, nth_calloc(capacity, sizeof(bool)), free);
68     if (rigid_bodies->grounded == NULL) {
69         RETURN_LT(lt, NULL);
70     }
71
72     rigid_bodies->forces = PUSH_LT(lt, nth_calloc(capacity, sizeof(Vec)), free);
73     if (rigid_bodies->forces == NULL) {
74         RETURN_LT(lt, NULL);
75     }
76
77     return rigid_bodies;
78 }
79
80 void destroy_rigid_bodies(RigidBodies *rigid_bodies)
81 {
82     trace_assert(rigid_bodies);
83     RETURN_LT0(rigid_bodies->lt);
84 }
85
86 int rigid_bodies_update(RigidBodies *rigid_bodies,
87                         float delta_time)
88 {
89     trace_assert(rigid_bodies);
90     (void) delta_time;
91     /* TODO(#639): rigid_bodies_update is not implemented */
92     return 0;
93 }
94
95 int rigid_bodies_render(RigidBodies *rigid_bodies,
96                         Camera *camera)
97 {
98     trace_assert(rigid_bodies);
99     trace_assert(camera);
100
101     for (size_t i = 0; i < rigid_bodies->count; ++i) {
102         if (camera_fill_rect(
103                 camera,
104                 rect_from_vecs(
105                     rigid_bodies->positions[i],
106                     rigid_bodies->sizes[i]),
107                 rigid_bodies->colors[i]) < 0) {
108             return -1;
109         }
110     }
111
112     return 0;
113 }
114
115 RigidBodyId rigid_bodies_add(RigidBodies *rigid_bodies,
116                              Rect rect,
117                              Color color)
118 {
119     trace_assert(rigid_bodies);
120     trace_assert(rigid_bodies->count < rigid_bodies->capacity);
121
122     RigidBodyId id = rigid_bodies->count++;
123     rigid_bodies->positions[id] = vec(rect.x, rect.y);
124     rigid_bodies->sizes[id] = vec(rect.w, rect.h);
125     rigid_bodies->colors[id] = color;
126
127     return id;
128 }
129
130 Rect rigid_bodies_hitbox(const RigidBodies *rigid_bodies,
131                          RigidBodyId id)
132 {
133     trace_assert(rigid_bodies);
134     trace_assert(id < rigid_bodies->count);
135
136     return rect_from_vecs(rigid_bodies->positions[id],
137                           rigid_bodies->sizes[id]);
138 }
139
140 void rigid_bodies_move(RigidBodies *rigid_bodies,
141                        RigidBodyId id,
142                        Vec movement)
143 {
144     trace_assert(rigid_bodies);
145     trace_assert(id < rigid_bodies->count);
146
147     rigid_bodies->movements[id] = movement;
148 }
149
150 int rigid_bodies_touches_ground(const RigidBodies *rigid_bodies,
151                                 RigidBodyId id)
152 {
153     trace_assert(rigid_bodies);
154     trace_assert(id < rigid_bodies->count);
155
156     return rigid_bodies->grounded[id];
157 }
158
159 void rigid_bodies_apply_force(RigidBodies * rigid_bodies,
160                               RigidBodyId id,
161                               Vec force)
162 {
163     trace_assert(rigid_bodies);
164     trace_assert(id < rigid_bodies->count);
165
166     rigid_bodies->forces[id] = vec_sum(rigid_bodies->forces[id], force);
167 }
168
169 void rigid_bodies_transform_velocity(RigidBodies *rigid_bodies,
170                                      RigidBodyId id,
171                                      mat3x3 trans_mat)
172 {
173     trace_assert(rigid_bodies);
174     trace_assert(id < rigid_bodies->count);
175
176     rigid_bodies->velocities[id] = point_mat3x3_product(
177         rigid_bodies->velocities[id],
178         trans_mat);
179 }
180
181 void rigid_bodies_teleport_to(RigidBodies *rigid_bodies,
182                               RigidBodyId id,
183                               Vec position)
184 {
185     trace_assert(rigid_bodies);
186     trace_assert(id < rigid_bodies->count);
187
188     rigid_bodies->positions[id] = position;
189 }
190
191 void rigid_bodies_damper(RigidBodies *rigid_bodies,
192                          RigidBodyId id,
193                          Vec v)
194 {
195     trace_assert(rigid_bodies);
196     trace_assert(id < rigid_bodies->count);
197
198     rigid_bodies_apply_force(
199         rigid_bodies, id,
200         vec(
201             rigid_bodies->velocities[id].x * v.x,
202             rigid_bodies->velocities[id].y * v.y));
203 }