Mirai's Miscellaneous Misadventures
M39 / core / collisions.c
1
2
3
4#include <mimimi/compound-behaviors.h>
5#include <mimimi/collisions.h>
6#include <mimimi/allocators.h>
7#include <mimimi/geometry.h>
8
9struct mimimi_collision
10{
11 int count;
12 struct mimimi_position **positions;
13 int strength;
14 int proximity;
15 int height;
16 int tolerance;
17};
18
19static void mimimi_collide(void *data)
20{
21 struct mimimi_collision *collision = data;
22 struct mimimi_position **positions = collision->positions;
23
24 for (int i = 0 ; i < collision->count ; i++)
25 {
26 int a = positions[i]->x;
27
28 int k = i;
29 for (int j = i - 1 ; j >= 0 ; j--)
30 {
31 int b = positions[j]->x;
32 if (a <= b) break;
33
34 struct mimimi_position *position = positions[k];
35 positions[k] = positions[j];
36 positions[j] = position;
37
38 k = j;
39 }
40 }
41
42 for (int i = 1 ; i < collision->count ; i++)
43 {
44 int y = positions[i]->y - positions[i - 1]->y;
45 if (y > collision->height) continue;
46 if (y < -collision->height) continue;
47
48 int *a = &positions[i]->x;
49 int *b = &positions[i - 1]->x;
50 int d = *b - *a;
51 if (d < collision->proximity)
52 {
53 int push = collision->strength / (d + collision->tolerance);
54 *a -= push;
55 *b += push;
56 }
57 }
58}
59
60struct mimimi_behavior *mimimi_collision(int count, struct mimimi_position **positions, int proximity, int height, int strength, int tolerance, struct mimimi_allocator *allocator)
61{
62 struct mimimi_behavior *compound = mimimi_compound_behavior(allocator);
63 struct mimimi_collision *collision = mimimi_compound_allocate(compound, sizeof *collision, allocator);
64 collision->count = count;
65 collision->positions = positions;
66 collision->strength = strength;
67 collision->proximity = proximity;
68 collision->height = height;
69 collision->tolerance = tolerance;
70 mimimi_compound(compound, mimimi_function(collision, &mimimi_collide, allocator));
71 return compound;
72}