annotate trunk/chipmunkd/cpSpaceStep.d @ 29:80058cee1a77

updated to chipmunk 5.3.4
author Extrawurst
date Thu, 16 Dec 2010 00:33:06 +0100
parents 4ceef5833c8c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
1
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
2 // written in the D programming language
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
3
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
4 module chipmunkd.cpSpaceStep;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
5
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
6 import chipmunkd.chipmunk;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
7 //import chipmunkd.chipmunk_types_h;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
8 //import chipmunkd.cpVect,chipmunkd.cpVect_h;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
9 //import chipmunkd.cpHashSet;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
10 //import chipmunkd.cpCollision;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
11 //import chipmunkd.cpBody;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
12 //import chipmunkd.cpArray;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
13 //import chipmunkd.cpShape;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
14 //import chipmunkd.cpBB;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
15 //import chipmunkd.cpArbiter;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
16 //import chipmunkd.cpSpaceHash;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
17 //import chipmunkd.constraints.cpConstraint;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
18 //import chipmunkd.cpSpaceQuery;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
19 //
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
20 //#pragma mark Post Step Callback Functions
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
21
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
22 struct PostStepCallback {
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
23 cpPostStepFunc func;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
24 void *obj;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
25 void *data;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
26 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
27
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
28 static cpBool
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
29 postStepFuncSetEql(PostStepCallback *a, PostStepCallback *b){
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
30 return a.obj == b.obj;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
31 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
32
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
33 static void *
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
34 postStepFuncSetTrans(PostStepCallback *callback, void *ignored)
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
35 {
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
36 PostStepCallback *value = cast(PostStepCallback *)cpmalloc(PostStepCallback.sizeof);
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
37 (*value) = (*callback);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
38
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
39 return value;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
40 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
41
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
42 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
43 cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *obj, void *data)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
44 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
45 if(!space.postStepCallbacks){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
46 space.postStepCallbacks = cpHashSetNew(0, cast(cpHashSetEqlFunc)&postStepFuncSetEql, cast(cpHashSetTransFunc)&postStepFuncSetTrans);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
47 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
48
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
49 PostStepCallback callback = {func, obj, data};
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
50 cpHashSetInsert(space.postStepCallbacks, cast(cpHashValue)cast(size_t)obj, &callback, null);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
51 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
52
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
53 void *
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
54 cpSpaceGetPostStepData(cpSpace *space, void *obj)
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
55 {
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
56 if(space.postStepCallbacks){
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
57 PostStepCallback query = {null, obj, null};
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
58 PostStepCallback *callback = cast(PostStepCallback *)cpHashSetFind(space.postStepCallbacks, cast(cpHashValue)cast(size_t)obj, &query);
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
59 return (callback ? callback.data : null);
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
60 } else {
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
61 return null;
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
62 }
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
63 }
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
64
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
65 //#pragma mark Contact Buffer Functions
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
66
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
67 enum CP_CONTACTS_BUFFER_SIZE = ((CP_BUFFER_BYTES - cpContactBufferHeader.sizeof)/cpContact.sizeof);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
68
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
69 struct cpContactBuffer {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
70 cpContactBufferHeader header;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
71 cpContact[CP_CONTACTS_BUFFER_SIZE] contacts;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
72 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
73
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
74 static cpContactBufferHeader *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
75 cpSpaceAllocContactBuffer(cpSpace *space)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
76 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
77 cpContactBuffer *buffer = cast(cpContactBuffer *)cpmalloc(cpContactBuffer.sizeof);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
78 cpArrayPush(space.allocatedBuffers, buffer);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
79 return cast(cpContactBufferHeader *)buffer;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
80 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
81
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
82 static cpContactBufferHeader *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
83 cpContactBufferHeaderInit(cpContactBufferHeader *header, cpTimestamp stamp, cpContactBufferHeader *splice)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
84 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
85 header.stamp = stamp;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
86 header.next = (splice ? splice.next : header);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
87 header.numContacts = 0;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
88
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
89 return header;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
90 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
91
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
92 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
93 cpSpacePushFreshContactBuffer(cpSpace *space)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
94 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
95 cpTimestamp stamp = space.stamp;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
96
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
97 cpContactBufferHeader *head = space.contactBuffersHead;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
98
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
99 if(!head){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
100 // No buffers have been allocated, make one
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
101 space.contactBuffersHead = cpContactBufferHeaderInit(cpSpaceAllocContactBuffer(space), stamp, null);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
102 } else if(stamp - head.next.stamp > cp_contact_persistence){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
103 // The tail buffer is available, rotate the ring
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
104 cpContactBufferHeader *tail = head.next;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
105 space.contactBuffersHead = cpContactBufferHeaderInit(tail, stamp, tail);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
106 } else {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
107 // Allocate a new buffer and push it into the ring
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
108 cpContactBufferHeader *buffer = cpContactBufferHeaderInit(cpSpaceAllocContactBuffer(space), stamp, head);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
109 space.contactBuffersHead = head.next = buffer;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
110 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
111 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
112
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
113
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
114 static cpContact *
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
115 cpContactBufferGetArray(cpSpace *space)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
116 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
117 if(space.contactBuffersHead.numContacts + CP_MAX_CONTACTS_PER_ARBITER > CP_CONTACTS_BUFFER_SIZE){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
118 // contact buffer could overflow on the next collision, push a fresh one.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
119 cpSpacePushFreshContactBuffer(space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
120 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
121
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
122 cpContactBufferHeader *head = space.contactBuffersHead;
13
c03a41d47b60 - finished all constraints properties
Extrawurst
parents: 4
diff changeset
123 return &(cast(cpContactBuffer *)head).contacts[head.numContacts];
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
124 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
125
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
126 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
127 cpSpacePushContacts(cpSpace *space, int count){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
128 assert(count <= CP_MAX_CONTACTS_PER_ARBITER, "Internal error, too many contact point overflow!");
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
129 space.contactBuffersHead.numContacts += count;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
130 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
131
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
132 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
133 cpSpacePopContacts(cpSpace *space, int count){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
134 space.contactBuffersHead.numContacts -= count;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
135 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
136
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
137 //#pragma mark Collision Detection Functions
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
138
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
139 static cpBool
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
140 queryReject(cpShape *a, cpShape *b)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
141 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
142 return
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
143 // BBoxes must overlap
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
144 !cpBBintersects(a.bb, b.bb)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
145 // Don't collide shapes attached to the same body.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
146 || a._body == b._body
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
147 // Don't collide objects in the same non-zero group
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
148 || (a.group && a.group == b.group)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
149 // Don't collide objects that don't share at least on layer.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
150 || !(a.layers & b.layers);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
151 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
152
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
153 // Callback from the spatial hash.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
154 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
155 queryFunc(cpShape *a, cpShape *b, cpSpace *space)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
156 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
157 // Reject any of the simple cases
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
158 if(queryReject(a,b)) return;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
159
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
160 // Find the collision pair function for the shapes.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
161 struct tmp{cpCollisionType a, b;} tmp ids = {a.collision_type, b.collision_type};
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
162 cpHashValue collHashID = CP_HASH_PAIR(a.collision_type, b.collision_type);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
163 cpCollisionHandler *handler = cast(cpCollisionHandler *)cpHashSetFind(space.collFuncSet, collHashID, &ids);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
164
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
165 cpBool sensor = a.sensor || b.sensor;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
166 if(sensor && handler == &space.defaultHandler) return;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
167
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
168 // Shape 'a' should have the lower shape type. (required by cpCollideShapes() )
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
169 if(a.klass.type > b.klass.type){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
170 cpShape *temp = a;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
171 a = b;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
172 b = temp;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
173 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
174
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
175 // Narrow-phase collision detection.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
176 cpContact *contacts = cpContactBufferGetArray(space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
177 int numContacts = cpCollideShapes(a, b, contacts);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
178 if(!numContacts) return; // Shapes are not colliding.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
179 cpSpacePushContacts(space, numContacts);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
180
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
181 // Get an arbiter from space.contactSet for the two shapes.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
182 // This is where the persistant contact magic comes from.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
183 cpShape *shape_pair[] = [a, b];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
184 cpHashValue arbHashID = CP_HASH_PAIR(cast(size_t)a, cast(size_t)b);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
185 cpArbiter *arb = cast(cpArbiter *)cpHashSetInsert(space.contactSet, arbHashID, shape_pair.ptr, space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
186 cpArbiterUpdate(arb, contacts, numContacts, handler, a, b); // retains the contacts array
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
187
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
188 // Call the begin function first if it's the first step
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
189 if(arb.state == cpArbiterState.cpArbiterStateFirstColl && !handler.begin(arb, space, handler.data)){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
190 cpArbiterIgnore(arb); // permanently ignore the collision until separation
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
191 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
192
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
193 if(
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
194 // Ignore the arbiter if it has been flagged
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
195 (arb.state != cpArbiterState.cpArbiterStateIgnore) &&
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
196 // Call preSolve
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
197 handler.preSolve(arb, space, handler.data) &&
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
198 // Process, but don't add collisions for sensors.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
199 !sensor
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
200 ){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
201 cpArrayPush(space.arbiters, arb);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
202 } else {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
203 cpSpacePopContacts(space, numContacts);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
204
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
205 arb.contacts = null;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
206 arb.numContacts = 0;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
207
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
208 // Normally arbiters are set as used after calling the post-step callback.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
209 // However, post-step callbacks are not called for sensors or arbiters rejected from pre-solve.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
210 if(arb.state != cpArbiterState.cpArbiterStateIgnore) arb.state = cpArbiterState.cpArbiterStateNormal;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
211 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
212
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
213 // Time stamp the arbiter so we know it was used recently.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
214 arb.stamp = space.stamp;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
215 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
216
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
217 // Iterator for active/static hash collisions.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
218 static void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
219 active2staticIter(cpShape *shape, cpSpace *space)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
220 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
221 cpSpaceHashQuery(space.staticShapes, shape, shape.bb, cast(cpSpaceHashQueryFunc)&queryFunc, space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
222 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
223
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
224 // Hashset filter func to throw away old arbiters.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
225 static cpBool
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
226 contactSetFilter(cpArbiter *arb, cpSpace *space)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
227 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
228 if(space.sleepTimeThreshold != INFINITY){
23
4ceef5833c8c updated to chipmunk 5.3.3
Extrawurst
parents: 13
diff changeset
229 cpBody *a = arb.a._body;
4ceef5833c8c updated to chipmunk 5.3.3
Extrawurst
parents: 13
diff changeset
230 cpBody *b = arb.b._body;
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
231
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
232 // both bodies are either static or sleeping
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
233 cpBool sleepingNow =
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
234 (cpBodyIsStatic(a) || cpBodyIsSleeping(a)) &&
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
235 (cpBodyIsStatic(b) || cpBodyIsSleeping(b));
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
236
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
237 if(sleepingNow){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
238 arb.state = cpArbiterState.cpArbiterStateSleep;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
239 return cpTrue;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
240 } else if(arb.state == cpArbiterState.cpArbiterStateSleep){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
241 // wake up the arbiter and continue as normal
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
242 arb.state = cpArbiterState.cpArbiterStateNormal;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
243 // TODO is it possible that cpArbiterStateIgnore should be set here instead?
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
244 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
245 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
246
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
247 cpTimestamp ticks = space.stamp - arb.stamp;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
248
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
249 // was used last frame, but not this one
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
250 if(ticks >= 1 && arb.state != cpArbiterState.cpArbiterStateCached){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
251 arb.handler.separate(arb, space, arb.handler.data);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
252 arb.state = cpArbiterState.cpArbiterStateCached;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
253 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
254
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
255 if(ticks >= cp_contact_persistence){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
256 arb.contacts = null;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
257 arb.numContacts = 0;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
258
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
259 cpArrayPush(space.pooledArbiters, arb);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
260 return cpFalse;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
261 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
262
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
263 return cpTrue;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
264 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
265
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
266 // Hashset filter func to call and throw away post step callbacks.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
267 static void
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
268 postStepCallbackSetIter(PostStepCallback *callback, cpSpace *space)
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
269 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
270 callback.func(space, callback.obj, callback.data);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
271 cpfree(callback);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
272 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
273
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
274 //#pragma mark All Important cpSpaceStep() Function
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
275
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
276 //void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
277
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
278 static void updateBBCache(cpShape *shape, void *unused){cpShapeCacheBB(shape);}
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
279
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
280 void
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
281 cpSpaceStep(cpSpace *space, cpFloat dt)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
282 {
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
283 if(!dt) return; // don't step if the timestep is 0!
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
284 cpFloat dt_inv = 1.0f/dt;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
285
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
286 cpArray *bodies = space.bodies;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
287 cpArray *constraints = space.constraints;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
288
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
289 // Empty the arbiter list.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
290 space.arbiters.num = 0;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
291
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
292 // Integrate positions.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
293 for(int i=0; i<bodies.num; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
294 cpBody *_body = cast(cpBody *)bodies.arr[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
295 _body.position_func(_body, dt);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
296 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
297
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
298 // Pre-cache BBoxes and shape data.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
299 cpSpaceHashEach(space.activeShapes, cast(cpSpaceHashIterator)&updateBBCache, null);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
300
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
301 cpSpaceLock(space);
23
4ceef5833c8c updated to chipmunk 5.3.3
Extrawurst
parents: 13
diff changeset
302
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
303 // Collide!
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
304 cpSpacePushFreshContactBuffer(space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
305 if(space.staticShapes.handleSet.entries)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
306 cpSpaceHashEach(space.activeShapes, cast(cpSpaceHashIterator)&active2staticIter, space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
307 cpSpaceHashQueryRehash(space.activeShapes, cast(cpSpaceHashQueryFunc)&queryFunc, space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
308
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
309 cpSpaceUnlock(space);
23
4ceef5833c8c updated to chipmunk 5.3.3
Extrawurst
parents: 13
diff changeset
310
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
311 // If body sleeping is enabled, do that now.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
312 if(space.sleepTimeThreshold != INFINITY){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
313 cpSpaceProcessComponents(space, dt);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
314 bodies = space.bodies; // rebuilt by processContactComponents()
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
315 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
316
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
317 // Clear out old cached arbiters and dispatch untouch functions
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
318 cpHashSetFilter(space.contactSet, cast(cpHashSetFilterFunc)&contactSetFilter, space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
319
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
320 // Prestep the arbiters.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
321 cpArray *arbiters = space.arbiters;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
322 for(int i=0; i<arbiters.num; i++)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
323 cpArbiterPreStep(cast(cpArbiter *)arbiters.arr[i], dt_inv);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
324
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
325 // Prestep the constraints.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
326 for(int i=0; i<constraints.num; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
327 cpConstraint *constraint = cast(cpConstraint *)constraints.arr[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
328 constraint.klass.preStep(constraint, dt, dt_inv);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
329 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
330
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
331 for(int i=0; i<space.elasticIterations; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
332 for(int j=0; j<arbiters.num; j++)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
333 cpArbiterApplyImpulse(cast(cpArbiter *)arbiters.arr[j], 1.0f);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
334
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
335 for(int j=0; j<constraints.num; j++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
336 cpConstraint *constraint = cast(cpConstraint *)constraints.arr[j];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
337 constraint.klass.applyImpulse(constraint);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
338 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
339 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
340
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
341 // Integrate velocities.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
342 cpFloat damping = cpfpow(1.0f/space.damping, -dt);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
343 for(int i=0; i<bodies.num; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
344 cpBody *_body = cast(cpBody *)bodies.arr[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
345 _body.velocity_func(_body, space.gravity, damping, dt);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
346 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
347
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
348 for(int i=0; i<arbiters.num; i++)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
349 cpArbiterApplyCachedImpulse(cast(cpArbiter *)arbiters.arr[i]);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
350
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
351 // run the old-style elastic solver if elastic iterations are disabled
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
352 cpFloat elasticCoef = (space.elasticIterations ? 0.0f : 1.0f);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
353
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
354 // Run the impulse solver.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
355 for(int i=0; i<space.iterations; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
356 for(int j=0; j<arbiters.num; j++)
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
357 cpArbiterApplyImpulse(cast(cpArbiter *)arbiters.arr[j], elasticCoef);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
358
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
359 for(int j=0; j<constraints.num; j++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
360 cpConstraint *constraint = cast(cpConstraint *)constraints.arr[j];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
361 constraint.klass.applyImpulse(constraint);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
362 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
363 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
364
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
365 cpSpaceLock(space);
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
366
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
367 // run the post solve callbacks
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
368 for(int i=0; i<arbiters.num; i++){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
369 cpArbiter *arb = cast(cpArbiter *) arbiters.arr[i];
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
370
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
371 cpCollisionHandler *handler = arb.handler;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
372 handler.postSolve(arb, space, handler.data);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
373
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
374 arb.state = cpArbiterState.cpArbiterStateNormal;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
375 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
376
29
80058cee1a77 updated to chipmunk 5.3.4
Extrawurst
parents: 23
diff changeset
377 cpSpaceUnlock(space);
23
4ceef5833c8c updated to chipmunk 5.3.3
Extrawurst
parents: 13
diff changeset
378
4
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
379 // Run the post step callbacks
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
380 // Loop because post step callbacks may create more post step callbacks
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
381 while(space.postStepCallbacks){
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
382 cpHashSet *callbacks = space.postStepCallbacks;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
383 space.postStepCallbacks = null;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
384
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
385 cpHashSetEach(callbacks, cast(cpHashSetIterFunc)&postStepCallbackSetIter, space);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
386 cpHashSetFree(callbacks);
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
387 }
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
388
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
389 // Increment the stamp.
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
390 space.stamp++;
7ebbd4d05553 initial commit
Extrawurst
parents:
diff changeset
391 }