sceneContainerTest.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. #include "testing/unitTesting.h"
  2. #include "platform/platform.h"
  3. #include "console/simBase.h"
  4. #include "console/consoleTypes.h"
  5. #include "console/scriptObjects.h"
  6. #include "console/simBase.h"
  7. #include "console/engineAPI.h"
  8. #include "math/mMath.h"
  9. #include "console/stringStack.h"
  10. #include "scene/sceneContainer.h"
  11. #include "T3D/missionMarker.h"
  12. #include "collision/clippedPolyList.h"
  13. using ::testing::Matcher;
  14. using ::testing::TypedEq;
  15. class LazyItemAllocatorTest : public ::testing::Test
  16. {
  17. protected:
  18. LazyItemAllocatorTest()
  19. {
  20. }
  21. void SetUp() override
  22. {
  23. }
  24. };
  25. TEST_F(LazyItemAllocatorTest, realloc)
  26. {
  27. LazyItemAllocator<U32> testAllocator(1024);
  28. EXPECT_EQ(testAllocator.isNull(), true);
  29. EXPECT_EQ(testAllocator.getPtr(), (U32*)NULL);
  30. EXPECT_EQ(testAllocator.canFit(1), false);
  31. // Should alloc memory
  32. testAllocator.realloc(1, false);
  33. void* oldPtr = testAllocator.getPtr();
  34. EXPECT_EQ(testAllocator.isNull(), false);
  35. EXPECT_NE(testAllocator.getPtr(), (U32*)NULL);
  36. EXPECT_EQ(testAllocator.canFit(1), true);
  37. EXPECT_EQ(testAllocator.canFit(2), true);
  38. EXPECT_EQ(testAllocator.canFit(1024), true);
  39. EXPECT_EQ(testAllocator.canFit(1025), false);
  40. // Should be the same
  41. testAllocator.realloc(2, false);
  42. EXPECT_EQ(testAllocator.canFit(3), true);
  43. EXPECT_EQ(testAllocator.getPtr(), oldPtr);
  44. // Alloc more and then return to normal
  45. testAllocator.realloc(1025, false);
  46. EXPECT_EQ(testAllocator.canFit(1025), true);
  47. testAllocator.realloc(1022, true);
  48. EXPECT_EQ(testAllocator.canFit(1025), false);
  49. }
  50. class SceneContainerBinRefListTest : public ::testing::Test
  51. {
  52. protected:
  53. SceneContainerBinRefListTest()
  54. {
  55. }
  56. void SetUp() override
  57. {
  58. }
  59. };
  60. TEST_F(SceneContainerBinRefListTest, getValues)
  61. {
  62. SceneContainerBinRefList<U32> testList;
  63. srand(11891830);
  64. // Add some items
  65. U32 valueList[10];
  66. U32 valueList2[10];
  67. for (U32 i = 0; i < 10; i++)
  68. {
  69. valueList[i] = rand() % 1024;
  70. valueList2[i] = rand() % 1024;
  71. }
  72. auto listHandle1 = testList.allocList(10, valueList);
  73. auto listHandle2 = testList.allocList(5, valueList2);
  74. // Grab some items
  75. U32 numValues1 = 0;
  76. U32 numValues2 = 0;
  77. auto newValueList1 = testList.getValues(listHandle1, numValues1);
  78. auto newValueList2 = testList.getValues(listHandle2, numValues2);
  79. // Should be sequential
  80. EXPECT_GT(newValueList2, newValueList1);
  81. EXPECT_EQ(numValues1, 10);
  82. EXPECT_EQ(numValues2, 5);
  83. bool allOk = true;
  84. for (U32 i = 0; i < 10; i++)
  85. {
  86. if (valueList[i] != newValueList1[i])
  87. allOk = false;
  88. }
  89. for (U32 i = 0; i < 5; i++)
  90. {
  91. if (valueList2[i] != newValueList2[i])
  92. allOk = false;
  93. }
  94. EXPECT_EQ(allOk, true);
  95. // Free item, no longer valid
  96. testList.freeList(listHandle1);
  97. auto newValueList3 = testList.getValues(listHandle1, numValues1);
  98. // NOTE: this is not NULL since item gets put in a free list
  99. EXPECT_NE(newValueList3, (U32*)NULL);
  100. EXPECT_EQ(numValues1, 0);
  101. // Grab some more items (they should appear AFTER the last alloc)
  102. U32 numValues4 = 0;
  103. auto listHandle4 = testList.allocList(1, valueList2);
  104. auto newValueList4 = testList.getValues(listHandle4, numValues4);
  105. EXPECT_EQ(numValues4, 1);
  106. EXPECT_GT(newValueList4, newValueList2);
  107. }
  108. TEST_F(SceneContainerBinRefListTest, getValueIterators)
  109. {
  110. SceneContainerBinRefList<U32> testList;
  111. srand(1111830);
  112. // Add some items
  113. U32 valueList[10];
  114. U32 valueList2[10];
  115. for (U32 i = 0; i < 10; i++)
  116. {
  117. valueList[i] = rand() % 1024;
  118. valueList2[i] = rand() % 1024;
  119. }
  120. auto listHandle1 = testList.allocList(10, valueList);
  121. auto listHandle2 = testList.allocList(5, valueList2);
  122. // Grab some items
  123. SceneContainerBinRefList<U32>::ValueIterator start1;
  124. SceneContainerBinRefList<U32>::ValueIterator end1;
  125. SceneContainerBinRefList<U32>::ValueIterator start2;
  126. SceneContainerBinRefList<U32>::ValueIterator end2;
  127. testList.getValueIterators(listHandle1, start1, end1);
  128. testList.getValueIterators(listHandle2, start2, end2);
  129. EXPECT_EQ((end1.getPtr() - start1.getPtr()), 10);
  130. EXPECT_EQ((end2.getPtr() - start2.getPtr()), 5);
  131. EXPECT_GT(start2.getPtr(), start1.getPtr());
  132. // We can update the value
  133. start1++;
  134. *start1 = 2040;
  135. EXPECT_EQ(*(start1.getPtr()), 2040);
  136. EXPECT_EQ((end1.getPtr() - 10)[1], 2040);
  137. // Iterators are NULL for an OOB item
  138. testList.getValueIterators(100, start1, end1);
  139. EXPECT_EQ((start1.getPtr()), (U32*)NULL);
  140. EXPECT_EQ((end1.getPtr()), (U32*)NULL);
  141. EXPECT_EQ((end1.isValid()), false);
  142. }
  143. TEST_F(SceneContainerBinRefListTest, getValueIterator)
  144. {
  145. SceneContainerBinRefList<U32> testList;
  146. srand(1111830);
  147. // Add some items
  148. U32 valueList[10];
  149. U32 valueList2[10];
  150. for (U32 i = 0; i < 10; i++)
  151. {
  152. valueList[i] = rand() % 1024;
  153. valueList2[i] = rand() % 1024;
  154. }
  155. testList.allocList(2, valueList);
  156. auto listHandle2 = testList.allocList(3, valueList2);
  157. auto handleItr = testList.getValueIterator(listHandle2);
  158. EXPECT_NE((handleItr.getPtr()), (U32*)NULL);
  159. EXPECT_EQ((handleItr.isValid()), true);
  160. EXPECT_EQ((*handleItr), valueList2[0]);
  161. EXPECT_EQ((handleItr.getCount()), 3);
  162. handleItr++;
  163. EXPECT_EQ((handleItr.getIndex()), 1);
  164. EXPECT_EQ((*handleItr), valueList2[1]);
  165. handleItr++;
  166. EXPECT_EQ((*handleItr), valueList2[2]);
  167. handleItr++;
  168. EXPECT_EQ((handleItr.isValid()), false);
  169. // Iterators are NULL for an OOB item
  170. auto oobItr = testList.getValueIterator(100);
  171. EXPECT_EQ((oobItr.getPtr()), (U32*)NULL);
  172. EXPECT_EQ((oobItr.isValid()), false);
  173. }
  174. TEST_F(SceneContainerBinRefListTest, allocList)
  175. {
  176. SceneContainerBinRefList<U32> testList;
  177. srand(1131830);
  178. // Set base values
  179. U32 valueList[10];
  180. U32 valueList2[10];
  181. for (U32 i = 0; i < 10; i++)
  182. {
  183. valueList[i] = rand() % 1024;
  184. valueList2[i] = rand() % 1024;
  185. }
  186. // Check allocations
  187. auto listHandle2 = testList.allocList(3, valueList2);
  188. EXPECT_EQ(testList.getBinLists().size(), 1);
  189. EXPECT_EQ(testList.getBinLists()[0].numValues, 3);
  190. EXPECT_EQ(testList.getBinLists()[0].startValue, 0);
  191. auto listHandle3 = testList.allocList(4, valueList);
  192. EXPECT_EQ(testList.getBinLists().size(), 2);
  193. EXPECT_EQ(testList.getBinLists()[1].numValues, 4);
  194. EXPECT_EQ(testList.getBinLists()[1].startValue, 3);
  195. // Zero alloc should still return a list
  196. auto listHandle5 = testList.allocList(0, NULL);
  197. EXPECT_EQ(testList.getBinLists().size(), 3);
  198. EXPECT_EQ(testList.getBinLists()[2].numValues, 0);
  199. EXPECT_EQ(testList.getBinLists()[2].startValue, 7);
  200. }
  201. TEST_F(SceneContainerBinRefListTest, reallocList)
  202. {
  203. SceneContainerBinRefList<U32> testList;
  204. srand(1131830);
  205. // Set base values
  206. U32 valueList[10];
  207. U32 valueList2[10];
  208. for (U32 i = 0; i < 10; i++)
  209. {
  210. valueList[i] = rand() % 1024;
  211. valueList2[i] = rand() % 1024;
  212. }
  213. // Reallocating should puts new items at the end
  214. auto listHandle1 = testList.allocList(2, valueList2);
  215. testList.reallocList(listHandle1, 1, valueList2);
  216. EXPECT_EQ(testList.getBinLists().size(), 1);
  217. EXPECT_EQ(testList.getBinLists()[0].numValues, 1);
  218. EXPECT_EQ(testList.getBinLists()[0].startValue, 2);
  219. auto listHandle3 = testList.allocList(3, valueList);
  220. testList.reallocList(listHandle3, 5, valueList2);
  221. EXPECT_EQ(testList.getBinLists().size(), 2);
  222. EXPECT_EQ(testList.getBinLists()[1].numValues, 5);
  223. EXPECT_EQ(testList.getBinLists()[1].startValue, 6);
  224. // Unless it has the same number of items
  225. testList.reallocList(listHandle3, 5, valueList2);
  226. EXPECT_EQ(testList.getBinLists().size(), 2);
  227. EXPECT_EQ(testList.getBinLists()[1].numValues, 5);
  228. EXPECT_EQ(testList.getBinLists()[1].startValue, 6);
  229. // Should handle invalid handles
  230. testList.reallocList(100, 5, valueList2);
  231. EXPECT_EQ(testList.getBinLists().size(), 2);
  232. EXPECT_EQ(testList.getBinLists()[0].numValues, 1);
  233. EXPECT_EQ(testList.getBinLists()[0].startValue, 2);
  234. EXPECT_EQ(testList.getBinLists()[1].numValues, 5);
  235. EXPECT_EQ(testList.getBinLists()[1].startValue, 6);
  236. }
  237. TEST_F(SceneContainerBinRefListTest, freeList)
  238. {
  239. SceneContainerBinRefList<U32> testList;
  240. srand(6131830);
  241. // Set base values
  242. U32 valueList[10];
  243. U32 valueList2[10];
  244. for (U32 i = 0; i < 10; i++)
  245. {
  246. valueList[i] = rand() % 1024;
  247. valueList2[i] = rand() % 1024;
  248. }
  249. // Make some items
  250. testList.allocList(2, valueList);
  251. auto listHandle2 = testList.allocList(3, valueList2);
  252. auto listHandle3 = testList.allocList(4, valueList);
  253. auto listHandle4 = testList.allocList(5, valueList2);
  254. // Free the middle one, should now be a hole
  255. testList.freeList(listHandle3);
  256. EXPECT_EQ(testList.getBinLists().size(), 4);
  257. //
  258. EXPECT_EQ(testList.getBinLists()[0].numValues, 2);
  259. EXPECT_EQ(testList.getBinLists()[0].startValue, 0);
  260. //
  261. EXPECT_EQ(testList.getBinLists()[1].numValues, 3);
  262. EXPECT_EQ(testList.getBinLists()[1].startValue, 2);
  263. //
  264. EXPECT_EQ(testList.getBinLists()[2].numValues, 0);
  265. EXPECT_EQ(testList.getBinLists()[2].startValue, 0);
  266. //
  267. EXPECT_EQ(testList.getBinLists()[3].numValues, 5);
  268. EXPECT_EQ(testList.getBinLists()[3].startValue, 9);
  269. EXPECT_EQ(testList.getNextFreeListIndex(), listHandle3);
  270. // Freeing more will make a stack
  271. testList.freeList(listHandle2);
  272. EXPECT_EQ(testList.getNextFreeListIndex(), listHandle2);
  273. EXPECT_EQ(testList.getBinLists().size(), 4);
  274. //
  275. EXPECT_EQ(testList.getBinLists()[0].numValues, 2);
  276. EXPECT_EQ(testList.getBinLists()[0].startValue, 0);
  277. //
  278. EXPECT_EQ(testList.getBinLists()[1].numValues, 0);
  279. EXPECT_EQ(testList.getBinLists()[1].startValue, 3);
  280. //
  281. EXPECT_EQ(testList.getBinLists()[2].numValues, 0);
  282. EXPECT_EQ(testList.getBinLists()[2].startValue, 0);
  283. //
  284. EXPECT_EQ(testList.getBinLists()[3].numValues, 5);
  285. EXPECT_EQ(testList.getBinLists()[3].startValue, 9);
  286. // ... which can be popped like this
  287. auto listHandle5 = testList.allocList(1, valueList);
  288. EXPECT_EQ(testList.getNextFreeListIndex(), listHandle3);
  289. auto listHandle6 = testList.allocList(1, valueList);
  290. EXPECT_EQ(testList.getNextFreeListIndex(), 0);
  291. EXPECT_EQ(testList.getBinLists().size(), 4);
  292. // Should handle invalid handles
  293. testList.freeList(10);
  294. EXPECT_EQ(testList.getBinLists().size(), 4);
  295. // Compaction will occur if we free more than CompactionThreshold items in total
  296. U32* bigList = new U32[SceneContainerBinRefList<U32>::CompactionThreshold];
  297. memset(bigList, 0, SceneContainerBinRefList<U32>::CompactionThreshold * sizeof(U32));
  298. auto listHandle8 = testList.allocList(SceneContainerBinRefList<U32>::CompactionThreshold, bigList);
  299. auto listHandle9 = testList.allocList(SceneContainerBinRefList<U32>::CompactionThreshold, bigList);
  300. EXPECT_EQ(testList.getBinLists().size(), 6);
  301. //
  302. EXPECT_EQ(testList.getBinLists()[4].numValues, SceneContainerBinRefList<U32>::CompactionThreshold);
  303. EXPECT_EQ(testList.getBinLists()[4].startValue, 16);
  304. //
  305. EXPECT_EQ(testList.getBinLists()[5].numValues, SceneContainerBinRefList<U32>::CompactionThreshold);
  306. EXPECT_EQ(testList.getBinLists()[5].startValue, 16 + (SceneContainerBinRefList<U32>::CompactionThreshold));
  307. //
  308. testList.freeList(listHandle8);
  309. EXPECT_EQ(testList.getBinLists().size(), 6);
  310. // NOTE: everying unused should get reset to 0
  311. //
  312. EXPECT_EQ(testList.getBinLists()[0].numValues, 2);
  313. EXPECT_EQ(testList.getBinLists()[0].startValue, 0);
  314. //
  315. EXPECT_EQ(testList.getBinLists()[1].numValues, 1); // listHandle5
  316. EXPECT_EQ(testList.getBinLists()[1].startValue, 2);
  317. //
  318. EXPECT_EQ(testList.getBinLists()[2].numValues, 1); // listHandle6
  319. EXPECT_EQ(testList.getBinLists()[2].startValue, 3);
  320. //
  321. EXPECT_EQ(testList.getBinLists()[3].numValues, 5);
  322. EXPECT_EQ(testList.getBinLists()[3].startValue, 4);
  323. //
  324. EXPECT_EQ(testList.getBinLists()[4].numValues, 0);
  325. EXPECT_EQ(testList.getBinLists()[4].startValue, 0);
  326. //
  327. EXPECT_EQ(testList.getBinLists()[5].numValues, SceneContainerBinRefList<U32>::CompactionThreshold);
  328. EXPECT_EQ(testList.getBinLists()[5].startValue, 9);
  329. }
  330. TEST_F(SceneContainerBinRefListTest, replaceListBin)
  331. {
  332. SceneContainerBinRefList<U32> testList;
  333. // Set base values
  334. U32 valueList[] = { 1, 2, 3, 1, 2 };
  335. U32 valueList2[] = { 256, 700, 1, 1000 };
  336. // Make some items
  337. auto listHandle2 = testList.allocList(5, valueList);
  338. auto listHandle3 = testList.allocList(4, valueList2);
  339. // Replace items in the list
  340. testList.replaceListBin(listHandle2, 1, 100);
  341. testList.replaceListBin(listHandle2, 2, 1010);
  342. testList.replaceListBin(listHandle2, 3, 101010);
  343. // First instances of the items should get replaced
  344. auto itr1 = testList.getValueIterator(listHandle2);
  345. auto itr2 = testList.getValueIterator(listHandle3);
  346. EXPECT_EQ(*itr1, 100); itr1++;
  347. EXPECT_EQ(*itr1, 1010); itr1++;
  348. EXPECT_EQ(*itr1, 101010); itr1++;
  349. EXPECT_EQ(*itr1, 1); itr1++;
  350. EXPECT_EQ(*itr1, 2); itr1++;
  351. //
  352. EXPECT_EQ(*itr2, 256); itr2++;
  353. EXPECT_EQ(*itr2, 700); itr2++;
  354. EXPECT_EQ(*itr2, 1); itr2++;
  355. EXPECT_EQ(*itr2, 1000); itr2++;
  356. }
  357. TEST_F(SceneContainerBinRefListTest, containsBinItem)
  358. {
  359. SceneContainerBinRefList<U32> testList;
  360. // Set base values
  361. U32 valueList[] = { 1,2,3 };
  362. U32 valueList2[] = { 256, 700, 900, 1000 };
  363. // Make some items
  364. auto listHandle2 = testList.allocList(3, valueList);
  365. auto listHandle3 = testList.allocList(4, valueList2);
  366. // Checks should pass
  367. EXPECT_EQ(testList.containsBinItem(listHandle2, 1), true);
  368. EXPECT_EQ(testList.containsBinItem(listHandle2, 2), true);
  369. EXPECT_EQ(testList.containsBinItem(listHandle2, 3), true);
  370. EXPECT_EQ(testList.containsBinItem(listHandle2, 256), false);
  371. EXPECT_EQ(testList.containsBinItem(listHandle2, 700), false);
  372. EXPECT_EQ(testList.containsBinItem(listHandle2, 900), false);
  373. EXPECT_EQ(testList.containsBinItem(listHandle2, 1000), false);
  374. //
  375. EXPECT_EQ(testList.containsBinItem(listHandle3, 1), false);
  376. EXPECT_EQ(testList.containsBinItem(listHandle3, 2), false);
  377. EXPECT_EQ(testList.containsBinItem(listHandle3, 3), false);
  378. EXPECT_EQ(testList.containsBinItem(listHandle3, 256), true);
  379. EXPECT_EQ(testList.containsBinItem(listHandle3, 700), true);
  380. EXPECT_EQ(testList.containsBinItem(listHandle3, 900), true);
  381. EXPECT_EQ(testList.containsBinItem(listHandle3, 1000), true);
  382. // Invalid handles should return false
  383. EXPECT_EQ(testList.containsBinItem(62, 1000), false);
  384. }
  385. TEST_F(SceneContainerBinRefListTest, compact)
  386. {
  387. SceneContainerBinRefList<U32> testList;
  388. srand(7131830);
  389. // Set base values
  390. U32 valueList[10];
  391. U32 valueList2[10];
  392. for (U32 i = 0; i < 10; i++)
  393. {
  394. valueList[i] = rand() % 1024;
  395. valueList2[i] = rand() % 1024;
  396. }
  397. // Unallocated list should do nothing
  398. testList.compact();
  399. EXPECT_EQ(testList.getBin(), (U32*)NULL);
  400. // Check allocations
  401. auto listHandle2 = testList.allocList(3, valueList2);
  402. auto listHandle3 = testList.allocList(4, valueList2);
  403. EXPECT_EQ(testList.getBinLists().size(), 2);
  404. //
  405. EXPECT_EQ(testList.getBinLists()[0].numValues, 3);
  406. EXPECT_EQ(testList.getBinLists()[0].startValue, 0);
  407. //
  408. EXPECT_EQ(testList.getBinLists()[1].numValues, 4);
  409. EXPECT_EQ(testList.getBinLists()[1].startValue, 3);
  410. testList.compact();
  411. EXPECT_EQ(testList.getBinLists().size(), 2);
  412. //
  413. EXPECT_EQ(testList.getBinLists()[0].numValues, 3);
  414. EXPECT_EQ(testList.getBinLists()[0].startValue, 0);
  415. //
  416. EXPECT_EQ(testList.getBinLists()[1].numValues, 4);
  417. EXPECT_EQ(testList.getBinLists()[1].startValue, 3);
  418. // Make lots of tiny allocations
  419. U32 totalAllocItems = 0;
  420. for (U32 i = 0; i < SceneContainerBinRefList<U32>::CompactionThreshold / 2; i++)
  421. {
  422. auto listHandle = testList.allocList(1, valueList2);
  423. testList.freeList(listHandle);
  424. totalAllocItems++;
  425. }
  426. //
  427. auto endListHandle = testList.allocList(4, valueList2);
  428. EXPECT_EQ(testList.getBinLists().size(), 3);
  429. //
  430. EXPECT_EQ(testList.getBinLists()[0].numValues, 3);
  431. EXPECT_EQ(testList.getBinLists()[0].startValue, 0);
  432. //
  433. EXPECT_EQ(testList.getBinLists()[1].numValues, 4);
  434. EXPECT_EQ(testList.getBinLists()[1].startValue, 3);
  435. //
  436. EXPECT_EQ(testList.getBinLists()[2].numValues, 4);
  437. EXPECT_EQ(testList.getBinLists()[2].startValue, 7 + totalAllocItems);
  438. // Compact should compact everything
  439. testList.compact();
  440. EXPECT_EQ(testList.getBinLists().size(), 3);
  441. //
  442. EXPECT_EQ(testList.getBinLists()[0].numValues, 3);
  443. EXPECT_EQ(testList.getBinLists()[0].startValue, 0);
  444. //
  445. EXPECT_EQ(testList.getBinLists()[1].numValues, 4);
  446. EXPECT_EQ(testList.getBinLists()[1].startValue, 3);
  447. //
  448. EXPECT_EQ(testList.getBinLists()[2].numValues, 4);
  449. EXPECT_EQ(testList.getBinLists()[2].startValue, 7);
  450. }
  451. TEST_F(SceneContainerBinRefListTest, clear)
  452. {
  453. SceneContainerBinRefList<U32> testList;
  454. srand(1131830);
  455. // Set base values
  456. U32 valueList[10];
  457. U32 valueList2[10];
  458. for (U32 i = 0; i < 10; i++)
  459. {
  460. valueList[i] = rand() % 1024;
  461. valueList2[i] = rand() % 1024;
  462. }
  463. testList.allocList(3, valueList);
  464. testList.allocList(4, valueList2);
  465. EXPECT_EQ(testList.getBinLists().size(), 2);
  466. testList.clear();
  467. EXPECT_EQ(testList.getBinLists().size(), 0);
  468. }
  469. extern bool gEditingMission;
  470. class SceneObjectTestVariant : public SceneObject
  471. {
  472. typedef SceneObject Parent;
  473. public:
  474. std::function<void() > mAddCallback;
  475. U32 mNumCastRayCalls;
  476. U32 mNumBuildConvexCalls;
  477. U32 mNumBuildPolyListCalls;
  478. U32 mNumCollideBoxCalls;
  479. U32 mNumCastRayRenderedCalls;
  480. bool mReturnCastRay;
  481. RayInfo mRayInfo;
  482. bool onAdd()
  483. {
  484. if (Parent::onAdd())
  485. {
  486. mNumCastRayCalls = 0;
  487. mNumBuildConvexCalls = 0;
  488. mNumBuildPolyListCalls = 0;
  489. mNumCollideBoxCalls = 0;
  490. mNumCastRayRenderedCalls = 0;
  491. mReturnCastRay = false;
  492. mRayInfo = {};
  493. if (mAddCallback)
  494. mAddCallback();
  495. return true;
  496. }
  497. return false;
  498. }
  499. void onRemove()
  500. {
  501. removeFromScene();
  502. Parent::onRemove();
  503. }
  504. void setTypeMask(U32 mask)
  505. {
  506. mTypeMask = mask;
  507. }
  508. virtual void buildConvex(const Box3F& box, Convex* convex)
  509. {
  510. mNumBuildConvexCalls++;
  511. }
  512. virtual bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F& box, const SphereF& sphere)
  513. {
  514. mNumBuildPolyListCalls++;
  515. return false;
  516. }
  517. virtual bool castRay(const Point3F& start, const Point3F& end, RayInfo* info)
  518. {
  519. mNumCastRayCalls++;
  520. if (!mReturnCastRay)
  521. return false;
  522. *info = mRayInfo;
  523. return true;
  524. }
  525. virtual bool castRayRendered(const Point3F& start, const Point3F& end, RayInfo* info)
  526. {
  527. mNumCastRayRenderedCalls++;
  528. if (!mReturnCastRay)
  529. return false;
  530. *info = mRayInfo;
  531. return false;
  532. }
  533. virtual bool collideBox(const Point3F& start, const Point3F& end, RayInfo* info)
  534. {
  535. mNumCollideBoxCalls++;
  536. return false;
  537. }
  538. void setWorldBox(const Box3F& box)
  539. {
  540. mWorldBox = box;
  541. }
  542. };
  543. class SceneContainerTest : public ::testing::Test
  544. {
  545. protected:
  546. SimGroup* mGroup;
  547. SceneContainerTest()
  548. {
  549. }
  550. void SetUp() override
  551. {
  552. mGroup = new SimGroup();
  553. gEditingMission = true;
  554. SceneObjectTestVariant* so1 = new SceneObjectTestVariant;
  555. so1->registerObject("SO1");
  556. SceneObjectTestVariant* so2 = new SceneObjectTestVariant;
  557. so2->registerObject("SO2");
  558. SceneObjectTestVariant* so3 = new SceneObjectTestVariant;
  559. so3->registerObject("SO3");
  560. SceneObjectTestVariant* so4 = new SceneObjectTestVariant;
  561. so4->registerObject("SO4");
  562. SceneObjectTestVariant* so5 = new SceneObjectTestVariant;
  563. so5->registerObject("SO5");
  564. mGroup->addObject(so1);
  565. mGroup->addObject(so2);
  566. mGroup->addObject(so3);
  567. mGroup->addObject(so4);
  568. mGroup->addObject(so5);
  569. gEditingMission = false;
  570. }
  571. void TearDown() override
  572. {
  573. mGroup->deleteObject();
  574. }
  575. };
  576. TEST_F(SceneContainerTest, findObjects)
  577. {
  578. // Set up the objects
  579. SceneObjectTestVariant* so1 = NULL;
  580. SceneObjectTestVariant* so2 = NULL;
  581. SceneObjectTestVariant* so3 = NULL;
  582. SceneObjectTestVariant* so4 = NULL;
  583. SceneObjectTestVariant* so5 = NULL;
  584. Sim::findObject("SO1", so1);
  585. Sim::findObject("SO2", so2);
  586. Sim::findObject("SO3", so3);
  587. Sim::findObject("SO4", so4);
  588. Sim::findObject("SO5", so5);
  589. so1->setTypeMask(MarkerObjectType);
  590. so3->setTypeMask(MarkerObjectType);
  591. so4->setTypeMask(MarkerObjectType);
  592. so1->addToScene();
  593. so2->addToScene();
  594. so3->addToScene();
  595. so4->addToScene();
  596. so5->addToScene();
  597. // Should find all 3 objects we put there in the setup
  598. SceneContainer::ObjectList outList;
  599. gServerSceneGraph->getContainer()->findObjectList(MarkerObjectType, &outList);
  600. EXPECT_EQ(outList.size(), 3);
  601. EXPECT_EQ(outList[0], so1);
  602. EXPECT_EQ(outList[1], so3);
  603. EXPECT_EQ(outList[2], so4);
  604. outList.clear();
  605. // Won't find other objects
  606. gServerSceneGraph->getContainer()->findObjectList(PlayerObjectType, &outList);
  607. EXPECT_EQ(outList.size(), 0);
  608. so1->removeFromScene();
  609. so2->removeFromScene();
  610. so3->removeFromScene();
  611. so4->removeFromScene();
  612. so5->removeFromScene();
  613. }
  614. TEST_F(SceneContainerTest, polyhedronFindObjects)
  615. {
  616. // Basically: only gets called on objects in the right bin
  617. SceneObjectTestVariant* so1 = NULL;
  618. Polyhedron shape;
  619. shape.buildBox(MatrixF(1), Box3F(Point3F(0,0,0), Point3F(100,100,100)), true);
  620. Sim::findObject("SO1", so1);
  621. MatrixF m(1);
  622. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  623. so1->setTypeMask(MarkerObjectType);
  624. so1->setTransform(m);
  625. gClientSceneGraph->getContainer()->addObject(so1);
  626. static Vector<SceneObject*> foundList;
  627. foundList.clear();
  628. RayInfo info;
  629. gClientSceneGraph->getContainer()->polyhedronFindObjects(shape, MarkerObjectType, [](SceneObject* object, void* key) {
  630. });
  631. gClientSceneGraph->getContainer()->removeObject(so1);
  632. }
  633. TEST_F(SceneContainerTest, findObjectList)
  634. {
  635. // Basically: only gets called on objects in the right bin
  636. SceneObjectTestVariant* so1 = NULL;
  637. Sim::findObject("SO1", so1);
  638. MatrixF m(1);
  639. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  640. so1->setTypeMask(MarkerObjectType);
  641. so1->setTransform(m);
  642. gClientSceneGraph->getContainer()->addObject(so1);
  643. Vector<SceneObject*> foundList;
  644. PolyListContext ctx;
  645. Box3F box(Point3F(0, 0, 0), Point3F(0, 100, 0));
  646. RayInfo info;
  647. gClientSceneGraph->getContainer()->findObjectList(box, MarkerObjectType, &foundList);
  648. EXPECT_EQ(foundList.size(), 0);
  649. foundList.clear();
  650. box = Box3F(Point3F(0, 0, 0), Point3F(100, 100, 0));
  651. gClientSceneGraph->getContainer()->findObjectList(box, MarkerObjectType, &foundList);
  652. EXPECT_EQ(foundList.size(), 1);
  653. gClientSceneGraph->getContainer()->removeObject(so1);
  654. }
  655. TEST_F(SceneContainerTest, castRay)
  656. {
  657. // Basically: only gets called on objects in the right bin
  658. SceneObjectTestVariant* so1 = NULL;
  659. Sim::findObject("SO1", so1);
  660. MatrixF m(1);
  661. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  662. so1->setTypeMask(MarkerObjectType);
  663. so1->setTransform(m);
  664. so1->setWorldBox(Box3F(m.getPosition(), m.getPosition() + Point3F(SceneContainer::csmBinSize-2, SceneContainer::csmBinSize-2, 10)));
  665. gClientSceneGraph->getContainer()->addObject(so1);
  666. Point3F start(0, 0, 0);
  667. Point3F end(0, 100, 0);
  668. RayInfo info;
  669. bool castCheck = gClientSceneGraph->getContainer()->castRay(start, end, MarkerObjectType, &info);
  670. EXPECT_EQ(so1->mNumCastRayCalls, 0);
  671. start = Point3F(SceneContainer::csmBinSize + 1, SceneContainer::csmBinSize + 1, 0);
  672. castCheck = gClientSceneGraph->getContainer()->castRay(start, end, MarkerObjectType, &info);
  673. EXPECT_EQ(so1->mNumCastRayCalls, 1);
  674. gClientSceneGraph->getContainer()->removeObject(so1);
  675. }
  676. TEST_F(SceneContainerTest, castRay_order)
  677. {
  678. SceneObjectTestVariant* so1 = NULL;
  679. SceneObjectTestVariant* so2 = NULL;
  680. Sim::findObject("SO1", so1);
  681. Sim::findObject("SO2", so2);
  682. MatrixF m(1);
  683. m.setPosition(Point3F(0, 0, 0));
  684. so1->setTypeMask(MarkerObjectType);
  685. so1->setTransform(m);
  686. so1->setWorldBox(Box3F(m.getPosition() - Point3F(5, 5, 5), m.getPosition() + Point3F(5,5,5)));
  687. so2->setTypeMask(MarkerObjectType);
  688. so2->setGlobalBounds();
  689. so1->mReturnCastRay = true;
  690. so2->mReturnCastRay = true;
  691. gClientSceneGraph->getContainer()->addObject(so1);
  692. gClientSceneGraph->getContainer()->addObject(so2);
  693. // Here we need to ensure that so1 or so2 will be picked based on shortest distance
  694. RayInfo closeInfo = {};
  695. RayInfo farInfo = {};
  696. closeInfo.t = 5 / 100.0;
  697. farInfo.t = 10 / 100.0;
  698. // so1=far, so2=close
  699. {
  700. so1->mRayInfo = farInfo;
  701. so1->mRayInfo.object = so1;
  702. so2->mRayInfo = closeInfo;
  703. so2->mRayInfo.object = so2;
  704. Point3F start(0, 0, 0);
  705. Point3F end(0, 0, -100);
  706. RayInfo info;
  707. bool castCheck = gClientSceneGraph->getContainer()->castRay(start, end, MarkerObjectType, &info);
  708. EXPECT_EQ(castCheck, true);
  709. EXPECT_EQ(so1->mNumCastRayCalls, 1);
  710. EXPECT_EQ(so2->mNumCastRayCalls, 1);
  711. EXPECT_EQ(info.distance, 5);
  712. EXPECT_EQ(info.object, so2);
  713. }
  714. // so2=far, so1=close
  715. {
  716. so2->mRayInfo = farInfo;
  717. so2->mRayInfo.object = so2;
  718. so1->mRayInfo = closeInfo;
  719. so1->mRayInfo.object = so1;
  720. Point3F start(0, 0, 0);
  721. Point3F end(0, 0, -100);
  722. RayInfo info;
  723. bool castCheck = gClientSceneGraph->getContainer()->castRay(start, end, MarkerObjectType, &info);
  724. EXPECT_EQ(castCheck, true);
  725. EXPECT_EQ(so1->mNumCastRayCalls, 2);
  726. EXPECT_EQ(so2->mNumCastRayCalls, 2);
  727. EXPECT_EQ(info.distance, 5);
  728. EXPECT_EQ(info.object, so1);
  729. }
  730. gClientSceneGraph->getContainer()->removeObject(so1);
  731. gClientSceneGraph->getContainer()->removeObject(so2);
  732. }
  733. TEST_F(SceneContainerTest, castRayRendered)
  734. {
  735. // Basically: only gets called on objects in the right bin
  736. SceneObjectTestVariant* so1 = NULL;
  737. Sim::findObject("SO1", so1);
  738. MatrixF m(1);
  739. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  740. so1->setTypeMask(MarkerObjectType);
  741. so1->setTransform(m);
  742. so1->setWorldBox(Box3F(m.getPosition(), m.getPosition() + Point3F(SceneContainer::csmBinSize - 2, SceneContainer::csmBinSize - 2, 10)));
  743. gClientSceneGraph->getContainer()->addObject(so1);
  744. Point3F start(0, 0, 0);
  745. Point3F end(0, 100, 0);
  746. RayInfo info;
  747. bool castCheck = gClientSceneGraph->getContainer()->castRayRendered(start, end, MarkerObjectType, &info);
  748. EXPECT_EQ(so1->mNumCastRayRenderedCalls, 0);
  749. start = Point3F(SceneContainer::csmBinSize + 1, SceneContainer::csmBinSize + 1, 0);
  750. castCheck = gClientSceneGraph->getContainer()->castRayRendered(start, end, MarkerObjectType, &info);
  751. EXPECT_EQ(so1->mNumCastRayRenderedCalls, 1);
  752. gClientSceneGraph->getContainer()->removeObject(so1);
  753. }
  754. TEST_F(SceneContainerTest, collideBox)
  755. {
  756. // Basically: only gets called on objects in the right bin
  757. SceneObjectTestVariant* so1 = NULL;
  758. Sim::findObject("SO1", so1);
  759. MatrixF m(1);
  760. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  761. so1->setTypeMask(MarkerObjectType);
  762. so1->setTransform(m);
  763. gClientSceneGraph->getContainer()->addObject(so1);
  764. Point3F start(0, 0, 0);
  765. Point3F end(0, 100, 0);
  766. RayInfo info;
  767. bool castCheck = gClientSceneGraph->getContainer()->collideBox(start, end, 0xFFFFFFFF, &info);
  768. EXPECT_EQ(so1->mNumCollideBoxCalls, 0);
  769. start = Point3F(SceneContainer::csmBinSize + 1, SceneContainer::csmBinSize + 1, 0);
  770. castCheck = gClientSceneGraph->getContainer()->collideBox(start, end, 0xFFFFFFFF, &info);
  771. EXPECT_EQ(so1->mNumCollideBoxCalls, 1);
  772. gClientSceneGraph->getContainer()->removeObject(so1);
  773. }
  774. TEST_F(SceneContainerTest, buildPolyList)
  775. {
  776. // Basically: only gets called on objects in the right bin
  777. SceneObjectTestVariant* so1 = NULL;
  778. Sim::findObject("SO1", so1);
  779. MatrixF m(1);
  780. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  781. so1->setTypeMask(MarkerObjectType);
  782. so1->setTransform(m);
  783. gClientSceneGraph->getContainer()->addObject(so1);
  784. ClippedPolyList polyList;
  785. Box3F box(Point3F(0, 0, 0), Point3F(10, 10, 0));
  786. RayInfo info;
  787. bool castCheck = gClientSceneGraph->getContainer()->buildPolyList(PLC_Collision, box, 0xFFFFFFFF, &polyList);
  788. EXPECT_EQ(so1->mNumBuildPolyListCalls, 0);
  789. box = Box3F(Point3F(0, 0, 0), Point3F(100, 100, 0));
  790. castCheck = gClientSceneGraph->getContainer()->buildPolyList(PLC_Collision, box, 0xFFFFFFFF, &polyList);
  791. EXPECT_EQ(so1->mNumBuildPolyListCalls, 1);
  792. gClientSceneGraph->getContainer()->removeObject(so1);
  793. }
  794. TEST_F(SceneContainerTest, addObject)
  795. {
  796. // Set up the objects
  797. SceneObjectTestVariant* so1 = NULL;
  798. SceneObjectTestVariant* so2 = NULL;
  799. SceneObjectTestVariant* so3 = NULL;
  800. SceneObjectTestVariant* so4 = NULL;
  801. SceneObjectTestVariant* so5 = NULL;
  802. Sim::findObject("SO1", so1);
  803. Sim::findObject("SO2", so2);
  804. Sim::findObject("SO3", so3);
  805. Sim::findObject("SO4", so4);
  806. Sim::findObject("SO5", so5);
  807. so1->setTypeMask(MarkerObjectType);
  808. so3->setTypeMask(MarkerObjectType);
  809. so4->setTypeMask(MarkerObjectType);
  810. MatrixF m(1);
  811. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  812. so1->setTransform(m);
  813. m.setPosition(Point3F(0, SceneContainer::csmBinSize, 0));
  814. so2->setTransform(m);
  815. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, 0, 0));
  816. so3->setTransform(m);
  817. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, SceneContainer::csmBinSize * 2, 0));
  818. so4->setTransform(m);
  819. gClientSceneGraph->getContainer()->addObject(so1);
  820. gClientSceneGraph->getContainer()->addObject(so2);
  821. gClientSceneGraph->getContainer()->addObject(so3);
  822. gClientSceneGraph->getContainer()->addObject(so4);
  823. gClientSceneGraph->getContainer()->addObject(so5);
  824. EXPECT_EQ(so1->getContainer(), gClientSceneGraph->getContainer());
  825. EXPECT_EQ(so2->getContainer(), gClientSceneGraph->getContainer());
  826. EXPECT_EQ(so3->getContainer(), gClientSceneGraph->getContainer());
  827. EXPECT_EQ(so4->getContainer(), gClientSceneGraph->getContainer());
  828. EXPECT_EQ(so5->getContainer(), gClientSceneGraph->getContainer());
  829. // Should be put in correct bins
  830. U32 startIndex = so1->getRootContainerIndex();
  831. EXPECT_EQ(so2->getRootContainerIndex(), startIndex + 1);
  832. EXPECT_EQ(so3->getRootContainerIndex(), startIndex + 2);
  833. EXPECT_EQ(so4->getRootContainerIndex(), startIndex + 3);
  834. EXPECT_EQ(so5->getRootContainerIndex(), startIndex + 4);
  835. SceneBinListLookup lookup = {};
  836. lookup.mRange.minCoord[0] = 1;
  837. lookup.mRange.maxCoord[0] = 1;
  838. lookup.mRange.minCoord[1] = 0;
  839. lookup.mRange.maxCoord[1] = 0;
  840. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  841. lookup.mRange.minCoord[0] = 0;
  842. lookup.mRange.maxCoord[0] = 0;
  843. lookup.mRange.minCoord[1] = 1;
  844. lookup.mRange.maxCoord[1] = 1;
  845. EXPECT_EQ(so2->getContainerLookupInfo().mRange, lookup.mRange);
  846. lookup.mRange.minCoord[0] = 2;
  847. lookup.mRange.maxCoord[0] = 2;
  848. lookup.mRange.minCoord[1] = 0;
  849. lookup.mRange.maxCoord[1] = 0;
  850. EXPECT_EQ(so3->getContainerLookupInfo().mRange, lookup.mRange);
  851. lookup.mRange.minCoord[0] = 2;
  852. lookup.mRange.maxCoord[0] = 2;
  853. lookup.mRange.minCoord[1] = 2;
  854. lookup.mRange.maxCoord[1] = 2;
  855. EXPECT_EQ(so4->getContainerLookupInfo().mRange, lookup.mRange);
  856. lookup.mRange.minCoord[0] = 0;
  857. lookup.mRange.maxCoord[0] = 0;
  858. lookup.mRange.minCoord[1] = 0;
  859. lookup.mRange.maxCoord[1] = 0;
  860. EXPECT_EQ(so5->getContainerLookupInfo().mRange, lookup.mRange);
  861. // Check a bin
  862. Vector<SceneObject*> list;
  863. gClientSceneGraph->getContainer()->dumpBin(1, 0, list);
  864. EXPECT_EQ(list.size(), 1);
  865. EXPECT_EQ(list[0], so1);
  866. gClientSceneGraph->getContainer()->removeObject(so1);
  867. gClientSceneGraph->getContainer()->removeObject(so2);
  868. gClientSceneGraph->getContainer()->removeObject(so3);
  869. gClientSceneGraph->getContainer()->removeObject(so4);
  870. gClientSceneGraph->getContainer()->removeObject(so5);
  871. }
  872. TEST_F(SceneContainerTest, removeObject)
  873. {
  874. // Set up the objects
  875. SceneObjectTestVariant* so1 = NULL;
  876. SceneObjectTestVariant* so2 = NULL;
  877. SceneObjectTestVariant* so3 = NULL;
  878. Sim::findObject("SO1", so1);
  879. Sim::findObject("SO2", so2);
  880. Sim::findObject("SO3", so3);
  881. MatrixF m(1);
  882. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  883. so1->setTransform(m);
  884. m.setPosition(Point3F(0, SceneContainer::csmBinSize, 0));
  885. so2->setTransform(m);
  886. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, 0, 0));
  887. so3->setTransform(m);
  888. gClientSceneGraph->getContainer()->addObject(so1);
  889. gClientSceneGraph->getContainer()->addObject(so2);
  890. gClientSceneGraph->getContainer()->addObject(so3);
  891. EXPECT_EQ(so1->getContainer(), gClientSceneGraph->getContainer());
  892. EXPECT_EQ(so2->getContainer(), gClientSceneGraph->getContainer());
  893. EXPECT_EQ(so3->getContainer(), gClientSceneGraph->getContainer());
  894. // Should get removed correctly
  895. gClientSceneGraph->getContainer()->removeObject(so2);
  896. EXPECT_EQ(so1->getContainer(), gClientSceneGraph->getContainer());
  897. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  898. EXPECT_EQ(so3->getContainer(), gClientSceneGraph->getContainer());
  899. gClientSceneGraph->getContainer()->removeObject(so1);
  900. gClientSceneGraph->getContainer()->removeObject(so3);
  901. EXPECT_EQ(so1->getContainer(), (SceneContainer*)NULL);
  902. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  903. EXPECT_EQ(so3->getContainer(), (SceneContainer*)NULL);
  904. }
  905. TEST_F(SceneContainerTest, insertIntoBins)
  906. {
  907. // Set up the objects
  908. SceneObjectTestVariant* so1 = NULL;
  909. SceneObjectTestVariant* so2 = NULL;
  910. SceneObjectTestVariant* so3 = NULL;
  911. SceneObjectTestVariant* so4 = NULL;
  912. SceneObjectTestVariant* so5 = NULL;
  913. Sim::findObject("SO1", so1);
  914. Sim::findObject("SO2", so2);
  915. Sim::findObject("SO3", so3);
  916. Sim::findObject("SO4", so4);
  917. Sim::findObject("SO5", so5);
  918. so1->setTypeMask(MarkerObjectType);
  919. so3->setTypeMask(MarkerObjectType);
  920. so4->setTypeMask(MarkerObjectType);
  921. MatrixF m(1);
  922. m.setPosition(Point3F(SceneContainer::csmBinSize,0,0));
  923. so1->setTransform(m);
  924. m.setPosition(Point3F(0, SceneContainer::csmBinSize, 0));
  925. so2->setTransform(m);
  926. m.setPosition(Point3F(SceneContainer::csmBinSize*2, 0, 0));
  927. so3->setTransform(m);
  928. m.setPosition(Point3F(SceneContainer::csmBinSize*2, SceneContainer::csmBinSize*2, 0));
  929. so4->setTransform(m);
  930. gClientSceneGraph->getContainer()->insertIntoBins(so1);
  931. gClientSceneGraph->getContainer()->insertIntoBins(so2);
  932. gClientSceneGraph->getContainer()->insertIntoBins(so3);
  933. gClientSceneGraph->getContainer()->insertIntoBins(so4);
  934. gClientSceneGraph->getContainer()->insertIntoBins(so5);
  935. EXPECT_EQ(so1->getContainer(), (SceneContainer*)NULL);
  936. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  937. EXPECT_EQ(so3->getContainer(), (SceneContainer*)NULL);
  938. EXPECT_EQ(so4->getContainer(), (SceneContainer*)NULL);
  939. EXPECT_EQ(so5->getContainer(), (SceneContainer*)NULL);
  940. // Should be put in correct bins
  941. SceneBinListLookup lookup = {};
  942. lookup.mRange.minCoord[0] = 1;
  943. lookup.mRange.maxCoord[0] = 1;
  944. lookup.mRange.minCoord[1] = 0;
  945. lookup.mRange.maxCoord[1] = 0;
  946. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  947. lookup.mRange.minCoord[0] = 0;
  948. lookup.mRange.maxCoord[0] = 0;
  949. lookup.mRange.minCoord[1] = 1;
  950. lookup.mRange.maxCoord[1] = 1;
  951. EXPECT_EQ(so2->getContainerLookupInfo().mRange, lookup.mRange);
  952. lookup.mRange.minCoord[0] = 2;
  953. lookup.mRange.maxCoord[0] = 2;
  954. lookup.mRange.minCoord[1] = 0;
  955. lookup.mRange.maxCoord[1] = 0;
  956. EXPECT_EQ(so3->getContainerLookupInfo().mRange, lookup.mRange);
  957. lookup.mRange.minCoord[0] = 2;
  958. lookup.mRange.maxCoord[0] = 2;
  959. lookup.mRange.minCoord[1] = 2;
  960. lookup.mRange.maxCoord[1] = 2;
  961. EXPECT_EQ(so4->getContainerLookupInfo().mRange, lookup.mRange);
  962. lookup.mRange.minCoord[0] = 0;
  963. lookup.mRange.maxCoord[0] = 0;
  964. lookup.mRange.minCoord[1] = 0;
  965. lookup.mRange.maxCoord[1] = 0;
  966. EXPECT_EQ(so5->getContainerLookupInfo().mRange, lookup.mRange);
  967. // Check a bin
  968. Vector<SceneObject*> list;
  969. gClientSceneGraph->getContainer()->dumpBin(1, 0, list);
  970. EXPECT_EQ(list.size(), 1);
  971. EXPECT_EQ(list[0], so1);
  972. gClientSceneGraph->getContainer()->removeFromBins(so1);
  973. gClientSceneGraph->getContainer()->removeFromBins(so2);
  974. gClientSceneGraph->getContainer()->removeFromBins(so3);
  975. gClientSceneGraph->getContainer()->removeFromBins(so4);
  976. gClientSceneGraph->getContainer()->removeFromBins(so5);
  977. EXPECT_EQ(so1->getContainer(), (SceneContainer*)NULL);
  978. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  979. EXPECT_EQ(so3->getContainer(), (SceneContainer*)NULL);
  980. EXPECT_EQ(so4->getContainer(), (SceneContainer*)NULL);
  981. EXPECT_EQ(so5->getContainer(), (SceneContainer*)NULL);
  982. }
  983. TEST_F(SceneContainerTest, removeFromBins)
  984. {
  985. // Set up the objects
  986. SceneObjectTestVariant* so1 = NULL;
  987. SceneObjectTestVariant* so2 = NULL;
  988. SceneObjectTestVariant* so3 = NULL;
  989. SceneObjectTestVariant* so4 = NULL;
  990. SceneObjectTestVariant* so5 = NULL;
  991. Sim::findObject("SO1", so1);
  992. Sim::findObject("SO2", so2);
  993. Sim::findObject("SO3", so3);
  994. Sim::findObject("SO4", so4);
  995. Sim::findObject("SO5", so5);
  996. so1->setTypeMask(MarkerObjectType);
  997. so3->setTypeMask(MarkerObjectType);
  998. so4->setTypeMask(MarkerObjectType);
  999. MatrixF m(1);
  1000. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  1001. so1->setTransform(m);
  1002. m.setPosition(Point3F(0, SceneContainer::csmBinSize*3, 0));
  1003. so2->setTransform(m);
  1004. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, 0, 0));
  1005. so3->setTransform(m);
  1006. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, SceneContainer::csmBinSize * 2, 0));
  1007. so4->setTransform(m);
  1008. gClientSceneGraph->getContainer()->insertIntoBins(so1);
  1009. gClientSceneGraph->getContainer()->insertIntoBins(so2);
  1010. gClientSceneGraph->getContainer()->insertIntoBins(so3);
  1011. gClientSceneGraph->getContainer()->insertIntoBins(so4);
  1012. gClientSceneGraph->getContainer()->insertIntoBins(so5);
  1013. gClientSceneGraph->getContainer()->removeFromBins(so1);
  1014. gClientSceneGraph->getContainer()->removeFromBins(so2);
  1015. gClientSceneGraph->getContainer()->removeFromBins(so3);
  1016. gClientSceneGraph->getContainer()->removeFromBins(so4);
  1017. gClientSceneGraph->getContainer()->removeFromBins(so5);
  1018. EXPECT_EQ(so1->getContainer(), (SceneContainer*)NULL);
  1019. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  1020. EXPECT_EQ(so3->getContainer(), (SceneContainer*)NULL);
  1021. EXPECT_EQ(so4->getContainer(), (SceneContainer*)NULL);
  1022. EXPECT_EQ(so5->getContainer(), (SceneContainer*)NULL);
  1023. }
  1024. TEST_F(SceneContainerTest, checkBins)
  1025. {
  1026. // Set up the objects
  1027. SceneObjectTestVariant* so1 = NULL;
  1028. Sim::findObject("SO1", so1);
  1029. MatrixF m(1);
  1030. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  1031. so1->setTransform(m);
  1032. gClientSceneGraph->getContainer()->addObject(so1);
  1033. EXPECT_EQ(so1->getContainer(), gClientSceneGraph->getContainer());
  1034. // Should be put in correct bins
  1035. SceneBinListLookup lookup = {};
  1036. lookup.mRange.minCoord[0] = 1;
  1037. lookup.mRange.maxCoord[0] = 1;
  1038. lookup.mRange.minCoord[1] = 0;
  1039. lookup.mRange.maxCoord[1] = 0;
  1040. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  1041. // Check a bin
  1042. Vector<SceneObject*> list;
  1043. gClientSceneGraph->getContainer()->dumpBin(1, 0, list);
  1044. EXPECT_EQ(list.size(), 1);
  1045. EXPECT_EQ(list[0], so1);
  1046. // Move it
  1047. m.setPosition(Point3F(SceneContainer::csmBinSize*2, 0, 0));
  1048. so1->setTransform(m);
  1049. gClientSceneGraph->getContainer()->checkBins(so1);
  1050. lookup.mRange.minCoord[0] = 2;
  1051. lookup.mRange.maxCoord[0] = 2;
  1052. lookup.mRange.minCoord[1] = 0;
  1053. lookup.mRange.maxCoord[1] = 0;
  1054. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  1055. gClientSceneGraph->getContainer()->dumpBin(2, 0, list);
  1056. EXPECT_EQ(list.size(), 1);
  1057. EXPECT_EQ(list[0], so1);
  1058. gClientSceneGraph->getContainer()->removeObject(so1);
  1059. }
  1060. TEST_F(SceneContainerTest, initRadiusSearch)
  1061. {
  1062. // Set up the objects
  1063. SceneObjectTestVariant* so1 = NULL;
  1064. Sim::findObject("SO1", so1);
  1065. MatrixF m(1);
  1066. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  1067. so1->setTransform(m);
  1068. so1->setTypeMask(MarkerObjectType);
  1069. gClientSceneGraph->getContainer()->addObject(so1);
  1070. // Should be put in correct bins
  1071. SceneBinListLookup lookup = {};
  1072. lookup.mRange.minCoord[0] = 1;
  1073. lookup.mRange.maxCoord[0] = 1;
  1074. lookup.mRange.minCoord[1] = 0;
  1075. lookup.mRange.maxCoord[1] = 0;
  1076. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  1077. // Check a bin
  1078. Vector<SceneObject*> list;
  1079. gClientSceneGraph->getContainer()->initRadiusSearch(Point3F(0,0,0), 100.0f, MarkerObjectType);
  1080. EXPECT_EQ(gClientSceneGraph->getContainer()->getRadiusSearchList().size(), 1);
  1081. EXPECT_EQ(gClientSceneGraph->getContainer()->getRadiusSearchList()[0]->getPointer(), so1);
  1082. gClientSceneGraph->getContainer()->removeObject(so1);
  1083. }
  1084. TEST_F(SceneContainerTest, initTypeSearch)
  1085. {
  1086. // Set up the objects
  1087. SceneObjectTestVariant* so1 = NULL;
  1088. Sim::findObject("SO1", so1);
  1089. MatrixF m(1);
  1090. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  1091. so1->setTransform(m);
  1092. so1->setTypeMask(MarkerObjectType);
  1093. gClientSceneGraph->getContainer()->addObject(so1);
  1094. // Check
  1095. Vector<SceneObject*> list;
  1096. gClientSceneGraph->getContainer()->initTypeSearch(MarkerObjectType);
  1097. EXPECT_EQ(gClientSceneGraph->getContainer()->getRadiusSearchList().size(), 1);
  1098. EXPECT_EQ(gClientSceneGraph->getContainer()->getRadiusSearchList()[0]->getPointer(), so1);
  1099. gClientSceneGraph->getContainer()->removeObject(so1);
  1100. }
  1101. TEST_F(SceneContainerTest, getBinRange)
  1102. {
  1103. U32 minBin = 0;
  1104. U32 maxBin = 0;
  1105. SceneContainer::getBinRange(0, 0, minBin, maxBin);
  1106. EXPECT_EQ(minBin == 0 && maxBin == 0, true);
  1107. SceneContainer::getBinRange(0, SceneContainer::csmBinSize*0.5, minBin, maxBin);
  1108. EXPECT_EQ(minBin == 0 && maxBin == 0, true);
  1109. SceneContainer::getBinRange(SceneContainer::csmBinSize * 0.5, SceneContainer::csmBinSize * 0.5, minBin, maxBin);
  1110. EXPECT_EQ(minBin == 0 && maxBin == 0, true);
  1111. SceneContainer::getBinRange(0, SceneContainer::csmBinSize, minBin, maxBin);
  1112. EXPECT_EQ(minBin == 0 && maxBin == 1, true);
  1113. SceneContainer::getBinRange(SceneContainer::csmBinSize * 1.5, SceneContainer::csmBinSize * 1.5, minBin, maxBin);
  1114. EXPECT_EQ(minBin == 1 && maxBin == 1, true);
  1115. SceneContainer::getBinRange(SceneContainer::csmBinSize, SceneContainer::csmBinSize, minBin, maxBin);
  1116. EXPECT_EQ(minBin == 1 && maxBin == 1, true);
  1117. SceneContainer::getBinRange(SceneContainer::csmBinSize*2, SceneContainer::csmBinSize*2, minBin, maxBin);
  1118. EXPECT_EQ(minBin == 2 && maxBin == 2, true);
  1119. SceneContainer::getBinRange(-1, -1, minBin, maxBin);
  1120. EXPECT_EQ(minBin == (SceneContainer::csmNumAxisBins-1) && maxBin == (SceneContainer::csmNumAxisBins - 1), true);
  1121. SceneContainer::getBinRange(SceneContainer::csmTotalAxisBinSize, SceneContainer::csmTotalAxisBinSize, minBin, maxBin);
  1122. EXPECT_EQ(minBin == 0 && maxBin == 0, true);
  1123. SceneContainer::getBinRange(SceneContainer::csmTotalAxisBinSize + SceneContainer::csmBinSize, SceneContainer::csmTotalAxisBinSize + SceneContainer::csmBinSize, minBin, maxBin);
  1124. EXPECT_EQ(minBin == 1 && maxBin == 1, true);
  1125. SceneContainer::getBinRange(-5, SceneContainer::csmTotalAxisBinSize + SceneContainer::csmBinSize, minBin, maxBin);
  1126. EXPECT_EQ(minBin == 15 && maxBin == 30, true);
  1127. }