Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00008
00010
00016
00017
00018
00020
00021
00022
00023
00024
00025
00026
00028
00029
00030
00032
00033 #include "Stdafx.h"
00034
00035 using namespace Opcode;
00036
00037 inline_ void FindRunningIndex(udword& index, float* array, udword* sorted, int last, float max)
00038 {
00039 int First=index;
00040 while(First<=last)
00041 {
00042 index = (First+last)>>1;
00043
00044 if(max>array[sorted[index]]) First = index+1;
00045 else last = index-1;
00046 }
00047 }
00048
00049
00050
00051
00052 #define PRUNING_SORTER RadixSort
00053
00054
00055
00056 static PRUNING_SORTER* gCompletePruningSorter = null;
00057 static PRUNING_SORTER* gBipartitePruningSorter0 = null;
00058 static PRUNING_SORTER* gBipartitePruningSorter1 = null;
00059 inline_ PRUNING_SORTER* GetCompletePruningSorter()
00060 {
00061 if(!gCompletePruningSorter) gCompletePruningSorter = new PRUNING_SORTER;
00062 return gCompletePruningSorter;
00063 }
00064 inline_ PRUNING_SORTER* GetBipartitePruningSorter0()
00065 {
00066 if(!gBipartitePruningSorter0) gBipartitePruningSorter0 = new PRUNING_SORTER;
00067 return gBipartitePruningSorter0;
00068 }
00069 inline_ PRUNING_SORTER* GetBipartitePruningSorter1()
00070 {
00071 if(!gBipartitePruningSorter1) gBipartitePruningSorter1 = new PRUNING_SORTER;
00072 return gBipartitePruningSorter1;
00073 }
00074 void ReleasePruningSorters()
00075 {
00076 DELETESINGLE(gBipartitePruningSorter1);
00077 DELETESINGLE(gBipartitePruningSorter0);
00078 DELETESINGLE(gCompletePruningSorter);
00079 }
00080
00081
00083
00093
00094 bool Opcode::BipartiteBoxPruning(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs, const Axes& axes)
00095 {
00096
00097 if(!nb0 || !array0 || !nb1 || !array1) return false;
00098
00099
00100 udword Axis0 = axes.mAxis0;
00101 udword Axis1 = axes.mAxis1;
00102 udword Axis2 = axes.mAxis2;
00103
00104
00105 float* MinPosList0 = new float[nb0];
00106 float* MinPosList1 = new float[nb1];
00107
00108
00109 for(udword i=0;i<nb0;i++) MinPosList0[i] = array0[i]->GetMin(Axis0);
00110 for(udword i=0;i<nb1;i++) MinPosList1[i] = array1[i]->GetMin(Axis0);
00111
00112
00113 PRUNING_SORTER* RS0 = GetBipartitePruningSorter0();
00114 PRUNING_SORTER* RS1 = GetBipartitePruningSorter1();
00115 const udword* Sorted0 = RS0->Sort(MinPosList0, nb0).GetRanks();
00116 const udword* Sorted1 = RS1->Sort(MinPosList1, nb1).GetRanks();
00117
00118
00119 udword Index0, Index1;
00120
00121 const udword* const LastSorted0 = &Sorted0[nb0];
00122 const udword* const LastSorted1 = &Sorted1[nb1];
00123 const udword* RunningAddress0 = Sorted0;
00124 const udword* RunningAddress1 = Sorted1;
00125
00126 while(RunningAddress1<LastSorted1 && Sorted0<LastSorted0)
00127 {
00128 Index0 = *Sorted0++;
00129
00130 while(RunningAddress1<LastSorted1 && MinPosList1[*RunningAddress1]<MinPosList0[Index0]) RunningAddress1++;
00131
00132 const udword* RunningAddress2_1 = RunningAddress1;
00133
00134 while(RunningAddress2_1<LastSorted1 && MinPosList1[Index1 = *RunningAddress2_1++]<=array0[Index0]->GetMax(Axis0))
00135 {
00136 if(array0[Index0]->Intersect(*array1[Index1], Axis1))
00137 {
00138 if(array0[Index0]->Intersect(*array1[Index1], Axis2))
00139 {
00140 pairs.AddPair(Index0, Index1);
00141 }
00142 }
00143 }
00144 }
00145
00147
00148 while(RunningAddress0<LastSorted0 && Sorted1<LastSorted1)
00149 {
00150 Index0 = *Sorted1++;
00151
00152 while(RunningAddress0<LastSorted0 && MinPosList0[*RunningAddress0]<=MinPosList1[Index0]) RunningAddress0++;
00153
00154 const udword* RunningAddress2_0 = RunningAddress0;
00155
00156 while(RunningAddress2_0<LastSorted0 && MinPosList0[Index1 = *RunningAddress2_0++]<=array1[Index0]->GetMax(Axis0))
00157 {
00158 if(array0[Index1]->Intersect(*array1[Index0], Axis1))
00159 {
00160 if(array0[Index1]->Intersect(*array1[Index0], Axis2))
00161 {
00162 pairs.AddPair(Index1, Index0);
00163 }
00164 }
00165
00166 }
00167 }
00168
00169 DELETEARRAY(MinPosList1);
00170 DELETEARRAY(MinPosList0);
00171
00172 return true;
00173 }
00174
00175 #define ORIGINAL_VERSION
00176
00177
00179
00187
00188 bool Opcode::CompleteBoxPruning(udword nb, const AABB** array, Pairs& pairs, const Axes& axes)
00189 {
00190
00191 if(!nb || !array) return false;
00192
00193
00194 udword Axis0 = axes.mAxis0;
00195 udword Axis1 = axes.mAxis1;
00196 udword Axis2 = axes.mAxis2;
00197
00198 #ifdef ORIGINAL_VERSION
00199
00200
00201 float* PosList = new float[nb+1];
00202
00203
00204 for(udword i=0;i<nb;i++) PosList[i] = array[i]->GetMin(Axis0);
00205 PosList[nb++] = MAX_FLOAT;
00206
00207
00208 PRUNING_SORTER* RS = GetCompletePruningSorter();
00209 const udword* Sorted = RS->Sort(PosList, nb).GetRanks();
00210
00211
00212 const udword* const LastSorted = &Sorted[nb];
00213 const udword* RunningAddress = Sorted;
00214 udword Index0, Index1;
00215 while(RunningAddress<LastSorted && Sorted<LastSorted)
00216 {
00217 Index0 = *Sorted++;
00218
00219
00220 while(PosList[*RunningAddress++]<PosList[Index0]);
00221
00222 if(RunningAddress<LastSorted)
00223 {
00224 const udword* RunningAddress2 = RunningAddress;
00225
00226
00227 while(PosList[Index1 = *RunningAddress2++]<=array[Index0]->GetMax(Axis0))
00228 {
00229
00230
00231 if(array[Index0]->Intersect(*array[Index1], Axis1))
00232 {
00233 if(array[Index0]->Intersect(*array[Index1], Axis2))
00234 {
00235 pairs.AddPair(Index0, Index1);
00236 }
00237 }
00238
00239 }
00240 }
00241 }
00242
00243 DELETEARRAY(PosList);
00244 #endif
00245
00246 #ifdef JOAKIM
00247
00248
00249 float* MinList = new float[nb+1];
00250
00251
00252 for(udword i=0;i<nb;i++) MinList[i] = array[i]->GetMin(Axis0);
00253 MinList[nb] = MAX_FLOAT;
00254
00255
00256 PRUNING_SORTER* RS = GetCompletePruningSorter();
00257 udword* Sorted = RS->Sort(MinList, nb+1).GetRanks();
00258
00259
00260
00261
00262 const udword* RunningAddress = Sorted;
00263 udword Index0, Index1;
00264
00265
00266
00267 while(RunningAddress<&Sorted[nb])
00268
00269 {
00270
00271 Index0 = *RunningAddress++;
00272
00273
00274
00275
00276
00277 {
00278 const udword* RunningAddress2 = RunningAddress;
00279
00280
00281
00282
00283 float CurrentMax = array[Index0]->GetMax(Axis0);
00284
00285 while(MinList[Index1 = *RunningAddress2] <= CurrentMax)
00286
00287 {
00288
00289
00290 if(array[Index0]->Intersect(*array[Index1], Axis1))
00291 {
00292 if(array[Index0]->Intersect(*array[Index1], Axis2))
00293 {
00294 pairs.AddPair(Index0, Index1);
00295 }
00296 }
00297
00298
00299 RunningAddress2++;
00300
00301 }
00302 }
00303 }
00304
00305 DELETEARRAY(MinList);
00306 #endif
00307
00308 return true;
00309 }
00310
00312
00313
00314
00316
00318
00327
00328 bool Opcode::BruteForceBipartiteBoxTest(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs)
00329 {
00330
00331 if(!nb0 || !array0 || !nb1 || !array1) return false;
00332
00333
00334 for(udword i=0;i<nb0;i++)
00335 {
00336 for(udword j=0;j<nb1;j++)
00337 {
00338 if(array0[i]->Intersect(*array1[j])) pairs.AddPair(i, j);
00339 }
00340 }
00341 return true;
00342 }
00343
00345
00352
00353 bool Opcode::BruteForceCompleteBoxTest(udword nb, const AABB** array, Pairs& pairs)
00354 {
00355
00356 if(!nb || !array) return false;
00357
00358
00359 for(udword i=0;i<nb;i++)
00360 {
00361 for(udword j=i+1;j<nb;j++)
00362 {
00363 if(array[i]->Intersect(*array[j])) pairs.AddPair(i, j);
00364 }
00365 }
00366 return true;
00367 }