chipmunk 5.3.4.0-x86-mingw32 → 5.3.4.2-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/README +33 -13
- data/Rakefile +20 -7
- data/ext/chipmunk/extconf.rb +55 -12
- data/ext/chipmunk/rb_chipmunk.c +92 -98
- data/ext/chipmunk/rb_chipmunk.h +44 -34
- data/ext/chipmunk/rb_cpArbiter.c +135 -98
- data/ext/chipmunk/rb_cpBB.c +84 -101
- data/ext/chipmunk/rb_cpBody.c +219 -241
- data/ext/chipmunk/rb_cpConstraint.c +173 -185
- data/ext/chipmunk/rb_cpShape.c +347 -251
- data/ext/chipmunk/rb_cpSpace.c +376 -408
- data/ext/chipmunk/rb_cpVect.c +132 -170
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk.h +163 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk_ffi.h +59 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk_private.h +49 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk_types.h +151 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk_unsafe.h +54 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpConstraint.h +105 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpDampedRotarySpring.h +46 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpDampedSpring.h +53 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpGearJoint.h +41 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpGrooveJoint.h +48 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpPinJoint.h +43 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpPivotJoint.h +42 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpRatchetJoint.h +40 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpRotaryLimitJoint.h +39 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpSimpleMotor.h +37 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpSlideJoint.h +44 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/util.h +134 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpArbiter.h +188 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpArray.h +49 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpBB.h +74 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpBody.h +219 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpCollision.h +28 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpHashSet.h +82 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpPolyShape.h +103 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpShape.h +177 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpSpace.h +206 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpSpaceHash.h +110 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpVect.h +207 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/chipmunk.c +151 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpConstraint.c +54 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpDampedRotarySpring.c +105 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpDampedSpring.c +115 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpGearJoint.c +113 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpGrooveJoint.c +161 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpPinJoint.c +116 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpPivotJoint.c +114 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpRatchetJoint.c +126 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpRotaryLimitJoint.c +120 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpSimpleMotor.c +97 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpSlideJoint.c +129 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpArbiter.c +280 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpArray.c +143 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpBB.c +47 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpBody.c +192 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpCollision.c +411 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpHashSet.c +253 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpPolyShape.c +240 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpShape.c +405 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpace.c +499 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpaceComponent.c +279 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpaceHash.c +534 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpaceQuery.c +246 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpaceStep.c +398 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpVect.c +71 -0
- data/ext/chipmunk/vendor/chipmunk-5.3.4/src/prime.h +68 -0
- data/lib/1.9/chipmunk.so +0 -0
- data/lib/chipmunk.rb +19 -8
- metadata +84 -42
- data/lib/1.8/chipmunk.so +0 -0
@@ -0,0 +1,253 @@
|
|
1
|
+
/* Copyright (c) 2007 Scott Lembcke
|
2
|
+
*
|
3
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
* of this software and associated documentation files (the "Software"), to deal
|
5
|
+
* in the Software without restriction, including without limitation the rights
|
6
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
* copies of the Software, and to permit persons to whom the Software is
|
8
|
+
* furnished to do so, subject to the following conditions:
|
9
|
+
*
|
10
|
+
* The above copyright notice and this permission notice shall be included in
|
11
|
+
* all copies or substantial portions of the Software.
|
12
|
+
*
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
* SOFTWARE.
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include <stdlib.h>
|
23
|
+
#include <assert.h>
|
24
|
+
|
25
|
+
#include "chipmunk_private.h"
|
26
|
+
#include "prime.h"
|
27
|
+
|
28
|
+
static void freeWrap(void *ptr, void *unused){cpfree(ptr);}
|
29
|
+
|
30
|
+
void
|
31
|
+
cpHashSetDestroy(cpHashSet *set)
|
32
|
+
{
|
33
|
+
// Free the table.
|
34
|
+
cpfree(set->table);
|
35
|
+
|
36
|
+
cpArrayEach(set->allocatedBuffers, freeWrap, NULL);
|
37
|
+
cpArrayFree(set->allocatedBuffers);
|
38
|
+
}
|
39
|
+
|
40
|
+
void
|
41
|
+
cpHashSetFree(cpHashSet *set)
|
42
|
+
{
|
43
|
+
if(set){
|
44
|
+
cpHashSetDestroy(set);
|
45
|
+
cpfree(set);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
cpHashSet *
|
50
|
+
cpHashSetAlloc(void)
|
51
|
+
{
|
52
|
+
return (cpHashSet *)cpcalloc(1, sizeof(cpHashSet));
|
53
|
+
}
|
54
|
+
|
55
|
+
cpHashSet *
|
56
|
+
cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)
|
57
|
+
{
|
58
|
+
set->size = next_prime(size);
|
59
|
+
set->entries = 0;
|
60
|
+
|
61
|
+
set->eql = eqlFunc;
|
62
|
+
set->trans = trans;
|
63
|
+
|
64
|
+
set->default_value = NULL;
|
65
|
+
|
66
|
+
set->table = (cpHashSetBin **)cpcalloc(set->size, sizeof(cpHashSetBin *));
|
67
|
+
set->pooledBins = NULL;
|
68
|
+
|
69
|
+
set->allocatedBuffers = cpArrayNew(0);
|
70
|
+
|
71
|
+
return set;
|
72
|
+
}
|
73
|
+
|
74
|
+
cpHashSet *
|
75
|
+
cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)
|
76
|
+
{
|
77
|
+
return cpHashSetInit(cpHashSetAlloc(), size, eqlFunc, trans);
|
78
|
+
}
|
79
|
+
|
80
|
+
static int
|
81
|
+
setIsFull(cpHashSet *set)
|
82
|
+
{
|
83
|
+
return (set->entries >= set->size);
|
84
|
+
}
|
85
|
+
|
86
|
+
static void
|
87
|
+
cpHashSetResize(cpHashSet *set)
|
88
|
+
{
|
89
|
+
// Get the next approximate doubled prime.
|
90
|
+
int newSize = next_prime(set->size + 1);
|
91
|
+
// Allocate a new table.
|
92
|
+
cpHashSetBin **newTable = (cpHashSetBin **)cpcalloc(newSize, sizeof(cpHashSetBin *));
|
93
|
+
|
94
|
+
// Iterate over the chains.
|
95
|
+
for(int i=0; i<set->size; i++){
|
96
|
+
// Rehash the bins into the new table.
|
97
|
+
cpHashSetBin *bin = set->table[i];
|
98
|
+
while(bin){
|
99
|
+
cpHashSetBin *next = bin->next;
|
100
|
+
|
101
|
+
int idx = bin->hash%newSize;
|
102
|
+
bin->next = newTable[idx];
|
103
|
+
newTable[idx] = bin;
|
104
|
+
|
105
|
+
bin = next;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
cpfree(set->table);
|
110
|
+
|
111
|
+
set->table = newTable;
|
112
|
+
set->size = newSize;
|
113
|
+
}
|
114
|
+
|
115
|
+
static inline void
|
116
|
+
recycleBin(cpHashSet *set, cpHashSetBin *bin)
|
117
|
+
{
|
118
|
+
bin->next = set->pooledBins;
|
119
|
+
set->pooledBins = bin;
|
120
|
+
bin->elt = NULL;
|
121
|
+
}
|
122
|
+
|
123
|
+
static cpHashSetBin *
|
124
|
+
getUnusedBin(cpHashSet *set)
|
125
|
+
{
|
126
|
+
cpHashSetBin *bin = set->pooledBins;
|
127
|
+
|
128
|
+
if(bin){
|
129
|
+
set->pooledBins = bin->next;
|
130
|
+
return bin;
|
131
|
+
} else {
|
132
|
+
// Pool is exhausted, make more
|
133
|
+
int count = CP_BUFFER_BYTES/sizeof(cpHashSetBin);
|
134
|
+
cpAssert(count, "Buffer size is too small.");
|
135
|
+
|
136
|
+
cpHashSetBin *buffer = (cpHashSetBin *)cpmalloc(CP_BUFFER_BYTES);
|
137
|
+
cpArrayPush(set->allocatedBuffers, buffer);
|
138
|
+
|
139
|
+
// push all but the first one, return the first instead
|
140
|
+
for(int i=1; i<count; i++) recycleBin(set, buffer + i);
|
141
|
+
return buffer;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
void *
|
146
|
+
cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data)
|
147
|
+
{
|
148
|
+
int idx = hash%set->size;
|
149
|
+
|
150
|
+
// Find the bin with the matching element.
|
151
|
+
cpHashSetBin *bin = set->table[idx];
|
152
|
+
while(bin && !set->eql(ptr, bin->elt))
|
153
|
+
bin = bin->next;
|
154
|
+
|
155
|
+
// Create it necessary.
|
156
|
+
if(!bin){
|
157
|
+
bin = getUnusedBin(set);
|
158
|
+
bin->hash = hash;
|
159
|
+
bin->elt = set->trans(ptr, data); // Transform the pointer.
|
160
|
+
|
161
|
+
bin->next = set->table[idx];
|
162
|
+
set->table[idx] = bin;
|
163
|
+
|
164
|
+
set->entries++;
|
165
|
+
|
166
|
+
// Resize the set if it's full.
|
167
|
+
if(setIsFull(set))
|
168
|
+
cpHashSetResize(set);
|
169
|
+
}
|
170
|
+
|
171
|
+
return bin->elt;
|
172
|
+
}
|
173
|
+
|
174
|
+
void *
|
175
|
+
cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)
|
176
|
+
{
|
177
|
+
int idx = hash%set->size;
|
178
|
+
|
179
|
+
// Pointer to the previous bin pointer.
|
180
|
+
cpHashSetBin **prev_ptr = &set->table[idx];
|
181
|
+
// Pointer the the current bin.
|
182
|
+
cpHashSetBin *bin = set->table[idx];
|
183
|
+
|
184
|
+
// Find the bin
|
185
|
+
while(bin && !set->eql(ptr, bin->elt)){
|
186
|
+
prev_ptr = &bin->next;
|
187
|
+
bin = bin->next;
|
188
|
+
}
|
189
|
+
|
190
|
+
// Remove it if it exists.
|
191
|
+
if(bin){
|
192
|
+
// Update the previous bin pointer to point to the next bin.
|
193
|
+
(*prev_ptr) = bin->next;
|
194
|
+
set->entries--;
|
195
|
+
|
196
|
+
void *return_value = bin->elt;
|
197
|
+
|
198
|
+
recycleBin(set, bin);
|
199
|
+
|
200
|
+
return return_value;
|
201
|
+
}
|
202
|
+
|
203
|
+
return NULL;
|
204
|
+
}
|
205
|
+
|
206
|
+
void *
|
207
|
+
cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr)
|
208
|
+
{
|
209
|
+
int idx = hash%set->size;
|
210
|
+
cpHashSetBin *bin = set->table[idx];
|
211
|
+
while(bin && !set->eql(ptr, bin->elt))
|
212
|
+
bin = bin->next;
|
213
|
+
|
214
|
+
return (bin ? bin->elt : set->default_value);
|
215
|
+
}
|
216
|
+
|
217
|
+
void
|
218
|
+
cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data)
|
219
|
+
{
|
220
|
+
for(int i=0; i<set->size; i++){
|
221
|
+
cpHashSetBin *bin = set->table[i];
|
222
|
+
while(bin){
|
223
|
+
cpHashSetBin *next = bin->next;
|
224
|
+
func(bin->elt, data);
|
225
|
+
bin = next;
|
226
|
+
}
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
void
|
231
|
+
cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data)
|
232
|
+
{
|
233
|
+
// Iterate over all the chains.
|
234
|
+
for(int i=0; i<set->size; i++){
|
235
|
+
// The rest works similarly to cpHashSetRemove() above.
|
236
|
+
cpHashSetBin **prev_ptr = &set->table[i];
|
237
|
+
cpHashSetBin *bin = set->table[i];
|
238
|
+
while(bin){
|
239
|
+
cpHashSetBin *next = bin->next;
|
240
|
+
|
241
|
+
if(func(bin->elt, data)){
|
242
|
+
prev_ptr = &bin->next;
|
243
|
+
} else {
|
244
|
+
(*prev_ptr) = next;
|
245
|
+
|
246
|
+
set->entries--;
|
247
|
+
recycleBin(set, bin);
|
248
|
+
}
|
249
|
+
|
250
|
+
bin = next;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
}
|
@@ -0,0 +1,240 @@
|
|
1
|
+
/* Copyright (c) 2007 Scott Lembcke
|
2
|
+
*
|
3
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
* of this software and associated documentation files (the "Software"), to deal
|
5
|
+
* in the Software without restriction, including without limitation the rights
|
6
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
* copies of the Software, and to permit persons to whom the Software is
|
8
|
+
* furnished to do so, subject to the following conditions:
|
9
|
+
*
|
10
|
+
* The above copyright notice and this permission notice shall be included in
|
11
|
+
* all copies or substantial portions of the Software.
|
12
|
+
*
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
* SOFTWARE.
|
20
|
+
*/
|
21
|
+
|
22
|
+
#include <stdlib.h>
|
23
|
+
|
24
|
+
#include "chipmunk_private.h"
|
25
|
+
#include "chipmunk_unsafe.h"
|
26
|
+
|
27
|
+
cpPolyShape *
|
28
|
+
cpPolyShapeAlloc(void)
|
29
|
+
{
|
30
|
+
return (cpPolyShape *)cpcalloc(1, sizeof(cpPolyShape));
|
31
|
+
}
|
32
|
+
|
33
|
+
static void
|
34
|
+
cpPolyShapeTransformVerts(cpPolyShape *poly, cpVect p, cpVect rot)
|
35
|
+
{
|
36
|
+
cpVect *src = poly->verts;
|
37
|
+
cpVect *dst = poly->tVerts;
|
38
|
+
|
39
|
+
for(int i=0; i<poly->numVerts; i++)
|
40
|
+
dst[i] = cpvadd(p, cpvrotate(src[i], rot));
|
41
|
+
}
|
42
|
+
|
43
|
+
static void
|
44
|
+
cpPolyShapeTransformAxes(cpPolyShape *poly, cpVect p, cpVect rot)
|
45
|
+
{
|
46
|
+
cpPolyShapeAxis *src = poly->axes;
|
47
|
+
cpPolyShapeAxis *dst = poly->tAxes;
|
48
|
+
|
49
|
+
for(int i=0; i<poly->numVerts; i++){
|
50
|
+
cpVect n = cpvrotate(src[i].n, rot);
|
51
|
+
dst[i].n = n;
|
52
|
+
dst[i].d = cpvdot(p, n) + src[i].d;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
static cpBB
|
57
|
+
cpPolyShapeCacheData(cpShape *shape, cpVect p, cpVect rot)
|
58
|
+
{
|
59
|
+
cpPolyShape *poly = (cpPolyShape *)shape;
|
60
|
+
|
61
|
+
cpFloat l, b, r, t;
|
62
|
+
|
63
|
+
cpPolyShapeTransformAxes(poly, p, rot);
|
64
|
+
cpPolyShapeTransformVerts(poly, p, rot);
|
65
|
+
|
66
|
+
cpVect *verts = poly->tVerts;
|
67
|
+
l = r = verts[0].x;
|
68
|
+
b = t = verts[0].y;
|
69
|
+
|
70
|
+
// TODO do as part of cpPolyShapeTransformVerts?
|
71
|
+
for(int i=1; i<poly->numVerts; i++){
|
72
|
+
cpVect v = verts[i];
|
73
|
+
|
74
|
+
l = cpfmin(l, v.x);
|
75
|
+
r = cpfmax(r, v.x);
|
76
|
+
|
77
|
+
b = cpfmin(b, v.y);
|
78
|
+
t = cpfmax(t, v.y);
|
79
|
+
}
|
80
|
+
|
81
|
+
return cpBBNew(l, b, r, t);
|
82
|
+
}
|
83
|
+
|
84
|
+
static void
|
85
|
+
cpPolyShapeDestroy(cpShape *shape)
|
86
|
+
{
|
87
|
+
cpPolyShape *poly = (cpPolyShape *)shape;
|
88
|
+
|
89
|
+
cpfree(poly->verts);
|
90
|
+
cpfree(poly->tVerts);
|
91
|
+
|
92
|
+
cpfree(poly->axes);
|
93
|
+
cpfree(poly->tAxes);
|
94
|
+
}
|
95
|
+
|
96
|
+
static cpBool
|
97
|
+
cpPolyShapePointQuery(cpShape *shape, cpVect p){
|
98
|
+
return cpBBcontainsVect(shape->bb, p) && cpPolyShapeContainsVert((cpPolyShape *)shape, p);
|
99
|
+
}
|
100
|
+
|
101
|
+
static void
|
102
|
+
cpPolyShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)
|
103
|
+
{
|
104
|
+
cpPolyShape *poly = (cpPolyShape *)shape;
|
105
|
+
cpPolyShapeAxis *axes = poly->tAxes;
|
106
|
+
cpVect *verts = poly->tVerts;
|
107
|
+
int numVerts = poly->numVerts;
|
108
|
+
|
109
|
+
for(int i=0; i<numVerts; i++){
|
110
|
+
cpVect n = axes[i].n;
|
111
|
+
cpFloat an = cpvdot(a, n);
|
112
|
+
if(axes[i].d > an) continue;
|
113
|
+
|
114
|
+
cpFloat bn = cpvdot(b, n);
|
115
|
+
cpFloat t = (axes[i].d - an)/(bn - an);
|
116
|
+
if(t < 0.0f || 1.0f < t) continue;
|
117
|
+
|
118
|
+
cpVect point = cpvlerp(a, b, t);
|
119
|
+
cpFloat dt = -cpvcross(n, point);
|
120
|
+
cpFloat dtMin = -cpvcross(n, verts[i]);
|
121
|
+
cpFloat dtMax = -cpvcross(n, verts[(i+1)%numVerts]);
|
122
|
+
|
123
|
+
if(dtMin <= dt && dt <= dtMax){
|
124
|
+
info->shape = shape;
|
125
|
+
info->t = t;
|
126
|
+
info->n = n;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
static const cpShapeClass polyClass = {
|
132
|
+
CP_POLY_SHAPE,
|
133
|
+
cpPolyShapeCacheData,
|
134
|
+
cpPolyShapeDestroy,
|
135
|
+
cpPolyShapePointQuery,
|
136
|
+
cpPolyShapeSegmentQuery,
|
137
|
+
};
|
138
|
+
|
139
|
+
cpBool
|
140
|
+
cpPolyValidate(const cpVect *verts, const int numVerts)
|
141
|
+
{
|
142
|
+
for(int i=0; i<numVerts; i++){
|
143
|
+
cpVect a = verts[i];
|
144
|
+
cpVect b = verts[(i+1)%numVerts];
|
145
|
+
cpVect c = verts[(i+2)%numVerts];
|
146
|
+
|
147
|
+
if(cpvcross(cpvsub(b, a), cpvsub(c, b)) > 0.0f)
|
148
|
+
return cpFalse;
|
149
|
+
}
|
150
|
+
|
151
|
+
return cpTrue;
|
152
|
+
}
|
153
|
+
|
154
|
+
int
|
155
|
+
cpPolyShapeGetNumVerts(cpShape *shape)
|
156
|
+
{
|
157
|
+
cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
|
158
|
+
return ((cpPolyShape *)shape)->numVerts;
|
159
|
+
}
|
160
|
+
|
161
|
+
cpVect
|
162
|
+
cpPolyShapeGetVert(cpShape *shape, int idx)
|
163
|
+
{
|
164
|
+
cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
|
165
|
+
cpAssert(0 <= idx && idx < cpPolyShapeGetNumVerts(shape), "Index out of range.");
|
166
|
+
|
167
|
+
return ((cpPolyShape *)shape)->verts[idx];
|
168
|
+
}
|
169
|
+
|
170
|
+
|
171
|
+
static void
|
172
|
+
setUpVerts(cpPolyShape *poly, int numVerts, cpVect *verts, cpVect offset)
|
173
|
+
{
|
174
|
+
poly->numVerts = numVerts;
|
175
|
+
|
176
|
+
poly->verts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));
|
177
|
+
poly->tVerts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));
|
178
|
+
poly->axes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));
|
179
|
+
poly->tAxes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));
|
180
|
+
|
181
|
+
for(int i=0; i<numVerts; i++){
|
182
|
+
cpVect a = cpvadd(offset, verts[i]);
|
183
|
+
cpVect b = cpvadd(offset, verts[(i+1)%numVerts]);
|
184
|
+
cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));
|
185
|
+
|
186
|
+
poly->verts[i] = a;
|
187
|
+
poly->axes[i].n = n;
|
188
|
+
poly->axes[i].d = cpvdot(n, a);
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
cpPolyShape *
|
193
|
+
cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset)
|
194
|
+
{
|
195
|
+
// Fail if the user attempts to pass a concave poly, or a bad winding.
|
196
|
+
cpAssert(cpPolyValidate(verts, numVerts), "Polygon is concave or has a reversed winding.");
|
197
|
+
|
198
|
+
setUpVerts(poly, numVerts, verts, offset);
|
199
|
+
cpShapeInit((cpShape *)poly, &polyClass, body);
|
200
|
+
|
201
|
+
return poly;
|
202
|
+
}
|
203
|
+
|
204
|
+
cpShape *
|
205
|
+
cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset)
|
206
|
+
{
|
207
|
+
return (cpShape *)cpPolyShapeInit(cpPolyShapeAlloc(), body, numVerts, verts, offset);
|
208
|
+
}
|
209
|
+
|
210
|
+
cpPolyShape *
|
211
|
+
cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height)
|
212
|
+
{
|
213
|
+
cpFloat hw = width/2.0f;
|
214
|
+
cpFloat hh = height/2.0f;
|
215
|
+
|
216
|
+
cpVect verts[] = {
|
217
|
+
cpv(-hw,-hh),
|
218
|
+
cpv(-hw, hh),
|
219
|
+
cpv( hw, hh),
|
220
|
+
cpv( hw,-hh),
|
221
|
+
};
|
222
|
+
|
223
|
+
return cpPolyShapeInit(poly, body, 4, verts, cpvzero);
|
224
|
+
}
|
225
|
+
|
226
|
+
cpShape *
|
227
|
+
cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height)
|
228
|
+
{
|
229
|
+
return (cpShape *)cpBoxShapeInit(cpPolyShapeAlloc(), body, width, height);
|
230
|
+
}
|
231
|
+
|
232
|
+
// Unsafe API (chipmunk_unsafe.h)
|
233
|
+
|
234
|
+
void
|
235
|
+
cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset)
|
236
|
+
{
|
237
|
+
cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
|
238
|
+
cpPolyShapeDestroy(shape);
|
239
|
+
setUpVerts((cpPolyShape *)shape, numVerts, verts, offset);
|
240
|
+
}
|