Mercurial > projects > chipmunkd
comparison trunk/chipmunkd/cpSpaceComponent.d @ 29:80058cee1a77
updated to chipmunk 5.3.4
author | Extrawurst |
---|---|
date | Thu, 16 Dec 2010 00:33:06 +0100 |
parents | 4ceef5833c8c |
children | 34b36b5193af |
comparison
equal
deleted
inserted
replaced
28:4541ca17975b | 29:80058cee1a77 |
---|---|
33 b_root.node.parent = a_root; | 33 b_root.node.parent = a_root; |
34 a_root.node.rank++; | 34 a_root.node.rank++; |
35 } | 35 } |
36 } | 36 } |
37 | 37 |
38 static void | 38 void |
39 componentActivate(cpBody *root) | 39 cpSpaceActivateBody(cpSpace *space, cpBody *_body) |
40 { | 40 { |
41 if(!cpBodyIsSleeping(root)) return; | 41 if(space.locked){ |
42 | 42 // cpSpaceActivateBody() is called again once the space is unlocked |
43 cpSpace *space = root.space; | 43 cpArrayPush(space.rousedBodies, _body); |
44 assert(space, "Trying to activate a body that was never added to a space."); | 44 } else { |
45 assert(!space.locked, "Bodies can not be awakened during a query or a call to cpSpaceSte(). Put these calls into a post-step callback."); | 45 cpArrayPush(space.bodies, _body); |
46 | |
47 cpBody *_body = root; | |
48 cpBody *next; | |
49 do { | |
50 next = _body.node.next; | |
51 | |
52 cpFloat idleTime = (cpBodyIsStatic(_body) ? cast(cpFloat)INFINITY : 0.0f); | |
53 cpComponentNode node = {null, null, 0, idleTime}; | |
54 _body.node = node; | |
55 if(!cpBodyIsRogue(_body)) cpArrayPush(space.bodies, _body); | |
56 | |
57 for(cpShape *shape=_body.shapesList; shape; shape=shape.next){ | 46 for(cpShape *shape=_body.shapesList; shape; shape=shape.next){ |
58 cpSpaceHashRemove(space.staticShapes, shape, shape.hashid); | 47 cpSpaceHashRemove(space.staticShapes, shape, shape.hashid); |
59 cpSpaceHashInsert(space.activeShapes, shape, shape.hashid, shape.bb); | 48 cpSpaceHashInsert(space.activeShapes, shape, shape.hashid, shape.bb); |
60 } | 49 } |
50 } | |
51 } | |
52 | |
53 static void | |
54 componentActivate(cpBody *root) | |
55 { | |
56 if(!cpBodyIsSleeping(root)) return; | |
57 | |
58 cpSpace *space = root.space; | |
59 assert(space, "Trying to activate a body that was never added to a space."); | |
60 | |
61 cpBody *_body = root, next; | |
62 do { | |
63 next = _body.node.next; | |
64 | |
65 cpComponentNode node = {null, null, 0, 0.0f}; | |
66 _body.node = node; | |
67 | |
68 cpSpaceActivateBody(space, _body); | |
69 | |
61 } while((_body = next) != root); | 70 } while((_body = next) != root); |
62 | 71 |
63 cpArrayDeleteObj(space.sleepingComponents, root); | 72 cpArrayDeleteObj(space.sleepingComponents, root); |
64 } | 73 } |
65 | 74 |
66 void | 75 void |
67 cpBodyActivate(cpBody *_body) | 76 cpBodyActivate(cpBody *_body) |
68 { | 77 { |
69 // Reset the idle time even if it's not in a currently sleeping component | 78 //NOTE: dmd compiler bug when useing -inline |
70 // Like a body resting on or jointed to a rogue body. | 79 auto foo = componentNodeRoot(_body); |
71 if(!cpBodyIsStatic(_body)) _body.node.idleTime = 0.0f; | 80 componentActivate(foo); |
72 componentActivate(componentNodeRoot(_body)); | |
73 } | 81 } |
74 | 82 |
75 static void | 83 static void |
76 mergeBodies(cpSpace *space, cpArray *components, cpArray *rogueBodies, cpBody *a, cpBody *b) | 84 mergeBodies(cpSpace *space, cpArray *components, cpArray *rogueBodies, cpBody *a, cpBody *b) |
77 { | 85 { |
78 // Don't merge with the static body | 86 // Ignore connections to static bodies |
79 if(cpBodyIsStatic(a) || cpBodyIsStatic(b)) return; | 87 if(cpBodyIsStatic(a) || cpBodyIsStatic(b)) return; |
80 | 88 |
81 cpBody *a_root = componentNodeRoot(a); | 89 cpBody *a_root = componentNodeRoot(a); |
82 cpBody *b_root = componentNodeRoot(b); | 90 cpBody *b_root = componentNodeRoot(b); |
83 | 91 |
89 } else if(a_sleep || b_sleep){ | 97 } else if(a_sleep || b_sleep){ |
90 componentActivate(a_root); | 98 componentActivate(a_root); |
91 componentActivate(b_root); | 99 componentActivate(b_root); |
92 } | 100 } |
93 | 101 |
94 // Add any rogue bodies (bodies not added to the space) | 102 // Add any rogue bodies found to the list and reset the idle time of anything they touch. |
95 if(cpBodyIsRogue(a)) cpArrayPush(rogueBodies, a); | 103 if(cpBodyIsRogue(a)){ cpArrayPush(rogueBodies, a); b.node.idleTime = 0.0f; } |
96 if(cpBodyIsRogue(b)) cpArrayPush(rogueBodies, b); | 104 if(cpBodyIsRogue(b)){ cpArrayPush(rogueBodies, b); a.node.idleTime = 0.0f; } |
97 | 105 |
98 componentNodeMerge(a_root, b_root); | 106 componentNodeMerge(a_root, b_root); |
99 } | 107 } |
100 | 108 |
101 static cpBool | 109 static cpBool |
140 cpArray *bodies = space.bodies; | 148 cpArray *bodies = space.bodies; |
141 cpArray *newBodies = cpArrayNew(bodies.num); | 149 cpArray *newBodies = cpArrayNew(bodies.num); |
142 cpArray *rogueBodies = cpArrayNew(16); | 150 cpArray *rogueBodies = cpArrayNew(16); |
143 cpArray *arbiters = space.arbiters; | 151 cpArray *arbiters = space.arbiters; |
144 cpArray *constraints = space.constraints; | 152 cpArray *constraints = space.constraints; |
145 cpArray *components = cpArrayNew(bodies.num/8); | 153 cpArray *components = cpArrayNew(space.sleepingComponents.num); |
146 | 154 |
147 cpFloat dv = space.idleSpeedThreshold; | 155 cpFloat dv = space.idleSpeedThreshold; |
148 cpFloat dvsq = (dv ? dv*dv : cpvdot(space.gravity, space.gravity)*dt*dt); | 156 cpFloat dvsq = (dv ? dv*dv : cpvdot(space.gravity, space.gravity)*dt*dt); |
157 | |
149 // update idling | 158 // update idling |
150 for(int i=0; i<bodies.num; i++){ | 159 for(int i=0; i<bodies.num; i++){ |
151 cpBody *_body = cast(cpBody*)bodies.arr[i]; | 160 cpBody *_body = cast(cpBody*)bodies.arr[i]; |
152 | 161 |
153 cpFloat thresh = (dvsq ? _body.m*dvsq : 0.0f); | 162 cpFloat thresh = (dvsq ? _body.m*dvsq : 0.0f); |
163 cpConstraint *constraint = cast(cpConstraint *)constraints.arr[j]; | 172 cpConstraint *constraint = cast(cpConstraint *)constraints.arr[j]; |
164 mergeBodies(space, components, rogueBodies, constraint.a, constraint.b); | 173 mergeBodies(space, components, rogueBodies, constraint.a, constraint.b); |
165 } | 174 } |
166 | 175 |
167 // iterate bodies and add them to their components | 176 // iterate bodies and add them to their components |
168 for(int i=0; i<bodies.num; i++) | 177 for(int i=0; i<bodies.num; i++) addToComponent(cast(cpBody*)bodies.arr[i], components); |
169 addToComponent(cast(cpBody*)bodies.arr[i], components); | 178 for(int i=0; i<rogueBodies.num; i++) addToComponent(cast(cpBody*)rogueBodies.arr[i], components); |
170 for(int i=0; i<rogueBodies.num; i++) | |
171 addToComponent(cast(cpBody*)rogueBodies.arr[i], components); | |
172 | 179 |
173 // iterate components, copy or deactivate | 180 // iterate components, copy or deactivate |
174 for(int i=0; i<components.num; i++){ | 181 for(int i=0; i<components.num; i++){ |
175 cpBody *root = cast(cpBody*)components.arr[i]; | 182 cpBody *root = cast(cpBody*)components.arr[i]; |
176 if(componentActive(root, space.sleepTimeThreshold)){ | 183 if(componentActive(root, space.sleepTimeThreshold)){ |
178 cpBody *next; | 185 cpBody *next; |
179 do { | 186 do { |
180 next = _body.node.next; | 187 next = _body.node.next; |
181 | 188 |
182 if(!cpBodyIsRogue(_body)) cpArrayPush(newBodies, _body); | 189 if(!cpBodyIsRogue(_body)) cpArrayPush(newBodies, _body); |
183 _body.node.next = null; | 190 cpComponentNode node = {null, null, 0, _body.node.idleTime}; |
184 _body.node.parent = null; | 191 _body.node = node; |
185 _body.node.rank = 0; | |
186 } while((_body = next) != root); | 192 } while((_body = next) != root); |
187 } else { | 193 } else { |
188 cpBody *_body = root; | 194 cpBody *_body = root; |
189 cpBody *next; | 195 cpBody *next; |
190 do { | 196 do { |
222 assert(!group || cpBodyIsSleeping(group), "Cannot use a non-sleeping body as a group identifier."); | 228 assert(!group || cpBodyIsSleeping(group), "Cannot use a non-sleeping body as a group identifier."); |
223 | 229 |
224 if(cpBodyIsSleeping(_body)) return; | 230 if(cpBodyIsSleeping(_body)) return; |
225 | 231 |
226 for(cpShape *shape = _body.shapesList; shape; shape = shape.next){ | 232 for(cpShape *shape = _body.shapesList; shape; shape = shape.next){ |
233 cpShapeCacheBB(shape); | |
227 cpSpaceHashRemove(space.activeShapes, shape, shape.hashid); | 234 cpSpaceHashRemove(space.activeShapes, shape, shape.hashid); |
228 | |
229 cpShapeCacheBB(shape); | |
230 cpSpaceHashInsert(space.staticShapes, shape, shape.hashid, shape.bb); | 235 cpSpaceHashInsert(space.staticShapes, shape, shape.hashid, shape.bb); |
231 } | 236 } |
232 | 237 |
233 if(group){ | 238 if(group){ |
234 cpBody *root = componentNodeRoot(group); | 239 cpBody *root = componentNodeRoot(group); |
246 cpArrayDeleteObj(space.bodies, _body); | 251 cpArrayDeleteObj(space.bodies, _body); |
247 } | 252 } |
248 | 253 |
249 static void | 254 static void |
250 activateTouchingHelper(cpShape *shape, cpContactPointSet *points, cpArray **bodies){ | 255 activateTouchingHelper(cpShape *shape, cpContactPointSet *points, cpArray **bodies){ |
251 if(*bodies == null) (*bodies) = cpArrayNew(0); | 256 cpBodyActivate(shape._body); |
252 cpArrayPush(*bodies, shape._body); | |
253 } | 257 } |
254 | 258 |
255 void | 259 void |
256 cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape){ | 260 cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape){ |
257 cpArray *bodies = null; | 261 cpArray *bodies = null; |
258 cpSpaceShapeQuery(space, shape, cast(cpSpaceShapeQueryFunc)&activateTouchingHelper, &bodies); | 262 cpSpaceShapeQuery(space, shape, cast(cpSpaceShapeQueryFunc)&activateTouchingHelper, &bodies); |
259 | 263 } |
260 if(bodies){ | |
261 for(int i=0; i<bodies.num; i++){ | |
262 cpBody *_body = cast(cpBody *)bodies.arr[i]; | |
263 cpBodyActivate(_body); | |
264 } | |
265 } | |
266 } |