00001 #include <stdio.h>
00002 #include <memory.h>
00003 #include <crtdbg.h>
00004
00005 #include "RTree.h"
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifdef WIN32
00016
00017
00018 #ifdef _DEBUG
00019 #define SET_CRT_DEBUG_FIELD(a) \
00020 _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
00021 #define CLEAR_CRT_DEBUG_FIELD(a) \
00022 _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
00023 #else
00024 #define SET_CRT_DEBUG_FIELD(a) ((void) 0)
00025 #define CLEAR_CRT_DEBUG_FIELD(a) ((void) 0)
00026 #endif
00027 #endif //WIN32
00028
00029
00030
00031
00032
00033
00034 static float RandFloat(float a_min, float a_max)
00035 {
00036 const float ooMax = 1.0f / (float)(RAND_MAX+1);
00037
00038 float retValue = ( (float)rand() * ooMax * (a_max - a_min) + a_min);
00039
00040 ASSERT(retValue >= a_min && retValue < a_max);
00041
00042 return retValue;
00043 }
00044
00045
00047 struct Vec3
00048 {
00050 Vec3() {}
00051
00053 Vec3(float a_x, float a_y, float a_z)
00054 {
00055 v[0] = a_x;
00056 v[1] = a_y;
00057 v[2] = a_z;
00058 }
00059
00061 Vec3 operator+ (const Vec3& a_other) const
00062 {
00063 return Vec3(v[0] + a_other.v[0],
00064 v[1] + a_other.v[1],
00065 v[2] + a_other.v[2]);
00066 }
00067
00068 float v[3];
00069 };
00070
00071
00072 static bool BoxesIntersect(const Vec3& a_boxMinA, const Vec3& a_boxMaxA,
00073 const Vec3& a_boxMinB, const Vec3& a_boxMaxB)
00074 {
00075 for(int axis=0; axis<3; ++axis)
00076 {
00077 if(a_boxMinA.v[axis] > a_boxMaxB.v[axis] ||
00078 a_boxMaxA.v[axis] < a_boxMinB.v[axis])
00079 {
00080 return false;
00081 }
00082 }
00083 return true;
00084 }
00085
00086
00088 struct SomeThing
00089 {
00090 SomeThing()
00091 {
00092 ++s_outstandingAllocs;
00093 }
00094 ~SomeThing()
00095 {
00096 --s_outstandingAllocs;
00097 }
00098
00099 int m_creationCounter;
00100 Vec3 m_min, m_max;
00101
00102 static int s_outstandingAllocs;
00103 };
00104
00106 int SomeThing::s_outstandingAllocs = 0;
00107
00108
00110 bool _cdecl QueryResultCallback(SomeThing* a_data, void* a_context)
00111 {
00112 printf("search found %d\n", a_data->m_creationCounter);
00113
00114 return true;
00115 }
00116
00117
00118 int main(int argc, char* argv[])
00119 {
00120 const int NUM_OBJECTS = 40;
00121 const int FRAC_OBJECTS = 4;
00122 const float MAX_WORLDSIZE = 10.0f;
00123 const float FRAC_WORLDSIZE = MAX_WORLDSIZE / 2;
00124
00125
00126 typedef RTree<SomeThing*, float, 3> SomeThingTree;
00127
00128 ASSERT( NUM_OBJECTS > FRAC_OBJECTS );
00129
00130 int index;
00131 SomeThing* thingArray[NUM_OBJECTS * 2];
00132
00133 memset(thingArray, 0, sizeof(thingArray));
00134
00135
00136
00137
00138 SomeThingTree tree;
00139
00140
00141
00142 int counter = 0;
00143 for( index = 0; index < NUM_OBJECTS; ++index )
00144 {
00145 SomeThing* newThing = new SomeThing;
00146
00147 newThing->m_creationCounter = counter++;
00148 newThing->m_min = Vec3(RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE), RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE), RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE));
00149 Vec3 extent = Vec3(RandFloat(0, FRAC_WORLDSIZE), RandFloat(0, FRAC_WORLDSIZE), RandFloat(0, FRAC_WORLDSIZE));
00150 newThing->m_max = newThing->m_min + extent;
00151
00152 thingArray[counter-1] = newThing;
00153
00154 tree.Insert(newThing->m_min.v, newThing->m_max.v, newThing);
00155 printf("inserting %d\n", newThing->m_creationCounter);
00156 }
00157
00158 printf("tree count = %d\n", tree.Count());
00159
00160 int numToDelete = NUM_OBJECTS / FRAC_OBJECTS;
00161 int numToStep = FRAC_OBJECTS;
00162
00163
00164 for( index = 0; index < NUM_OBJECTS; index += numToStep )
00165 {
00166 SomeThing* curThing = thingArray[index];
00167
00168 if(curThing)
00169 {
00170 tree.Remove(curThing->m_min.v, curThing->m_max.v, curThing);
00171 printf("removing %d\n", curThing->m_creationCounter);
00172
00173 delete curThing;
00174 thingArray[index] = NULL;
00175 }
00176 }
00177
00178 printf("tree count = %d\n", tree.Count());
00179
00180
00181 for( index = 0; index < numToDelete; ++index )
00182 {
00183 SomeThing* newThing = new SomeThing;
00184
00185 newThing->m_creationCounter = counter++;
00186 newThing->m_min = Vec3(RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE), RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE), RandFloat(-MAX_WORLDSIZE, MAX_WORLDSIZE));
00187 Vec3 extent = Vec3(RandFloat(0, FRAC_WORLDSIZE), RandFloat(0, FRAC_WORLDSIZE), RandFloat(0, FRAC_WORLDSIZE));
00188 newThing->m_max = newThing->m_min + extent;
00189
00190 thingArray[counter-1] = newThing;
00191
00192 tree.Insert(newThing->m_min.v, newThing->m_max.v, newThing);
00193 printf("inserting %d\n", newThing->m_creationCounter);
00194 }
00195
00196 printf("tree count = %d\n", tree.Count());
00197
00198 Vec3 searchMin(0,0,0);
00199 Vec3 searchMax(FRAC_WORLDSIZE, FRAC_WORLDSIZE, FRAC_WORLDSIZE);
00200 tree.Search(searchMin.v, searchMax.v, &QueryResultCallback, NULL);
00201
00202
00203
00204
00205
00206
00207 SomeThingTree::Iterator it;
00208 for( tree.GetFirst(it); !tree.IsNull(it); tree.GetNext(it) )
00209 {
00210 SomeThing* curThing = tree.GetAt(it);
00211
00212 if(BoxesIntersect(searchMin, searchMax, curThing->m_min, curThing->m_max))
00213 {
00214 printf("brute found %d\n", curThing->m_creationCounter);
00215 }
00216 }
00217
00218
00219
00220 for( tree.GetFirst(it); !tree.IsNull(it); tree.GetNext(it) )
00221 {
00222 SomeThing* removeElem = tree.GetAt(it);
00223 if(removeElem)
00224 {
00225 printf("deleting %d\n", removeElem->m_creationCounter);
00226 delete removeElem;
00227 }
00228 }
00229
00230
00231 tree.RemoveAll();
00232
00233 if(SomeThing::s_outstandingAllocs > 0)
00234 {
00235 printf("Memory leak!\n");
00236 printf("s_outstandingAllocs = %d\n", SomeThing::s_outstandingAllocs);
00237 }
00238 else
00239 {
00240 printf("No memory leaks detected by app\n");
00241 }
00242
00243
00244 getchar();
00245
00246 #ifdef WIN32
00247
00248 SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF );
00249 #endif //WIN32
00250
00251 return 0;
00252 }