Mercurial > projects > chipmunkd
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 } |