diff options
Diffstat (limited to 'libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp')
-rw-r--r-- | libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp | 514 |
1 files changed, 514 insertions, 0 deletions
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp b/libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp new file mode 100644 index 0000000..91e1d37 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/src/gim_boxpruning.cpp | |||
@@ -0,0 +1,514 @@ | |||
1 | |||
2 | /* | ||
3 | ----------------------------------------------------------------------------- | ||
4 | This source file is part of GIMPACT Library. | ||
5 | |||
6 | For the latest info, see http://gimpact.sourceforge.net/ | ||
7 | |||
8 | Copyright (c) 2006 Francisco Leon. C.C. 80087371. | ||
9 | email: projectileman@yahoo.com | ||
10 | |||
11 | This library is free software; you can redistribute it and/or | ||
12 | modify it under the terms of EITHER: | ||
13 | (1) The GNU Lesser General Public License as published by the Free | ||
14 | Software Foundation; either version 2.1 of the License, or (at | ||
15 | your option) any later version. The text of the GNU Lesser | ||
16 | General Public License is included with this library in the | ||
17 | file GIMPACT-LICENSE-LGPL.TXT. | ||
18 | (2) The BSD-style license that is included with this library in | ||
19 | the file GIMPACT-LICENSE-BSD.TXT. | ||
20 | |||
21 | This library is distributed in the hope that it will be useful, | ||
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files | ||
24 | GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. | ||
25 | |||
26 | ----------------------------------------------------------------------------- | ||
27 | */ | ||
28 | |||
29 | |||
30 | #include "GIMPACT/gim_boxpruning.h" | ||
31 | |||
32 | |||
33 | |||
34 | //! Allocate memory for all aabb set. | ||
35 | void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT count) | ||
36 | { | ||
37 | aabbset->m_count = count; | ||
38 | aabbset->m_boxes = (aabb3f *)gim_alloc(sizeof(aabb3f)*count); | ||
39 | |||
40 | if(count<GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES) | ||
41 | { | ||
42 | aabbset->m_maxcoords = 0; | ||
43 | aabbset->m_sorted_mincoords = 0; | ||
44 | } | ||
45 | else | ||
46 | { | ||
47 | aabbset->m_maxcoords = (GUINT *)gim_alloc(sizeof(GUINT)*aabbset->m_count ); | ||
48 | aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count); | ||
49 | } | ||
50 | aabbset->m_shared = 0; | ||
51 | INVALIDATE_AABB(aabbset->m_global_bound); | ||
52 | } | ||
53 | |||
54 | //! Destroys the aabb set. | ||
55 | void gim_aabbset_destroy(GIM_AABB_SET * aabbset) | ||
56 | { | ||
57 | aabbset->m_count = 0; | ||
58 | if(aabbset->m_shared==0) | ||
59 | { | ||
60 | gim_free(aabbset->m_boxes,0); | ||
61 | gim_free(aabbset->m_maxcoords,0); | ||
62 | gim_free(aabbset->m_sorted_mincoords,0); | ||
63 | } | ||
64 | aabbset->m_boxes = 0; | ||
65 | aabbset->m_sorted_mincoords = 0; | ||
66 | aabbset->m_maxcoords = 0; | ||
67 | } | ||
68 | |||
69 | void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset) | ||
70 | { | ||
71 | aabb3f * paabb = aabbset->m_boxes; | ||
72 | aabb3f * globalbox = &aabbset->m_global_bound; | ||
73 | AABB_COPY((*globalbox),(*paabb)); | ||
74 | |||
75 | GUINT count = aabbset->m_count-1; | ||
76 | paabb++; | ||
77 | while(count) | ||
78 | { | ||
79 | MERGEBOXES(*globalbox,*paabb) | ||
80 | paabb++; | ||
81 | count--; | ||
82 | } | ||
83 | } | ||
84 | |||
85 | |||
86 | //! Sorts the boxes for box prunning. | ||
87 | /*! | ||
88 | 1) find the integer representation of the aabb coords | ||
89 | 2) Sorts the min coords | ||
90 | 3) Calcs the global bound | ||
91 | \pre aabbset must be allocated. And the boxes must be already set. | ||
92 | \param aabbset | ||
93 | \param calc_global_bound If 1 , calcs the global bound | ||
94 | \post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates | ||
95 | */ | ||
96 | void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound) | ||
97 | { | ||
98 | if(aabbset->m_sorted_mincoords == 0) | ||
99 | {//allocate | ||
100 | aabbset->m_maxcoords = (GUINT *)gim_alloc(sizeof(GUINT)*aabbset->m_count ); | ||
101 | aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count); | ||
102 | } | ||
103 | |||
104 | GUINT i, count = aabbset->m_count; | ||
105 | aabb3f * paabb = aabbset->m_boxes; | ||
106 | GUINT * maxcoords = aabbset->m_maxcoords; | ||
107 | GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords; | ||
108 | |||
109 | if(count<860)//Calibrated on a Pentium IV | ||
110 | { | ||
111 | //Sort by quick sort | ||
112 | //Calculate keys | ||
113 | for(i=0;i<count;i++) | ||
114 | { | ||
115 | GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]); | ||
116 | GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,sorted_tokens[i].m_key); | ||
117 | sorted_tokens[i].m_value = i; | ||
118 | } | ||
119 | GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , sorted_tokens, count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | //Sort by radix sort | ||
124 | GIM_RSORT_TOKEN * unsorted = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN )*count); | ||
125 | //Calculate keys | ||
126 | for(i=0;i<count;i++) | ||
127 | { | ||
128 | GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]); | ||
129 | GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,unsorted[i].m_key); | ||
130 | unsorted[i].m_value = i; | ||
131 | } | ||
132 | GIM_RADIX_SORT_RTOKENS(unsorted,sorted_tokens,count); | ||
133 | gim_free(unsorted,0); | ||
134 | } | ||
135 | |||
136 | if(calc_global_bound) gim_aabbset_calc_global_bound(aabbset); | ||
137 | } | ||
138 | |||
139 | //utility macros | ||
140 | |||
141 | /*#define PUSH_PAIR(i,j,pairset)\ | ||
142 | {\ | ||
143 | GIM_PAIR _pair={i,j};\ | ||
144 | GIM_DYNARRAY_PUSH_ITEM(GIM_PAIR,pairset,_pair);\ | ||
145 | }*/ | ||
146 | |||
147 | #define PUSH_PAIR(i,j,pairset)\ | ||
148 | {\ | ||
149 | GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\ | ||
150 | GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\ | ||
151 | _pair->m_index1 = i;\ | ||
152 | _pair->m_index2 = j;\ | ||
153 | } | ||
154 | |||
155 | #define PUSH_PAIR_INV(i,j,pairset)\ | ||
156 | {\ | ||
157 | GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\ | ||
158 | GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\ | ||
159 | _pair->m_index1 = j;\ | ||
160 | _pair->m_index2 = i;\ | ||
161 | } | ||
162 | |||
163 | #define FIND_OVERLAPPING_FOWARD(\ | ||
164 | curr_index,\ | ||
165 | test_count,\ | ||
166 | test_aabb,\ | ||
167 | max_coord_uint,\ | ||
168 | sorted_tokens,\ | ||
169 | aabbarray,\ | ||
170 | pairset,\ | ||
171 | push_pair_macro)\ | ||
172 | {\ | ||
173 | GUINT _i = test_count;\ | ||
174 | char _intersected;\ | ||
175 | GIM_RSORT_TOKEN * _psorted_tokens = sorted_tokens;\ | ||
176 | while(max_coord_uint >= _psorted_tokens->m_key && _i>0)\ | ||
177 | {\ | ||
178 | AABBCOLLISION(_intersected,test_aabb,aabbarray[_psorted_tokens->m_value]);\ | ||
179 | if(_intersected)\ | ||
180 | {\ | ||
181 | push_pair_macro(curr_index, _psorted_tokens->m_value,pairset);\ | ||
182 | }\ | ||
183 | _psorted_tokens++;\ | ||
184 | _i--;\ | ||
185 | }\ | ||
186 | } | ||
187 | |||
188 | //! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set. | ||
189 | /*! | ||
190 | \pre aabbset must be allocated and sorted, the boxes must be already set. | ||
191 | \param aabbset Must be sorted. Global bound isn't required | ||
192 | \param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100) | ||
193 | */ | ||
194 | void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs) | ||
195 | { | ||
196 | collision_pairs->m_size = 0; | ||
197 | GUINT count = aabbset->m_count; | ||
198 | aabb3f * paabb = aabbset->m_boxes; | ||
199 | GUINT * maxcoords = aabbset->m_maxcoords; | ||
200 | GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords; | ||
201 | aabb3f test_aabb; | ||
202 | while(count>1) | ||
203 | { | ||
204 | ///current cache variables | ||
205 | GUINT curr_index = sorted_tokens->m_value; | ||
206 | GUINT max_coord_uint = maxcoords[curr_index]; | ||
207 | AABB_COPY(test_aabb,paabb[curr_index]); | ||
208 | |||
209 | ///next pairs | ||
210 | sorted_tokens++; | ||
211 | count--; | ||
212 | FIND_OVERLAPPING_FOWARD( curr_index, count, test_aabb, max_coord_uint, sorted_tokens , paabb, (*collision_pairs),PUSH_PAIR); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | //! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set. | ||
217 | /*! | ||
218 | \pre aabbset must be allocated, the boxes must be already set. | ||
219 | \param aabbset Global bound isn't required. Doen't need to be sorted. | ||
220 | \param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100) | ||
221 | */ | ||
222 | void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs) | ||
223 | { | ||
224 | collision_pairs->m_size = 0; | ||
225 | GUINT i,j; | ||
226 | GUINT count = aabbset->m_count; | ||
227 | aabb3f * paabb = aabbset->m_boxes; | ||
228 | char intersected; | ||
229 | for (i=0;i< count-1 ;i++ ) | ||
230 | { | ||
231 | for (j=i+1;j<count ;j++ ) | ||
232 | { | ||
233 | AABBCOLLISION(intersected,paabb[i],paabb[j]); | ||
234 | if(intersected) | ||
235 | { | ||
236 | PUSH_PAIR(i,j,(*collision_pairs)); | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | |||
242 | //! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set. | ||
243 | /*! | ||
244 | \pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set. | ||
245 | \param aabbset1 Must be sorted, Global bound is required. | ||
246 | \param aabbset2 Must be sorted, Global bound is required. | ||
247 | \param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100) | ||
248 | */ | ||
249 | void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs) | ||
250 | { | ||
251 | char intersected; | ||
252 | collision_pairs->m_size = 0; | ||
253 | |||
254 | AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound); | ||
255 | if(intersected == 0) return; | ||
256 | |||
257 | GUINT count1 = aabbset1->m_count; | ||
258 | aabb3f * paabb1 = aabbset1->m_boxes; | ||
259 | GUINT * maxcoords1 = aabbset1->m_maxcoords; | ||
260 | GIM_RSORT_TOKEN * sorted_tokens1 = aabbset1->m_sorted_mincoords; | ||
261 | |||
262 | GUINT count2 = aabbset2->m_count; | ||
263 | aabb3f * paabb2 = aabbset2->m_boxes; | ||
264 | GUINT * maxcoords2 = aabbset2->m_maxcoords; | ||
265 | GIM_RSORT_TOKEN * sorted_tokens2 = aabbset2->m_sorted_mincoords; | ||
266 | |||
267 | GUINT curr_index; | ||
268 | |||
269 | GUINT max_coord_uint; | ||
270 | aabb3f test_aabb; | ||
271 | |||
272 | //Classify boxes | ||
273 | //Find Set intersection | ||
274 | aabb3f int_abbb; | ||
275 | BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb); | ||
276 | |||
277 | //Clasify set 1 | ||
278 | GIM_RSORT_TOKEN * classified_tokens1 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count1); | ||
279 | GUINT i,classified_count1 = 0,classified_count2 = 0; | ||
280 | |||
281 | |||
282 | for (i=0;i<count1;i++ ) | ||
283 | { | ||
284 | curr_index = sorted_tokens1[i].m_value; | ||
285 | AABBCOLLISION(intersected,paabb1[curr_index],int_abbb); | ||
286 | if(intersected) | ||
287 | { | ||
288 | classified_tokens1[classified_count1] = sorted_tokens1[i]; | ||
289 | classified_count1++; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | if(classified_count1==0) | ||
294 | { | ||
295 | gim_free(classified_tokens1 ,0); | ||
296 | return; // no pairs | ||
297 | } | ||
298 | |||
299 | //Clasify set 2 | ||
300 | GIM_RSORT_TOKEN * classified_tokens2 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count2); | ||
301 | |||
302 | for (i=0;i<count2;i++ ) | ||
303 | { | ||
304 | curr_index = sorted_tokens2[i].m_value; | ||
305 | AABBCOLLISION(intersected,paabb2[curr_index],int_abbb); | ||
306 | if(intersected) | ||
307 | { | ||
308 | classified_tokens2[classified_count2] = sorted_tokens2[i]; | ||
309 | classified_count2++; | ||
310 | } | ||
311 | } | ||
312 | |||
313 | if(classified_count2==0) | ||
314 | { | ||
315 | gim_free(classified_tokens1 ,0); | ||
316 | gim_free(classified_tokens2 ,0); | ||
317 | return; // no pairs | ||
318 | } | ||
319 | |||
320 | sorted_tokens1 = classified_tokens1; | ||
321 | sorted_tokens2 = classified_tokens2; | ||
322 | |||
323 | while(classified_count1>0&&classified_count2>0) | ||
324 | { | ||
325 | if(sorted_tokens1->m_key <= sorted_tokens2->m_key) | ||
326 | { | ||
327 | ///current cache variables | ||
328 | curr_index = sorted_tokens1->m_value; | ||
329 | max_coord_uint = maxcoords1[curr_index]; | ||
330 | AABB_COPY(test_aabb,paabb1[curr_index]); | ||
331 | ///next pairs | ||
332 | sorted_tokens1++; | ||
333 | classified_count1--; | ||
334 | FIND_OVERLAPPING_FOWARD( curr_index, classified_count2, test_aabb, max_coord_uint, sorted_tokens2 , paabb2, (*collision_pairs), PUSH_PAIR); | ||
335 | } | ||
336 | else ///Switch test | ||
337 | { | ||
338 | ///current cache variables | ||
339 | curr_index = sorted_tokens2->m_value; | ||
340 | max_coord_uint = maxcoords2[curr_index]; | ||
341 | AABB_COPY(test_aabb,paabb2[curr_index]); | ||
342 | ///next pairs | ||
343 | sorted_tokens2++; | ||
344 | classified_count2--; | ||
345 | FIND_OVERLAPPING_FOWARD( curr_index, classified_count1, test_aabb, max_coord_uint, sorted_tokens1 , paabb1, (*collision_pairs), PUSH_PAIR_INV ); | ||
346 | } | ||
347 | } | ||
348 | gim_free(classified_tokens1 ,0); | ||
349 | gim_free(classified_tokens2 ,0); | ||
350 | } | ||
351 | |||
352 | //! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set. | ||
353 | /*! | ||
354 | \pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set. | ||
355 | \param aabbset1 Must be sorted, Global bound is required. | ||
356 | \param aabbset2 Must be sorted, Global bound is required. | ||
357 | \param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100) | ||
358 | */ | ||
359 | void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs) | ||
360 | { | ||
361 | char intersected; | ||
362 | collision_pairs->m_size = 0; | ||
363 | AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound); | ||
364 | if(intersected == 0) return; | ||
365 | |||
366 | aabb3f int_abbb; | ||
367 | //Find Set intersection | ||
368 | BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb); | ||
369 | //Clasify set 1 | ||
370 | GUINT i,j; | ||
371 | GUINT classified_count = 0; | ||
372 | |||
373 | GUINT count = aabbset1->m_count; | ||
374 | aabb3f * paabb1 = aabbset1->m_boxes; | ||
375 | aabb3f * paabb2 = aabbset2->m_boxes; | ||
376 | |||
377 | GUINT * classified = (GUINT *) gim_alloc(sizeof(GUINT)*count); | ||
378 | |||
379 | for (i=0;i<count;i++ ) | ||
380 | { | ||
381 | AABBCOLLISION(intersected,paabb1[i],int_abbb); | ||
382 | if(intersected) | ||
383 | { | ||
384 | classified[classified_count] = i; | ||
385 | classified_count++; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | if(classified_count==0) return; // no pairs | ||
390 | |||
391 | //intesect set2 | ||
392 | count = aabbset2->m_count; | ||
393 | for (i=0;i<count;i++) | ||
394 | { | ||
395 | AABBCOLLISION(intersected,paabb2[i],int_abbb); | ||
396 | if(intersected) | ||
397 | { | ||
398 | for (j=0;j<classified_count;j++) | ||
399 | { | ||
400 | AABBCOLLISION(intersected,paabb2[i],paabb1[classified[j]]); | ||
401 | if(intersected) | ||
402 | { | ||
403 | PUSH_PAIR(classified[j],i,(*collision_pairs)); | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | } | ||
408 | gim_free(classified,0); | ||
409 | } | ||
410 | |||
411 | |||
412 | //! Initalizes the set. Sort Boxes if needed. | ||
413 | /*! | ||
414 | \pre aabbset must be allocated. And the boxes must be already set. | ||
415 | \post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box, | ||
416 | else it Sorts the entire set( Only applicable for large sets) | ||
417 | */ | ||
418 | void gim_aabbset_update(GIM_AABB_SET * aabbset) | ||
419 | { | ||
420 | if(aabbset->m_count < GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES) | ||
421 | {//Brute force approach | ||
422 | gim_aabbset_calc_global_bound(aabbset); | ||
423 | } | ||
424 | else | ||
425 | {//Sorted force approach | ||
426 | gim_aabbset_sort(aabbset,1); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | //! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set. | ||
431 | /*! | ||
432 | This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted. | ||
433 | |||
434 | \param aabbset Set of boxes. Sorting isn't required. | ||
435 | \param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100) | ||
436 | \pre aabbset must be allocated and initialized. | ||
437 | \post If aabbset->m_count >= GIM_MIN_SORTED_PRUNING_BOXES, then it calls to gim_aabbset_sort and then to gim_aabbset_self_intersections_sorted. | ||
438 | */ | ||
439 | void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs) | ||
440 | { | ||
441 | if(aabbset->m_count < GIM_MIN_SORTED_PRUNING_BOXES) | ||
442 | {//Brute force approach | ||
443 | gim_aabbset_self_intersections_brute_force(aabbset,collision_pairs); | ||
444 | } | ||
445 | else | ||
446 | {//Sorted force approach | ||
447 | gim_aabbset_sort(aabbset,0); | ||
448 | gim_aabbset_self_intersections_sorted(aabbset,collision_pairs); | ||
449 | } | ||
450 | } | ||
451 | |||
452 | //! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set. | ||
453 | /*! | ||
454 | \pre aabbset1 and aabbset2 must be allocated and updated. See . | ||
455 | \param aabbset1 Must be sorted, Global bound is required. | ||
456 | \param aabbset2 Must be sorted, Global bound is required. | ||
457 | \param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100) | ||
458 | */ | ||
459 | void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs) | ||
460 | { | ||
461 | if(aabbset1->m_sorted_mincoords == 0||aabbset2->m_sorted_mincoords == 0) | ||
462 | {//Brute force approach | ||
463 | gim_aabbset_bipartite_intersections_brute_force(aabbset1,aabbset2,collision_pairs); | ||
464 | } | ||
465 | else | ||
466 | {//Sorted force approach | ||
467 | gim_aabbset_bipartite_intersections_sorted(aabbset1,aabbset2,collision_pairs); | ||
468 | } | ||
469 | } | ||
470 | |||
471 | void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided) | ||
472 | { | ||
473 | collided->m_size = 0; | ||
474 | char intersected; | ||
475 | AABBCOLLISION(intersected,aabbset->m_global_bound,(*test_aabb)); | ||
476 | if(intersected == 0) return; | ||
477 | |||
478 | GUINT i; | ||
479 | GUINT count = aabbset->m_count; | ||
480 | aabb3f * paabb = aabbset->m_boxes; | ||
481 | aabb3f _testaabb; | ||
482 | AABB_COPY(_testaabb,*test_aabb); | ||
483 | |||
484 | for (i=0;i< count;i++ ) | ||
485 | { | ||
486 | AABBCOLLISION(intersected,paabb[i],_testaabb); | ||
487 | if(intersected) | ||
488 | { | ||
489 | GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),i); | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | |||
494 | void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided) | ||
495 | { | ||
496 | collided->m_size = 0; | ||
497 | char intersected; | ||
498 | GREAL tparam = 0; | ||
499 | BOX_INTERSECTS_RAY(aabbset->m_global_bound, vorigin, vdir, tparam, tmax,intersected); | ||
500 | if(intersected==0) return; | ||
501 | |||
502 | GUINT i; | ||
503 | GUINT count = aabbset->m_count; | ||
504 | aabb3f * paabb = aabbset->m_boxes; | ||
505 | |||
506 | for (i=0;i< count;i++ ) | ||
507 | { | ||
508 | BOX_INTERSECTS_RAY(paabb[i], vorigin, vdir, tparam, tmax,intersected); | ||
509 | if(intersected) | ||
510 | { | ||
511 | GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),i); | ||
512 | } | ||
513 | } | ||
514 | } | ||