chipmunk 5.3.4.5 → 6.1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/ext/chipmunk/chipmunk.c +199 -28
  2. data/ext/chipmunk/chipmunk.h +123 -68
  3. data/ext/chipmunk/chipmunk_ffi.h +129 -11
  4. data/ext/chipmunk/chipmunk_private.h +232 -16
  5. data/ext/chipmunk/chipmunk_types.h +94 -30
  6. data/ext/chipmunk/chipmunk_unsafe.h +12 -3
  7. data/ext/chipmunk/constraints/cpConstraint.h +90 -34
  8. data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
  9. data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
  10. data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
  11. data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
  12. data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
  13. data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
  14. data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
  15. data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
  16. data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
  17. data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
  18. data/ext/chipmunk/constraints/util.h +36 -44
  19. data/ext/chipmunk/cpArbiter.c +159 -94
  20. data/ext/chipmunk/cpArbiter.h +135 -129
  21. data/ext/chipmunk/cpArray.c +37 -56
  22. data/ext/chipmunk/cpBB.c +1 -12
  23. data/ext/chipmunk/cpBB.h +80 -18
  24. data/ext/chipmunk/cpBBTree.c +891 -0
  25. data/ext/chipmunk/cpBody.c +185 -47
  26. data/ext/chipmunk/cpBody.h +156 -124
  27. data/ext/chipmunk/cpCollision.c +126 -115
  28. data/ext/chipmunk/cpConstraint.c +10 -6
  29. data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
  30. data/ext/chipmunk/cpDampedSpring.c +25 -18
  31. data/ext/chipmunk/cpGearJoint.c +23 -17
  32. data/ext/chipmunk/cpGrooveJoint.c +26 -22
  33. data/ext/chipmunk/cpHashSet.c +51 -51
  34. data/ext/chipmunk/cpPinJoint.c +26 -19
  35. data/ext/chipmunk/cpPivotJoint.c +23 -19
  36. data/ext/chipmunk/cpPolyShape.c +93 -69
  37. data/ext/chipmunk/cpPolyShape.h +33 -69
  38. data/ext/chipmunk/cpRatchetJoint.c +26 -21
  39. data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
  40. data/ext/chipmunk/cpShape.c +122 -133
  41. data/ext/chipmunk/cpShape.h +146 -95
  42. data/ext/chipmunk/cpSimpleMotor.c +24 -17
  43. data/ext/chipmunk/cpSlideJoint.c +28 -26
  44. data/ext/chipmunk/cpSpace.c +251 -196
  45. data/ext/chipmunk/cpSpace.h +173 -103
  46. data/ext/chipmunk/cpSpaceComponent.c +236 -159
  47. data/ext/chipmunk/cpSpaceHash.c +259 -159
  48. data/ext/chipmunk/cpSpaceQuery.c +127 -59
  49. data/ext/chipmunk/cpSpaceStep.c +235 -197
  50. data/ext/chipmunk/cpSpatialIndex.c +69 -0
  51. data/ext/chipmunk/cpSpatialIndex.h +227 -0
  52. data/ext/chipmunk/cpSweep1D.c +254 -0
  53. data/ext/chipmunk/cpVect.c +11 -26
  54. data/ext/chipmunk/cpVect.h +76 -71
  55. data/ext/chipmunk/extconf.rb +4 -31
  56. data/ext/chipmunk/prime.h +1 -1
  57. data/ext/chipmunk/rb_chipmunk.c +36 -45
  58. data/ext/chipmunk/rb_chipmunk.h +6 -3
  59. data/ext/chipmunk/rb_cpArbiter.c +2 -2
  60. data/ext/chipmunk/rb_cpBB.c +116 -35
  61. data/ext/chipmunk/rb_cpBody.c +5 -12
  62. data/ext/chipmunk/rb_cpConstraint.c +144 -9
  63. data/ext/chipmunk/rb_cpShape.c +69 -78
  64. data/ext/chipmunk/rb_cpSpace.c +81 -76
  65. metadata +61 -61
  66. data/LICENSE +0 -22
  67. data/README +0 -110
  68. data/Rakefile +0 -102
  69. data/ext/chipmunk/cpArray.h +0 -49
  70. data/ext/chipmunk/cpCollision.h +0 -28
  71. data/ext/chipmunk/cpHashSet.h +0 -82
  72. data/ext/chipmunk/cpSpaceHash.h +0 -110
  73. data/lib/chipmunk.rb +0 -194
