diff trunk/chipmunkd/cpSpaceQuery.d @ 23:4ceef5833c8c

updated to chipmunk 5.3.3
author Extrawurst
date Fri, 10 Dec 2010 02:10:27 +0100
parents df4ebc8add66
children 80058cee1a77
line wrap: on
line diff
--- a/trunk/chipmunkd/cpSpaceQuery.d	Thu Dec 09 22:25:04 2010 +0100
+++ b/trunk/chipmunkd/cpSpaceQuery.d	Fri Dec 10 02:10:27 2010 +0100
@@ -28,8 +28,11 @@
 cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data)
 {
 	pointQueryContext context = {layers, group, func, data};
-	cpSpaceHashPointQuery(space.activeShapes, point, cast(cpSpaceHashQueryFunc)&pointQueryHelper, &context);
-	cpSpaceHashPointQuery(space.staticShapes, point, cast(cpSpaceHashQueryFunc)&pointQueryHelper, &context);
+	
+	cpBool locked = space.locked; space.locked = cpTrue; {
+		cpSpaceHashPointQuery(space.activeShapes, point, cast(cpSpaceHashQueryFunc)&pointQueryHelper, &context);
+		cpSpaceHashPointQuery(space.staticShapes, point, cast(cpSpaceHashQueryFunc)&pointQueryHelper, &context);
+	} space.locked = locked;
 }
 
 static void
@@ -89,8 +92,10 @@
 		func,
 	};
 	
-	cpSpaceHashSegmentQuery(space.staticShapes, &context, start, end, 1.0f, cast(cpSpaceHashSegmentQueryFunc)&segQueryFunc, data);
-	cpSpaceHashSegmentQuery(space.activeShapes, &context, start, end, 1.0f, cast(cpSpaceHashSegmentQueryFunc)&segQueryFunc, data);
+	cpBool locked = space.locked; space.locked = cpTrue; {
+		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;
 }
 
 struct segQueryFirstContext {
@@ -162,6 +167,69 @@
 cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data)
 {
 	bbQueryContext context = {layers, group, func, data};
+	
+	cpBool locked = space.locked; space.locked = cpTrue; {
 	cpSpaceHashQuery(space.activeShapes, &bb, bb, cast(cpSpaceHashQueryFunc)&bbQueryHelper, &context);
 	cpSpaceHashQuery(space.staticShapes, &bb, bb, cast(cpSpaceHashQueryFunc)&bbQueryHelper, &context);
+	} space.locked = locked;
 }
+
+//#pragma mark Shape Query Functions
+
+struct shapeQueryContext {
+	cpSpaceShapeQueryFunc func;
+	void *data;
+	cpBool anyCollision;
+}
+
+// Callback from the spatial hash.
+static void
+shapeQueryHelper(cpShape *a, cpShape *b, shapeQueryContext *context)
+{
+	// Reject any of the simple cases
+	if(
+		(a.group && a.group == b.group) ||
+		!(a.layers & b.layers) ||
+		a.sensor || b.sensor
+	) return;
+	
+	cpContact contacts[CP_MAX_CONTACTS_PER_ARBITER];
+	int numContacts = 0;
+	
+	// Shape 'a' should have the lower shape type. (required by cpCollideShapes() )
+	if(a.klass.type <= b.klass.type){
+		numContacts = cpCollideShapes(a, b, contacts.ptr);
+	} else {
+		numContacts = cpCollideShapes(b, a, contacts.ptr);
+		for(int i=0; i<numContacts; i++) contacts[i].n = cpvneg(contacts[i].n);
+	}
+	
+	if(numContacts){
+		context.anyCollision = cpTrue;
+		
+		if(context.func){
+			cpContactPointSet set; set.count = numContacts;
+			for(int i=0; i<set.count; i++){
+				set.points[i].point = contacts[i].p;
+				set.points[i].normal = contacts[i].p;
+				set.points[i].dist = contacts[i].dist;
+			}
+			
+			context.func(b, &set, context.data);
+		}
+	}
+}
+
+cpBool
+cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data)
+{
+	cpBB bb = cpShapeCacheBB(shape);
+	shapeQueryContext context = {func, data, cpFalse};
+	
+	cpBool locked = space.locked; space.locked = cpTrue; {
+		cpSpaceHashQuery(space.activeShapes, shape, bb, cast(cpSpaceHashQueryFunc)&shapeQueryHelper, &context);
+		cpSpaceHashQuery(space.staticShapes, shape, bb, cast(cpSpaceHashQueryFunc)&shapeQueryHelper, &context);
+	} space.locked = locked;
+	
+	return context.anyCollision;
+}