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 }