4
|
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 }
|