summaryrefslogtreecommitdiffhomepage
path: root/src/collision/rodeo_collision.c
blob: e4791bfdbe5fd8ce4ea9977dd62cf1254a5b94f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "rodeo/collision.h"
#include "rodeo/collision_t.h"
#include <stdio.h>

bool detect_collision(
	const rodeo_collision_2d_world_item_t *a,
	const rodeo_collision_2d_world_item_t *b
)
{
	return !(a->x+a->dx > b->x+b->dx + b->width ||
			b->x+b->dx > a->x+a->dx + a->width ||
			a->y+a->dy > b->y+b->dy + b->height ||
			b->y+b->dy > a->y+a->dy + a->height);
}

rodeo_collision_2d_world_t
rodeo_collision_2d_world_create(void)
{
	return cvec_collision_2d_world_item_init();
}

void
rodeo_collision_2d_world_destroy(
rodeo_collision_2d_world_t *world
)
{
	cvec_collision_2d_world_item_drop(world);
}

cvec_collision_2d_world_item_value*
rodeo_collision_2d_world_item_create(
	rodeo_collision_2d_world_t *world,
	rodeo_collision_2d_world_item_t item_params
)
{
	static uint32_t next_id = 0;
	item_params.id.id = next_id++;
	item_params.id.world = world;
	cvec_collision_2d_world_item_value* new_item = cvec_collision_2d_world_item_push(world, item_params);
	
	return new_item;
}

void
rodeo_collision_2d_world_item_destroy(
	cvec_collision_2d_world_item_value* cvec_value
)
{
	
	cvec_collision_2d_world_item_value temp = *cvec_collision_2d_world_item_back(cvec_value->id.world);
	*cvec_collision_2d_world_item_back(cvec_value->id.world) = *cvec_value;
	*cvec_value = temp;
	cvec_collision_2d_world_item_pop(cvec_value->id.world);
}

void
rodeo_collision_2d_world_item_destroy_by_id(
	world_id id
)
{
	rodeo_collision_2d_world_item_t* item = rodeo_collision_2d_world_item_get_by_id(id);
	rodeo_collision_2d_world_item_destroy(item);
}

rodeo_collision_2d_world_item_t*
rodeo_collision_2d_world_item_get_by_id(
	world_id id
)
{
	c_foreach(i, cvec_collision_2d_world_item, *id.world) {
		if (i.ref->id.id == id.id) {
			return i.ref;
		}
	}
	return NULL;
}

void
rodeo_collision_2d_world_compare_self(
	rodeo_collision_2d_world_t *world,
	void (*resolve)(
		rodeo_collision_2d_world_item_t *a,
		rodeo_collision_2d_world_item_t *b
	)
)
{
	c_foreach(i, cvec_collision_2d_world_item, *world) {
		c_foreach(j, cvec_collision_2d_world_item, cvec_collision_2d_world_item_advance(i, 1), cvec_collision_2d_world_item_end(world)) {
			if (detect_collision(i.ref, j.ref)) {
				resolve(i.ref, j.ref);
			}
		}
	}
}

void
rodeo_collision_2d_world_compare_other(
	rodeo_collision_2d_world_t *world_a,
	rodeo_collision_2d_world_t *world_b,
	void (*resolve)(
		rodeo_collision_2d_world_item_t *a,
		rodeo_collision_2d_world_item_t *b
	)
)
{
	c_foreach(i, cvec_collision_2d_world_item, *world_a) {
		c_foreach(j, cvec_collision_2d_world_item, *world_b) {
			if (detect_collision(i.ref, j.ref)) {
				resolve(i.ref, j.ref);
			}
		}
	}
}


int rodeo_collision_2d_item_cmp(
	const rodeo_collision_2d_world_item_t* a,
	const rodeo_collision_2d_world_item_t* b
)
{
	if (a->id.id == b->id.id) {
		return 0;
	} else {
		return a->id.id > b->id.id ? 1 : -1;
	}
}