Mercurial > projects > chipmunkd
changeset 29:80058cee1a77
updated to chipmunk 5.3.4
author | Extrawurst |
---|---|
date | Thu, 16 Dec 2010 00:33:06 +0100 |
parents | 4541ca17975b |
children | 34b36b5193af |
files | trunk/chipmunkd/cpSpace.d trunk/chipmunkd/cpSpaceComponent.d trunk/chipmunkd/cpSpaceQuery.d trunk/chipmunkd/cpSpaceStep.d |
diffstat | 4 files changed, 126 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/chipmunkd/cpSpace.d Mon Dec 13 21:40:56 2010 +0100 +++ b/trunk/chipmunkd/cpSpace.d Thu Dec 16 00:33:06 2010 +0100 @@ -1,4 +1,3 @@ - // written in the D programming language module chipmunkd.cpSpace; @@ -58,7 +57,7 @@ // *** Internally Used Fields // When the space is locked, you should not add or remove objects; - cpBool locked; + int locked; // Time stamp. Is incremented on every call to cpSpaceStep(). cpTimestamp stamp; @@ -73,6 +72,9 @@ // List of groups of sleeping bodies. cpArray *sleepingComponents; + // List of bodies that have been flagged to be awoken. + cpArray *rousedBodies; + // List of active arbiters for the impulse solver. cpArray* arbiters, pooledArbiters; @@ -278,6 +280,8 @@ space.bodies = cpArrayNew(0); space.sleepingComponents = cpArrayNew(0); + space.rousedBodies = cpArrayNew(0); + space.sleepTimeThreshold = INFINITY; space.idleSpeedThreshold = 0.0f; @@ -315,6 +319,7 @@ cpArrayFree(space.bodies); cpArrayFree(space.sleepingComponents); + cpArrayFree(space.rousedBodies); cpArrayFree(space.constraints); @@ -448,7 +453,7 @@ cpSpaceAddShape(cpSpace *space, cpShape *shape) { cpBody *_body = shape._body; - if(!_body || _body == &space.staticBody) return cpSpaceAddStaticShape(space, shape); + if(!_body || cpBodyIsStatic(_body)) return cpSpaceAddStaticShape(space, shape); assert(!cpHashSetFind(space.activeShapes.handleSet, shape.hashid, shape), "Cannot add the same shape more than once."); @@ -623,3 +628,51 @@ cpSpaceHashRehashObject(space.staticShapes, shape, shape.hashid); } +void +cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data) +{ + cpArray *bodies = space.bodies; + + for(int i=0; i<bodies.num; i++){ + func(cast(cpBody *)bodies.arr[i], data); + } + + cpArray *components = space.sleepingComponents; + for(int i=0; i<components.num; i++){ + cpBody *root = cast(cpBody *)components.arr[i]; + cpBody *_body = root, next; + do { + next = _body.node.next; + func(_body , data); + } while((_body = next) != root); + } +} + +// chipmunk_private.h + +//void *cpSpaceGetPostStepData(cpSpace *space, void *obj); + +//void cpSpaceActivateBody(cpSpace *space, cpBody *body); + +static void +cpSpaceLock(cpSpace *space) +{ + space.locked++; +} + +static void +cpSpaceUnlock(cpSpace *space) +{ + space.locked--; + assert(space.locked >= 0, "Internal error:Space lock underflow."); + + if(!space.locked){ + cpArray *waking = space.rousedBodies; + for(int i=0, count=waking.num; i<count; i++){ + cpSpaceActivateBody(space, cast(cpBody *)waking.arr[i]); + } + + waking.num = 0; + } +} +
--- a/trunk/chipmunkd/cpSpaceComponent.d Mon Dec 13 21:40:56 2010 +0100 +++ b/trunk/chipmunkd/cpSpaceComponent.d Thu Dec 16 00:33:06 2010 +0100 @@ -35,6 +35,21 @@ } } +void +cpSpaceActivateBody(cpSpace *space, cpBody *_body) +{ + if(space.locked){ + // cpSpaceActivateBody() is called again once the space is unlocked + cpArrayPush(space.rousedBodies, _body); + } else { + cpArrayPush(space.bodies, _body); + for(cpShape *shape=_body.shapesList; shape; shape=shape.next){ + cpSpaceHashRemove(space.staticShapes, shape, shape.hashid); + cpSpaceHashInsert(space.activeShapes, shape, shape.hashid, shape.bb); + } + } +} + static void componentActivate(cpBody *root) { @@ -42,22 +57,16 @@ cpSpace *space = root.space; assert(space, "Trying to activate a body that was never added to a space."); - assert(!space.locked, "Bodies can not be awakened during a query or a call to cpSpaceSte(). Put these calls into a post-step callback."); - - cpBody *_body = root; - cpBody *next; - do { - next = _body.node.next; - - cpFloat idleTime = (cpBodyIsStatic(_body) ? cast(cpFloat)INFINITY : 0.0f); - cpComponentNode node = {null, null, 0, idleTime}; - _body.node = node; - if(!cpBodyIsRogue(_body)) cpArrayPush(space.bodies, _body); - - for(cpShape *shape=_body.shapesList; shape; shape=shape.next){ - cpSpaceHashRemove(space.staticShapes, shape, shape.hashid); - cpSpaceHashInsert(space.activeShapes, shape, shape.hashid, shape.bb); - } + + cpBody *_body = root, next; + do { + next = _body.node.next; + + cpComponentNode node = {null, null, 0, 0.0f}; + _body.node = node; + + cpSpaceActivateBody(space, _body); + } while((_body = next) != root); cpArrayDeleteObj(space.sleepingComponents, root); @@ -66,16 +75,15 @@ void cpBodyActivate(cpBody *_body) { - // Reset the idle time even if it's not in a currently sleeping component - // Like a body resting on or jointed to a rogue body. - if(!cpBodyIsStatic(_body)) _body.node.idleTime = 0.0f; - componentActivate(componentNodeRoot(_body)); + //NOTE: dmd compiler bug when useing -inline + auto foo = componentNodeRoot(_body); + componentActivate(foo); } static void mergeBodies(cpSpace *space, cpArray *components, cpArray *rogueBodies, cpBody *a, cpBody *b) { - // Don't merge with the static body + // Ignore connections to static bodies if(cpBodyIsStatic(a) || cpBodyIsStatic(b)) return; cpBody *a_root = componentNodeRoot(a); @@ -91,9 +99,9 @@ componentActivate(b_root); } - // Add any rogue bodies (bodies not added to the space) - if(cpBodyIsRogue(a)) cpArrayPush(rogueBodies, a); - if(cpBodyIsRogue(b)) cpArrayPush(rogueBodies, b); + // Add any rogue bodies found to the list and reset the idle time of anything they touch. + if(cpBodyIsRogue(a)){ cpArrayPush(rogueBodies, a); b.node.idleTime = 0.0f; } + if(cpBodyIsRogue(b)){ cpArrayPush(rogueBodies, b); a.node.idleTime = 0.0f; } componentNodeMerge(a_root, b_root); } @@ -142,10 +150,11 @@ cpArray *rogueBodies = cpArrayNew(16); cpArray *arbiters = space.arbiters; cpArray *constraints = space.constraints; - cpArray *components = cpArrayNew(bodies.num/8); + cpArray *components = cpArrayNew(space.sleepingComponents.num); cpFloat dv = space.idleSpeedThreshold; cpFloat dvsq = (dv ? dv*dv : cpvdot(space.gravity, space.gravity)*dt*dt); + // update idling for(int i=0; i<bodies.num; i++){ cpBody *_body = cast(cpBody*)bodies.arr[i]; @@ -165,10 +174,8 @@ } // iterate bodies and add them to their components - for(int i=0; i<bodies.num; i++) - addToComponent(cast(cpBody*)bodies.arr[i], components); - for(int i=0; i<rogueBodies.num; i++) - addToComponent(cast(cpBody*)rogueBodies.arr[i], components); + for(int i=0; i<bodies.num; i++) addToComponent(cast(cpBody*)bodies.arr[i], components); + for(int i=0; i<rogueBodies.num; i++) addToComponent(cast(cpBody*)rogueBodies.arr[i], components); // iterate components, copy or deactivate for(int i=0; i<components.num; i++){ @@ -180,9 +187,8 @@ next = _body.node.next; if(!cpBodyIsRogue(_body)) cpArrayPush(newBodies, _body); - _body.node.next = null; - _body.node.parent = null; - _body.node.rank = 0; + cpComponentNode node = {null, null, 0, _body.node.idleTime}; + _body.node = node; } while((_body = next) != root); } else { cpBody *_body = root; @@ -224,9 +230,8 @@ if(cpBodyIsSleeping(_body)) return; for(cpShape *shape = _body.shapesList; shape; shape = shape.next){ + cpShapeCacheBB(shape); cpSpaceHashRemove(space.activeShapes, shape, shape.hashid); - - cpShapeCacheBB(shape); cpSpaceHashInsert(space.staticShapes, shape, shape.hashid, shape.bb); } @@ -248,19 +253,11 @@ static void activateTouchingHelper(cpShape *shape, cpContactPointSet *points, cpArray **bodies){ - if(*bodies == null) (*bodies) = cpArrayNew(0); - cpArrayPush(*bodies, shape._body); + cpBodyActivate(shape._body); } void cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape){ cpArray *bodies = null; cpSpaceShapeQuery(space, shape, cast(cpSpaceShapeQueryFunc)&activateTouchingHelper, &bodies); - - if(bodies){ - for(int i=0; i<bodies.num; i++){ - cpBody *_body = cast(cpBody *)bodies.arr[i]; - cpBodyActivate(_body); - } - } }
--- a/trunk/chipmunkd/cpSpaceQuery.d Mon Dec 13 21:40:56 2010 +0100 +++ b/trunk/chipmunkd/cpSpaceQuery.d Thu Dec 16 00:33:06 2010 +0100 @@ -29,10 +29,10 @@ { pointQueryContext context = {layers, group, func, data}; - cpBool locked = space.locked; space.locked = cpTrue; { + cpSpaceLock(space);{ cpSpaceHashPointQuery(space.activeShapes, point, cast(cpSpaceHashQueryFunc)&pointQueryHelper, &context); cpSpaceHashPointQuery(space.staticShapes, point, cast(cpSpaceHashQueryFunc)&pointQueryHelper, &context); - } space.locked = locked; + } cpSpaceUnlock(space); } static void @@ -50,15 +50,6 @@ return shape; } -void -cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data) -{ - cpArray *bodies = space.bodies; - - for(int i=0; i<bodies.num; i++) - func(cast(cpBody *)bodies.arr[i], data); -} - //#pragma mark Segment Query Functions struct segQueryContext { @@ -92,10 +83,10 @@ func, }; - cpBool locked = space.locked; space.locked = cpTrue; { + cpSpaceLock(space);{ cpSpaceHashSegmentQuery(space.staticShapes, &context, start, end, 1.0f, cast(cpSpaceHashSegmentQueryFunc)&segQueryFunc, data); cpSpaceHashSegmentQuery(space.activeShapes, &context, start, end, 1.0f, cast(cpSpaceHashSegmentQueryFunc)&segQueryFunc, data); - } space.locked = locked; + } cpSpaceUnlock(space); } struct segQueryFirstContext { @@ -168,10 +159,10 @@ { bbQueryContext context = {layers, group, func, data}; - cpBool locked = space.locked; space.locked = cpTrue; { + cpSpaceLock(space);{ cpSpaceHashQuery(space.activeShapes, &bb, bb, cast(cpSpaceHashQueryFunc)&bbQueryHelper, &context); cpSpaceHashQuery(space.staticShapes, &bb, bb, cast(cpSpaceHashQueryFunc)&bbQueryHelper, &context); - } space.locked = locked; + } cpSpaceUnlock(space); } //#pragma mark Shape Query Functions @@ -226,10 +217,10 @@ cpBB bb = cpShapeCacheBB(shape); shapeQueryContext context = {func, data, cpFalse}; - cpBool locked = space.locked; space.locked = cpTrue; { + cpSpaceLock(space);{ cpSpaceHashQuery(space.activeShapes, shape, bb, cast(cpSpaceHashQueryFunc)&shapeQueryHelper, &context); cpSpaceHashQuery(space.staticShapes, shape, bb, cast(cpSpaceHashQueryFunc)&shapeQueryHelper, &context); - } space.locked = locked; + } cpSpaceUnlock(space); return context.anyCollision; }
--- a/trunk/chipmunkd/cpSpaceStep.d Mon Dec 13 21:40:56 2010 +0100 +++ b/trunk/chipmunkd/cpSpaceStep.d Thu Dec 16 00:33:06 2010 +0100 @@ -19,21 +19,21 @@ // //#pragma mark Post Step Callback Functions -struct postStepCallback { +struct PostStepCallback { cpPostStepFunc func; void *obj; void *data; } static cpBool -postStepFuncSetEql(postStepCallback *a, postStepCallback *b){ +postStepFuncSetEql(PostStepCallback *a, PostStepCallback *b){ return a.obj == b.obj; } static void * -postStepFuncSetTrans(postStepCallback *callback, void *ignored) +postStepFuncSetTrans(PostStepCallback *callback, void *ignored) { - postStepCallback *value = cast(postStepCallback *)cpmalloc(postStepCallback.sizeof); + PostStepCallback *value = cast(PostStepCallback *)cpmalloc(PostStepCallback.sizeof); (*value) = (*callback); return value; @@ -46,10 +46,22 @@ space.postStepCallbacks = cpHashSetNew(0, cast(cpHashSetEqlFunc)&postStepFuncSetEql, cast(cpHashSetTransFunc)&postStepFuncSetTrans); } - postStepCallback callback = {func, obj, data}; + PostStepCallback callback = {func, obj, data}; cpHashSetInsert(space.postStepCallbacks, cast(cpHashValue)cast(size_t)obj, &callback, null); } +void * +cpSpaceGetPostStepData(cpSpace *space, void *obj) +{ + if(space.postStepCallbacks){ + PostStepCallback query = {null, obj, null}; + PostStepCallback *callback = cast(PostStepCallback *)cpHashSetFind(space.postStepCallbacks, cast(cpHashValue)cast(size_t)obj, &query); + return (callback ? callback.data : null); + } else { + return null; + } +} + //#pragma mark Contact Buffer Functions enum CP_CONTACTS_BUFFER_SIZE = ((CP_BUFFER_BYTES - cpContactBufferHeader.sizeof)/cpContact.sizeof); @@ -253,7 +265,7 @@ // Hashset filter func to call and throw away post step callbacks. static void -postStepCallbackSetIter(postStepCallback *callback, cpSpace *space) +postStepCallbackSetIter(PostStepCallback *callback, cpSpace *space) { callback.func(space, callback.obj, callback.data); cpfree(callback); @@ -269,7 +281,6 @@ cpSpaceStep(cpSpace *space, cpFloat dt) { if(!dt) return; // don't step if the timestep is 0! - cpFloat dt_inv = 1.0f/dt; cpArray *bodies = space.bodies; @@ -287,7 +298,7 @@ // Pre-cache BBoxes and shape data. cpSpaceHashEach(space.activeShapes, cast(cpSpaceHashIterator)&updateBBCache, null); - space.locked = cpTrue; + cpSpaceLock(space); // Collide! cpSpacePushFreshContactBuffer(space); @@ -295,7 +306,7 @@ cpSpaceHashEach(space.activeShapes, cast(cpSpaceHashIterator)&active2staticIter, space); cpSpaceHashQueryRehash(space.activeShapes, cast(cpSpaceHashQueryFunc)&queryFunc, space); - space.locked = cpFalse; + cpSpaceUnlock(space); // If body sleeping is enabled, do that now. if(space.sleepTimeThreshold != INFINITY){ @@ -351,7 +362,7 @@ } } - space.locked = cpTrue; + cpSpaceLock(space); // run the post solve callbacks for(int i=0; i<arbiters.num; i++){ @@ -363,7 +374,7 @@ arb.state = cpArbiterState.cpArbiterStateNormal; } - space.locked = cpFalse; + cpSpaceUnlock(space); // Run the post step callbacks // Loop because post step callbacks may create more post step callbacks