diff trunk/chipmunkd/cpSpaceQuery.d @ 4:7ebbd4d05553

initial commit
author Extrawurst
date Thu, 02 Dec 2010 02:11:26 +0100
parents
children df4ebc8add66
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trunk/chipmunkd/cpSpaceQuery.d	Thu Dec 02 02:11:26 2010 +0100
@@ -0,0 +1,167 @@
+
+// written in the D programming language
+
+module chipmunkd.cpSpaceQuery;
+
+import chipmunkd.chipmunk;
+import chipmunkd.chipmunk_types_h;
+
+struct pointQueryContext {
+	cpLayers layers;
+	cpGroup group;
+	cpSpacePointQueryFunc func;
+	void *data;
+}
+
+static void 
+pointQueryHelper(cpVect *point, cpShape *shape, pointQueryContext *context)
+{
+	if(
+		!(shape.group && context.group == shape.group) && (context.layers&shape.layers) &&
+		cpShapePointQuery(shape, *point)
+	){
+		context.func(shape, context.data);
+	}
+}
+
+void
+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);
+}
+
+static void
+rememberLastPointQuery(cpShape *shape, cpShape **outShape)
+{
+	if(!shape.sensor) *outShape = shape;
+}
+
+cpShape *
+cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group)
+{
+	cpShape *shape = null;
+	cpSpacePointQuery(space, point, layers, group, cast(cpSpacePointQueryFunc)&rememberLastPointQuery, &shape);
+	
+	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 {
+	cpVect start, end;
+	cpLayers layers;
+	cpGroup group;
+	cpSpaceSegmentQueryFunc func;
+}
+
+static cpFloat
+segQueryFunc(segQueryContext *context, cpShape *shape, void *data)
+{
+	cpSegmentQueryInfo info;
+	
+	if(
+		!(shape.group && context.group == shape.group) && (context.layers&shape.layers) &&
+		cpShapeSegmentQuery(shape, context.start, context.end, &info)
+	){
+		context.func(shape, info.t, info.n, data);
+	}
+	
+	return 1.0f;
+}
+
+void
+cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data)
+{
+	segQueryContext context = {
+		start, end,
+		layers, group,
+		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);
+}
+
+struct segQueryFirstContext {
+	cpVect start, end;
+	cpLayers layers;
+	cpGroup group;
+}
+
+static cpFloat
+segQueryFirst(segQueryFirstContext *context, cpShape *shape, cpSegmentQueryInfo *_out)
+{
+	cpSegmentQueryInfo info;
+	
+	if(
+		!(shape.group && context.group == shape.group) &&
+		(context.layers&shape.layers) &&
+		!shape.sensor &&
+		cpShapeSegmentQuery(shape, context.start, context.end, &info) &&
+		info.t < _out.t
+	){
+		*_out = info;
+	}
+	
+	return _out.t;
+}
+
+cpShape *
+cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *_out)
+{
+	cpSegmentQueryInfo info = {null, 1.0f, cpvzero};
+	if(_out){
+		(*_out) = info;
+  } else {
+		_out = &info;
+	}
+	
+	segQueryFirstContext context = {
+		start, end,
+		layers, group
+	};
+	
+	cpSpaceHashSegmentQuery(space.staticShapes, &context, start, end, 1.0f, cast(cpSpaceHashSegmentQueryFunc)&segQueryFirst, _out);
+	cpSpaceHashSegmentQuery(space.activeShapes, &context, start, end, _out.t, cast(cpSpaceHashSegmentQueryFunc)&segQueryFirst, _out);
+	
+	return _out.shape;
+}
+
+//#pragma mark BB Query functions
+
+struct bbQueryContext {
+	cpLayers layers;
+	cpGroup group;
+	cpSpaceBBQueryFunc func;
+	void *data;
+}
+
+static void 
+bbQueryHelper(cpBB *bb, cpShape *shape, bbQueryContext *context)
+{
+	if(
+		!(shape.group && context.group == shape.group) && (context.layers&shape.layers) &&
+		cpBBintersects(*bb, shape.bb)
+	){
+		context.func(shape, context.data);
+	}
+}
+
+void
+cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data)
+{
+	bbQueryContext context = {layers, group, func, data};
+	cpSpaceHashQuery(space.activeShapes, &bb, bb, cast(cpSpaceHashQueryFunc)&bbQueryHelper, &context);
+	cpSpaceHashQuery(space.staticShapes, &bb, bb, cast(cpSpaceHashQueryFunc)&bbQueryHelper, &context);
+}