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

initial commit
author Extrawurst
date Thu, 02 Dec 2010 02:11:26 +0100
parents
children df4ebc8add66
comparison
equal deleted inserted replaced
3:81145a61c2fe 4:7ebbd4d05553
1
2 // written in the D programming language
3
4 module chipmunkd.cpSpaceQuery;
5
6 import chipmunkd.chipmunk;
7 import chipmunkd.chipmunk_types_h;
8
9 struct pointQueryContext {
10 cpLayers layers;
11 cpGroup group;
12 cpSpacePointQueryFunc func;
13 void *data;
14 }
15
16 static void
17 pointQueryHelper(cpVect *point, cpShape *shape, pointQueryContext *context)
18 {
19 if(
20 !(shape.group && context.group == shape.group) && (context.layers&shape.layers) &&
21 cpShapePointQuery(shape, *point)
22 ){
23 context.func(shape, context.data);
24 }
25 }
26
27 void
28 cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data)
29 {
30 pointQueryContext context = {layers, group, func, data};
31 cpSpaceHashPointQuery(space.activeShapes, point, cast(cpSpaceHashQueryFunc)&pointQueryHelper, &context);
32 cpSpaceHashPointQuery(space.staticShapes, point, cast(cpSpaceHashQueryFunc)&pointQueryHelper, &context);
33 }
34
35 static void
36 rememberLastPointQuery(cpShape *shape, cpShape **outShape)
37 {
38 if(!shape.sensor) *outShape = shape;
39 }
40
41 cpShape *
42 cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group)
43 {
44 cpShape *shape = null;
45 cpSpacePointQuery(space, point, layers, group, cast(cpSpacePointQueryFunc)&rememberLastPointQuery, &shape);
46
47 return shape;
48 }
49
50 void
51 cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data)
52 {
53 cpArray *bodies = space.bodies;
54
55 for(int i=0; i<bodies.num; i++)
56 func(cast(cpBody *)bodies.arr[i], data);
57 }
58
59 //#pragma mark Segment Query Functions
60
61 struct segQueryContext {
62 cpVect start, end;
63 cpLayers layers;
64 cpGroup group;
65 cpSpaceSegmentQueryFunc func;
66 }
67
68 static cpFloat
69 segQueryFunc(segQueryContext *context, cpShape *shape, void *data)
70 {
71 cpSegmentQueryInfo info;
72
73 if(
74 !(shape.group && context.group == shape.group) && (context.layers&shape.layers) &&
75 cpShapeSegmentQuery(shape, context.start, context.end, &info)
76 ){
77 context.func(shape, info.t, info.n, data);
78 }
79
80 return 1.0f;
81 }
82
83 void
84 cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data)
85 {
86 segQueryContext context = {
87 start, end,
88 layers, group,
89 func,
90 };
91
92 cpSpaceHashSegmentQuery(space.staticShapes, &context, start, end, 1.0f, cast(cpSpaceHashSegmentQueryFunc)&segQueryFunc, data);
93 cpSpaceHashSegmentQuery(space.activeShapes, &context, start, end, 1.0f, cast(cpSpaceHashSegmentQueryFunc)&segQueryFunc, data);
94 }
95
96 struct segQueryFirstContext {
97 cpVect start, end;
98 cpLayers layers;
99 cpGroup group;
100 }
101
102 static cpFloat
103 segQueryFirst(segQueryFirstContext *context, cpShape *shape, cpSegmentQueryInfo *_out)
104 {
105 cpSegmentQueryInfo info;
106
107 if(
108 !(shape.group && context.group == shape.group) &&
109 (context.layers&shape.layers) &&
110 !shape.sensor &&
111 cpShapeSegmentQuery(shape, context.start, context.end, &info) &&
112 info.t < _out.t
113 ){
114 *_out = info;
115 }
116
117 return _out.t;
118 }
119
120 cpShape *
121 cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *_out)
122 {
123 cpSegmentQueryInfo info = {null, 1.0f, cpvzero};
124 if(_out){
125 (*_out) = info;
126 } else {
127 _out = &info;
128 }
129
130 segQueryFirstContext context = {
131 start, end,
132 layers, group
133 };
134
135 cpSpaceHashSegmentQuery(space.staticShapes, &context, start, end, 1.0f, cast(cpSpaceHashSegmentQueryFunc)&segQueryFirst, _out);
136 cpSpaceHashSegmentQuery(space.activeShapes, &context, start, end, _out.t, cast(cpSpaceHashSegmentQueryFunc)&segQueryFirst, _out);
137
138 return _out.shape;
139 }
140
141 //#pragma mark BB Query functions
142
143 struct bbQueryContext {
144 cpLayers layers;
145 cpGroup group;
146 cpSpaceBBQueryFunc func;
147 void *data;
148 }
149
150 static void
151 bbQueryHelper(cpBB *bb, cpShape *shape, bbQueryContext *context)
152 {
153 if(
154 !(shape.group && context.group == shape.group) && (context.layers&shape.layers) &&
155 cpBBintersects(*bb, shape.bb)
156 ){
157 context.func(shape, context.data);
158 }
159 }
160
161 void
162 cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data)
163 {
164 bbQueryContext context = {layers, group, func, data};
165 cpSpaceHashQuery(space.activeShapes, &bb, bb, cast(cpSpaceHashQueryFunc)&bbQueryHelper, &context);
166 cpSpaceHashQuery(space.staticShapes, &bb, bb, cast(cpSpaceHashQueryFunc)&bbQueryHelper, &context);
167 }