Mirai's Miscellaneous Misadventures

M39 / core / collisions.c

1// copyright 2023 zamfofex
2// license: AGPLv3 or later
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}