@@ -0,0 +1,69 @@
1
+ /* Copyright (c) 2010 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 "chipmunk_private.h"
23
+
24
+ void
25
+ cpSpatialIndexFree(cpSpatialIndex *index)
26
+ {
27
+ if(index){
28
+ cpSpatialIndexDestroy(index);
29
+ cpfree(index);
30
+ }
31
+ }
32
+
33
+ cpSpatialIndex *
34
+ cpSpatialIndexInit(cpSpatialIndex *index, cpSpatialIndexClass *klass, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex)
35
+ {
36
+ index->klass = klass;
37
+ index->bbfunc = bbfunc;
38
+ index->staticIndex = staticIndex;
39
+
40
+ if(staticIndex){
41
+ cpAssertHard(!staticIndex->dynamicIndex, "This static index is already associated with a dynamic index.");
42
+ staticIndex->dynamicIndex = index;
43
+ }
44
+
45
+ return index;
46
+ }
47
+
48
+ typedef struct dynamicToStaticContext {
49
+ cpSpatialIndexBBFunc bbfunc;
50
+ cpSpatialIndex *staticIndex;
51
+ cpSpatialIndexQueryFunc queryFunc;
52
+ void *data;
53
+ } dynamicToStaticContext;
54
+
55
+ static void
56
+ dynamicToStaticIter(void *obj, dynamicToStaticContext *context)
57
+ {
58
+ cpSpatialIndexQuery(context->staticIndex, obj, context->bbfunc(obj), context->queryFunc, context->data);
59
+ }
60
+
61
+ void
62
+ cpSpatialIndexCollideStatic(cpSpatialIndex *dynamicIndex, cpSpatialIndex *staticIndex, cpSpatialIndexQueryFunc func, void *data)
63
+ {
64
+ if(staticIndex && cpSpatialIndexCount(staticIndex) > 0){
65
+ dynamicToStaticContext context = {dynamicIndex->bbfunc, staticIndex, func, data};
66
+ cpSpatialIndexEach(dynamicIndex, (cpSpatialIndexIteratorFunc)dynamicToStaticIter, &context);
67
+ }
68
+ }
69
+
@@ -0,0 +1,227 @@
1
+ /* Copyright (c) 2010 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
+ /**
23
+ @defgroup cpSpatialIndex cpSpatialIndex
24
+
25
+ Spatial indexes are data structures that are used to accelerate collision detection
26
+ and spatial queries. Chipmunk provides a number of spatial index algorithms to pick from
27
+ and they are programmed in a generic way so that you can use them for holding more than
28
+ just cpShape structs.
29
+
30
+ It works by using @c void pointers to the objects you add and using a callback to ask your code
31
+ for bounding boxes when it needs them. Several types of queries can be performed an index as well
32
+ as reindexing and full collision information. All communication to the spatial indexes is performed
33
+ through callback functions.
34
+
35
+ Spatial indexes should be treated as opaque structs.
36
+ This meanns you shouldn't be reading any of the struct fields.
37
+ @{
38
+ */
39
+
40
+ //MARK: Spatial Index
41
+
42
+ /// Spatial index bounding box callback function type.
43
+ /// The spatial index calls this function and passes you a pointer to an object you added
44
+ /// when it needs to get the bounding box associated with that object.
45
+ typedef cpBB (*cpSpatialIndexBBFunc)(void *obj);
46
+ /// Spatial index/object iterator callback function type.
47
+ typedef void (*cpSpatialIndexIteratorFunc)(void *obj, void *data);
48
+ /// Spatial query callback function type.
49
+ typedef void (*cpSpatialIndexQueryFunc)(void *obj1, void *obj2, void *data);
50
+ /// Spatial segment query callback function type.
51
+ typedef cpFloat (*cpSpatialIndexSegmentQueryFunc)(void *obj1, void *obj2, void *data);
52
+
53
+
54
+ typedef struct cpSpatialIndexClass cpSpatialIndexClass;
55
+ typedef struct cpSpatialIndex cpSpatialIndex;
56
+
57
+ /// @private
58
+ struct cpSpatialIndex {
59
+ cpSpatialIndexClass *klass;
60
+
61
+ cpSpatialIndexBBFunc bbfunc;
62
+
63
+ cpSpatialIndex *staticIndex, *dynamicIndex;
64
+ };
65
+
66
+
67
+ //MARK: Spatial Hash
68
+
69
+ typedef struct cpSpaceHash cpSpaceHash;
70
+
71
+ /// Allocate a spatial hash.
72
+ cpSpaceHash* cpSpaceHashAlloc(void);
73
+ /// Initialize a spatial hash.
74
+ cpSpatialIndex* cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int numcells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
75
+ /// Allocate and initialize a spatial hash.
76
+ cpSpatialIndex* cpSpaceHashNew(cpFloat celldim, int cells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
77
+
78
+ /// Change the cell dimensions and table size of the spatial hash to tune it.
79
+ /// The cell dimensions should roughly match the average size of your objects
80
+ /// and the table size should be ~10 larger than the number of objects inserted.
81
+ /// Some trial and error is required to find the optimum numbers for efficiency.
82
+ void cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells);
83
+
84
+ //MARK: AABB Tree
85
+
86
+ typedef struct cpBBTree cpBBTree;
87
+
88
+ /// Allocate a bounding box tree.
89
+ cpBBTree* cpBBTreeAlloc(void);
90
+ /// Initialize a bounding box tree.
91
+ cpSpatialIndex* cpBBTreeInit(cpBBTree *tree, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
92
+ /// Allocate and initialize a bounding box tree.
93
+ cpSpatialIndex* cpBBTreeNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
94
+
95
+ /// Perform a static top down optimization of the tree.
96
+ void cpBBTreeOptimize(cpSpatialIndex *index);
97
+
98
+ /// Bounding box tree velocity callback function.
99
+ /// This function should return an estimate for the object's velocity.
100
+ typedef cpVect (*cpBBTreeVelocityFunc)(void *obj);
101
+ /// Set the velocity function for the bounding box tree to enable temporal coherence.
102
+ void cpBBTreeSetVelocityFunc(cpSpatialIndex *index, cpBBTreeVelocityFunc func);
103
+
104
+ //MARK: Single Axis Sweep
105
+
106
+ typedef struct cpSweep1D cpSweep1D;
107
+
108
+ /// Allocate a 1D sort and sweep broadphase.
109
+ cpSweep1D* cpSweep1DAlloc(void);
110
+ /// Initialize a 1D sort and sweep broadphase.
111
+ cpSpatialIndex* cpSweep1DInit(cpSweep1D *sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
112
+ /// Allocate and initialize a 1D sort and sweep broadphase.
113
+ cpSpatialIndex* cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
114
+
115
+ //MARK: Spatial Index Implementation
116
+
117
+ typedef void (*cpSpatialIndexDestroyImpl)(cpSpatialIndex *index);
118
+
119
+ typedef int (*cpSpatialIndexCountImpl)(cpSpatialIndex *index);
120
+ typedef void (*cpSpatialIndexEachImpl)(cpSpatialIndex *index, cpSpatialIndexIteratorFunc func, void *data);
121
+
122
+ typedef cpBool (*cpSpatialIndexContainsImpl)(cpSpatialIndex *index, void *obj, cpHashValue hashid);
123
+ typedef void (*cpSpatialIndexInsertImpl)(cpSpatialIndex *index, void *obj, cpHashValue hashid);
124
+ typedef void (*cpSpatialIndexRemoveImpl)(cpSpatialIndex *index, void *obj, cpHashValue hashid);
125
+
126
+ typedef void (*cpSpatialIndexReindexImpl)(cpSpatialIndex *index);
127
+ typedef void (*cpSpatialIndexReindexObjectImpl)(cpSpatialIndex *index, void *obj, cpHashValue hashid);
128
+ typedef void (*cpSpatialIndexReindexQueryImpl)(cpSpatialIndex *index, cpSpatialIndexQueryFunc func, void *data);
129
+
130
+ typedef void (*cpSpatialIndexQueryImpl)(cpSpatialIndex *index, void *obj, cpBB bb, cpSpatialIndexQueryFunc func, void *data);
131
+ typedef void (*cpSpatialIndexSegmentQueryImpl)(cpSpatialIndex *index, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpatialIndexSegmentQueryFunc func, void *data);
132
+
133
+ struct cpSpatialIndexClass {
134
+ cpSpatialIndexDestroyImpl destroy;
135
+
136
+ cpSpatialIndexCountImpl count;
137
+ cpSpatialIndexEachImpl each;
138
+
139
+ cpSpatialIndexContainsImpl contains;
140
+ cpSpatialIndexInsertImpl insert;
141
+ cpSpatialIndexRemoveImpl remove;
142
+
143
+ cpSpatialIndexReindexImpl reindex;
144
+ cpSpatialIndexReindexObjectImpl reindexObject;
145
+ cpSpatialIndexReindexQueryImpl reindexQuery;
146
+
147
+ cpSpatialIndexQueryImpl query;
148
+ cpSpatialIndexSegmentQueryImpl segmentQuery;
149
+ };
150
+
151
+ /// Destroy and free a spatial index.
152
+ void cpSpatialIndexFree(cpSpatialIndex *index);
153
+ /// Collide the objects in @c dynamicIndex against the objects in @c staticIndex using the query callback function.
154
+ void cpSpatialIndexCollideStatic(cpSpatialIndex *dynamicIndex, cpSpatialIndex *staticIndex, cpSpatialIndexQueryFunc func, void *data);
155
+
156
+ /// Destroy a spatial index.
157
+ static inline void cpSpatialIndexDestroy(cpSpatialIndex *index)
158
+ {
159
+ if(index->klass) index->klass->destroy(index);
160
+ }
161
+
162
+ /// Get the number of objects in the spatial index.
163
+ static inline int cpSpatialIndexCount(cpSpatialIndex *index)
164
+ {
165
+ return index->klass->count(index);
166
+ }
167
+
168
+ /// Iterate the objects in the spatial index. @c func will be called once for each object.
169
+ static inline void cpSpatialIndexEach(cpSpatialIndex *index, cpSpatialIndexIteratorFunc func, void *data)
170
+ {
171
+ index->klass->each(index, func, data);
172
+ }
173
+
174
+ /// Returns true if the spatial index contains the given object.
175
+ /// Most spatial indexes use hashed storage, so you must provide a hash value too.
176
+ static inline cpBool cpSpatialIndexContains(cpSpatialIndex *index, void *obj, cpHashValue hashid)
177
+ {
178
+ return index->klass->contains(index, obj, hashid);
179
+ }
180
+
181
+ /// Add an object to a spatial index.
182
+ /// Most spatial indexes use hashed storage, so you must provide a hash value too.
183
+ static inline void cpSpatialIndexInsert(cpSpatialIndex *index, void *obj, cpHashValue hashid)
184
+ {
185
+ index->klass->insert(index, obj, hashid);
186
+ }
187
+
188
+ /// Remove an object from a spatial index.
189
+ /// Most spatial indexes use hashed storage, so you must provide a hash value too.
190
+ static inline void cpSpatialIndexRemove(cpSpatialIndex *index, void *obj, cpHashValue hashid)
191
+ {
192
+ index->klass->remove(index, obj, hashid);
193
+ }
194
+
195
+ /// Perform a full reindex of a spatial index.
196
+ static inline void cpSpatialIndexReindex(cpSpatialIndex *index)
197
+ {
198
+ index->klass->reindex(index);
199
+ }
200
+
201
+ /// Reindex a single object in the spatial index.
202
+ static inline void cpSpatialIndexReindexObject(cpSpatialIndex *index, void *obj, cpHashValue hashid)
203
+ {
204
+ index->klass->reindexObject(index, obj, hashid);
205
+ }
206
+
207
+ /// Perform a rectangle query against the spatial index, calling @c func for each potential match.
208
+ static inline void cpSpatialIndexQuery(cpSpatialIndex *index, void *obj, cpBB bb, cpSpatialIndexQueryFunc func, void *data)
209
+ {
210
+ index->klass->query(index, obj, bb, func, data);
211
+ }
212
+
213
+ /// Perform a segment query against the spatial index, calling @c func for each potential match.
214
+ static inline void cpSpatialIndexSegmentQuery(cpSpatialIndex *index, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpatialIndexSegmentQueryFunc func, void *data)
215
+ {
216
+ index->klass->segmentQuery(index, obj, a, b, t_exit, func, data);
217
+ }
218
+
219
+ /// Simultaneously reindex and find all colliding objects.
220
+ /// @c func will be called once for each potentially overlapping pair of objects found.
221
+ /// If the spatial index was initialized with a static index, it will collide it's objects against that as well.
222
+ static inline void cpSpatialIndexReindexQuery(cpSpatialIndex *index, cpSpatialIndexQueryFunc func, void *data)
223
+ {
224
+ index->klass->reindexQuery(index, func, data);
225
+ }
226
+
227
+ ///@}
@@ -0,0 +1,254 @@
1
+ /* Copyright (c) 2010 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 "chipmunk_private.h"
23
+
24
+ static inline cpSpatialIndexClass *Klass();
25
+
26
+ //MARK: Basic Structures
27
+
28
+ typedef struct Bounds {
29
+ cpFloat min, max;
30
+ } Bounds;
31
+
32
+ typedef struct TableCell {
33
+ void *obj;
34
+ Bounds bounds;
35
+ } TableCell;
36
+
37
+ struct cpSweep1D
38
+ {
39
+ cpSpatialIndex spatialIndex;
40
+
41
+ int num;
42
+ int max;
43
+ TableCell *table;
44
+ };
45
+
46
+ static inline cpBool
47
+ BoundsOverlap(Bounds a, Bounds b)
48
+ {
49
+ return (a.min <= b.max && b.min <= a.max);
50
+ }
51
+
52
+ static inline Bounds
53
+ BBToBounds(cpSweep1D *sweep, cpBB bb)
54
+ {
55
+ Bounds bounds = {bb.l, bb.r};
56
+ return bounds;
57
+ }
58
+
59
+ static inline TableCell
60
+ MakeTableCell(cpSweep1D *sweep, void *obj)
61
+ {
62
+ TableCell cell = {obj, BBToBounds(sweep, sweep->spatialIndex.bbfunc(obj))};
63
+ return cell;
64
+ }
65
+
66
+ //MARK: Memory Management Functions
67
+
68
+ cpSweep1D *
69
+ cpSweep1DAlloc(void)
70
+ {
71
+ return (cpSweep1D *)cpcalloc(1, sizeof(cpSweep1D));
72
+ }
73
+
74
+ static void
75
+ ResizeTable(cpSweep1D *sweep, int size)
76
+ {
77
+ sweep->max = size;
78
+ sweep->table = (TableCell *)cprealloc(sweep->table, size*sizeof(TableCell));
79
+ }
80
+
81
+ cpSpatialIndex *
82
+ cpSweep1DInit(cpSweep1D *sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex)
83
+ {
84
+ cpSpatialIndexInit((cpSpatialIndex *)sweep, Klass(), bbfunc, staticIndex);
85
+
86
+ sweep->num = 0;
87
+ ResizeTable(sweep, 32);
88
+
89
+ return (cpSpatialIndex *)sweep;
90
+ }
91
+
92
+ cpSpatialIndex *
93
+ cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex)
94
+ {
95
+ return cpSweep1DInit(cpSweep1DAlloc(), bbfunc, staticIndex);
96
+ }
97
+
98
+ static void
99
+ cpSweep1DDestroy(cpSweep1D *sweep)
100
+ {
101
+ cpfree(sweep->table);
102
+ sweep->table = NULL;
103
+ }
104
+
105
+ //MARK: Misc
106
+
107
+ static int
108
+ cpSweep1DCount(cpSweep1D *sweep)
109
+ {
110
+ return sweep->num;
111
+ }
112
+
113
+ static void
114
+ cpSweep1DEach(cpSweep1D *sweep, cpSpatialIndexIteratorFunc func, void *data)
115
+ {
116
+ TableCell *table = sweep->table;
117
+ for(int i=0, count=sweep->num; i<count; i++) func(table[i].obj, data);
118
+ }
119
+
120
+ static int
121
+ cpSweep1DContains(cpSweep1D *sweep, void *obj, cpHashValue hashid)
122
+ {
123
+ TableCell *table = sweep->table;
124
+ for(int i=0, count=sweep->num; i<count; i++){
125
+ if(table[i].obj == obj) return cpTrue;
126
+ }
127
+
128
+ return cpFalse;
129
+ }
130
+
131
+ //MARK: Basic Operations
132
+
133
+ static void
134
+ cpSweep1DInsert(cpSweep1D *sweep, void *obj, cpHashValue hashid)
135
+ {
136
+ if(sweep->num == sweep->max) ResizeTable(sweep, sweep->max*2);
137
+
138
+ sweep->table[sweep->num] = MakeTableCell(sweep, obj);
139
+ sweep->num++;
140
+ }
141
+
142
+ static void
143
+ cpSweep1DRemove(cpSweep1D *sweep, void *obj, cpHashValue hashid)
144
+ {
145
+ TableCell *table = sweep->table;
146
+ for(int i=0, count=sweep->num; i<count; i++){
147
+ if(table[i].obj == obj){
148
+ int num = --sweep->num;
149
+
150
+ table[i] = table[num];
151
+ table[num].obj = NULL;
152
+
153
+ return;
154
+ }
155
+ }
156
+ }
157
+
158
+ //MARK: Reindexing Functions
159
+
160
+ static void
161
+ cpSweep1DReindexObject(cpSweep1D *sweep, void *obj, cpHashValue hashid)
162
+ {
163
+ // Nothing to do here
164
+ }
165
+
166
+ static void
167
+ cpSweep1DReindex(cpSweep1D *sweep)
168
+ {
169
+ // Nothing to do here
170
+ // Could perform a sort, but queries are not accelerated anyway.
171
+ }
172
+
173
+ //MARK: Query Functions
174
+
175
+ static void
176
+ cpSweep1DQuery(cpSweep1D *sweep, void *obj, cpBB bb, cpSpatialIndexQueryFunc func, void *data)
177
+ {
178
+ // Implementing binary search here would allow you to find an upper limit
179
+ // but not a lower limit. Probably not worth the hassle.
180
+
181
+ Bounds bounds = BBToBounds(sweep, bb);
182
+
183
+ TableCell *table = sweep->table;
184
+ for(int i=0, count=sweep->num; i<count; i++){
185
+ TableCell cell = table[i];
186
+ if(BoundsOverlap(bounds, cell.bounds) && obj != cell.obj) func(obj, cell.obj, data);
187
+ }
188
+ }
189
+
190
+ static void
191
+ cpSweep1DSegmentQuery(cpSweep1D *sweep, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpatialIndexSegmentQueryFunc func, void *data)
192
+ {
193
+ cpBB bb = cpBBExpand(cpBBNew(a.x, a.y, a.x, a.y), b);
194
+ Bounds bounds = BBToBounds(sweep, bb);
195
+
196
+ TableCell *table = sweep->table;
197
+ for(int i=0, count=sweep->num; i<count; i++){
198
+ TableCell cell = table[i];
199
+ if(BoundsOverlap(bounds, cell.bounds)) func(obj, cell.obj, data);
200
+ }
201
+ }
202
+
203
+ //MARK: Reindex/Query
204
+
205
+ static int
206
+ TableSort(TableCell *a, TableCell *b)
207
+ {
208
+ return (a->bounds.min < b->bounds.min ? -1 : (a->bounds.min > b->bounds.min ? 1 : 0));
209
+ }
210
+
211
+ static void
212
+ cpSweep1DReindexQuery(cpSweep1D *sweep, cpSpatialIndexQueryFunc func, void *data)
213
+ {
214
+ TableCell *table = sweep->table;
215
+ int count = sweep->num;
216
+
217
+ // Update bounds and sort
218
+ for(int i=0; i<count; i++) table[i] = MakeTableCell(sweep, table[i].obj);
219
+ qsort(table, count, sizeof(TableCell), (int (*)(const void *, const void *))TableSort); // TODO use insertion sort instead
220
+
221
+ for(int i=0; i<count; i++){
222
+ TableCell cell = table[i];
223
+ cpFloat max = cell.bounds.max;
224
+
225
+ for(int j=i+1; table[j].bounds.min < max && j<count; j++){
226
+ func(cell.obj, table[j].obj, data);
227
+ }
228
+ }
229
+
230
+ // Reindex query is also responsible for colliding against the static index.
231
+ // Fortunately there is a helper function for that.
232
+ cpSpatialIndexCollideStatic((cpSpatialIndex *)sweep, sweep->spatialIndex.staticIndex, func, data);
233
+ }
234
+
235
+ static cpSpatialIndexClass klass = {
236
+ (cpSpatialIndexDestroyImpl)cpSweep1DDestroy,
237
+
238
+ (cpSpatialIndexCountImpl)cpSweep1DCount,
239
+ (cpSpatialIndexEachImpl)cpSweep1DEach,
240
+ (cpSpatialIndexContainsImpl)cpSweep1DContains,
241
+
242
+ (cpSpatialIndexInsertImpl)cpSweep1DInsert,
243
+ (cpSpatialIndexRemoveImpl)cpSweep1DRemove,
244
+
245
+ (cpSpatialIndexReindexImpl)cpSweep1DReindex,
246
+ (cpSpatialIndexReindexObjectImpl)cpSweep1DReindexObject,
247
+ (cpSpatialIndexReindexQueryImpl)cpSweep1DReindexQuery,
248
+
249
+ (cpSpatialIndexQueryImpl)cpSweep1DQuery,
250
+ (cpSpatialIndexSegmentQueryImpl)cpSweep1DSegmentQuery,
251
+ };
252
+
253
+ static inline cpSpatialIndexClass *Klass(){return &klass;}
254
+