Mirai's Miscellaneous Misadventures
M39 / core / collisions.c
#include <mimimi/compound-behaviors.h>
#include <mimimi/collisions.h>
#include <mimimi/allocators.h>
#include <mimimi/geometry.h>
struct mimimi_collision
{
int count;
struct mimimi_position **positions;
int strength;
int proximity;
int height;
int tolerance;
};
static void mimimi_collide(void *data)
{
struct mimimi_collision *collision = data;
struct mimimi_position **positions = collision->positions;
for (int i = 0 ; i < collision->count ; i++)
{
int a = positions[i]->x;
int k = i;
for (int j = i - 1 ; j >= 0 ; j--)
{
int b = positions[j]->x;
if (a <= b) break;
struct mimimi_position *position = positions[k];
positions[k] = positions[j];
positions[j] = position;
k = j;
}
}
for (int i = 1 ; i < collision->count ; i++)
{
int y = positions[i]->y - positions[i - 1]->y;
if (y > collision->height) continue;
if (y < -collision->height) continue;
int *a = &positions[i]->x;
int *b = &positions[i - 1]->x;
int d = *b - *a;
if (d < collision->proximity)
{
int push = collision->strength / (d + collision->tolerance);
*a -= push;
*b += push;
}
}
}
struct mimimi_behavior *mimimi_collision(int count, struct mimimi_position **positions, int proximity, int height, int strength, int tolerance, struct mimimi_allocator *allocator)
{
struct mimimi_behavior *compound = mimimi_compound_behavior(allocator);
struct mimimi_collision *collision = mimimi_compound_allocate(compound, sizeof *collision, allocator);
collision->count = count;
collision->positions = positions;
collision->strength = strength;
collision->proximity = proximity;
collision->height = height;
collision->tolerance = tolerance;
mimimi_compound(compound, mimimi_function(collision, &mimimi_collide, allocator));
return compound;
}