sceneContainerTest.cpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  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 onAdd()
  481. {
  482. if (Parent::onAdd())
  483. {
  484. mNumCastRayCalls = 0;
  485. mNumBuildConvexCalls = 0;
  486. mNumBuildPolyListCalls = 0;
  487. mNumCollideBoxCalls = 0;
  488. mNumCastRayRenderedCalls = 0;
  489. if (mAddCallback)
  490. mAddCallback();
  491. return true;
  492. }
  493. return false;
  494. }
  495. void onRemove()
  496. {
  497. removeFromScene();
  498. Parent::onRemove();
  499. }
  500. void setTypeMask(U32 mask)
  501. {
  502. mTypeMask = mask;
  503. }
  504. virtual void buildConvex(const Box3F& box, Convex* convex)
  505. {
  506. mNumBuildConvexCalls++;
  507. }
  508. virtual bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F& box, const SphereF& sphere)
  509. {
  510. mNumBuildPolyListCalls++;
  511. return false;
  512. }
  513. virtual bool castRay(const Point3F& start, const Point3F& end, RayInfo* info)
  514. {
  515. mNumCastRayCalls++;
  516. return false;
  517. }
  518. virtual bool castRayRendered(const Point3F& start, const Point3F& end, RayInfo* info)
  519. {
  520. mNumCastRayRenderedCalls++;
  521. return false;
  522. }
  523. virtual bool collideBox(const Point3F& start, const Point3F& end, RayInfo* info)
  524. {
  525. mNumCollideBoxCalls++;
  526. return false;
  527. }
  528. void setWorldBox(const Box3F& box)
  529. {
  530. mWorldBox = box;
  531. }
  532. };
  533. class SceneContainerTest : public ::testing::Test
  534. {
  535. protected:
  536. SimGroup* mGroup;
  537. SceneContainerTest()
  538. {
  539. }
  540. void SetUp() override
  541. {
  542. mGroup = new SimGroup();
  543. gEditingMission = true;
  544. SceneObjectTestVariant* so1 = new SceneObjectTestVariant;
  545. so1->registerObject("SO1");
  546. SceneObjectTestVariant* so2 = new SceneObjectTestVariant;
  547. so2->registerObject("SO2");
  548. SceneObjectTestVariant* so3 = new SceneObjectTestVariant;
  549. so3->registerObject("SO3");
  550. SceneObjectTestVariant* so4 = new SceneObjectTestVariant;
  551. so4->registerObject("SO4");
  552. SceneObjectTestVariant* so5 = new SceneObjectTestVariant;
  553. so5->registerObject("SO5");
  554. mGroup->addObject(so1);
  555. mGroup->addObject(so2);
  556. mGroup->addObject(so3);
  557. mGroup->addObject(so4);
  558. mGroup->addObject(so5);
  559. gEditingMission = false;
  560. }
  561. void TearDown() override
  562. {
  563. mGroup->deleteObject();
  564. }
  565. };
  566. TEST_F(SceneContainerTest, findObjects)
  567. {
  568. // Set up the objects
  569. SceneObjectTestVariant* so1 = NULL;
  570. SceneObjectTestVariant* so2 = NULL;
  571. SceneObjectTestVariant* so3 = NULL;
  572. SceneObjectTestVariant* so4 = NULL;
  573. SceneObjectTestVariant* so5 = NULL;
  574. Sim::findObject("SO1", so1);
  575. Sim::findObject("SO2", so2);
  576. Sim::findObject("SO3", so3);
  577. Sim::findObject("SO4", so4);
  578. Sim::findObject("SO5", so5);
  579. so1->setTypeMask(MarkerObjectType);
  580. so3->setTypeMask(MarkerObjectType);
  581. so4->setTypeMask(MarkerObjectType);
  582. so1->addToScene();
  583. so2->addToScene();
  584. so3->addToScene();
  585. so4->addToScene();
  586. so5->addToScene();
  587. // Should find all 3 objects we put there in the setup
  588. SceneContainer::ObjectList outList;
  589. gServerSceneGraph->getContainer()->findObjectList(MarkerObjectType, &outList);
  590. EXPECT_EQ(outList.size(), 3);
  591. EXPECT_EQ(outList[0], so1);
  592. EXPECT_EQ(outList[1], so3);
  593. EXPECT_EQ(outList[2], so4);
  594. outList.clear();
  595. // Won't find other objects
  596. gServerSceneGraph->getContainer()->findObjectList(PlayerObjectType, &outList);
  597. EXPECT_EQ(outList.size(), 0);
  598. so1->removeFromScene();
  599. so2->removeFromScene();
  600. so3->removeFromScene();
  601. so4->removeFromScene();
  602. so5->removeFromScene();
  603. }
  604. TEST_F(SceneContainerTest, polyhedronFindObjects)
  605. {
  606. // Basically: only gets called on objects in the right bin
  607. SceneObjectTestVariant* so1 = NULL;
  608. Polyhedron shape;
  609. shape.buildBox(MatrixF(1), Box3F(Point3F(0,0,0), Point3F(100,100,100)), true);
  610. Sim::findObject("SO1", so1);
  611. MatrixF m(1);
  612. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  613. so1->setTypeMask(MarkerObjectType);
  614. so1->setTransform(m);
  615. gClientSceneGraph->getContainer()->addObject(so1);
  616. static Vector<SceneObject*> foundList;
  617. foundList.clear();
  618. RayInfo info;
  619. gClientSceneGraph->getContainer()->polyhedronFindObjects(shape, MarkerObjectType, [](SceneObject* object, void* key) {
  620. });
  621. gClientSceneGraph->getContainer()->removeObject(so1);
  622. }
  623. TEST_F(SceneContainerTest, findObjectList)
  624. {
  625. // Basically: only gets called on objects in the right bin
  626. SceneObjectTestVariant* so1 = NULL;
  627. Sim::findObject("SO1", so1);
  628. MatrixF m(1);
  629. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  630. so1->setTypeMask(MarkerObjectType);
  631. so1->setTransform(m);
  632. gClientSceneGraph->getContainer()->addObject(so1);
  633. Vector<SceneObject*> foundList;
  634. PolyListContext ctx;
  635. Box3F box(Point3F(0, 0, 0), Point3F(0, 100, 0));
  636. RayInfo info;
  637. gClientSceneGraph->getContainer()->findObjectList(box, MarkerObjectType, &foundList);
  638. EXPECT_EQ(foundList.size(), 0);
  639. foundList.clear();
  640. box = Box3F(Point3F(0, 0, 0), Point3F(100, 100, 0));
  641. gClientSceneGraph->getContainer()->findObjectList(box, MarkerObjectType, &foundList);
  642. EXPECT_EQ(foundList.size(), 1);
  643. gClientSceneGraph->getContainer()->removeObject(so1);
  644. }
  645. TEST_F(SceneContainerTest, castRay)
  646. {
  647. // Basically: only gets called on objects in the right bin
  648. SceneObjectTestVariant* so1 = NULL;
  649. Sim::findObject("SO1", so1);
  650. MatrixF m(1);
  651. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  652. so1->setTypeMask(MarkerObjectType);
  653. so1->setTransform(m);
  654. so1->setWorldBox(Box3F(m.getPosition(), m.getPosition() + Point3F(SceneContainer::csmBinSize-2, SceneContainer::csmBinSize-2, 10)));
  655. gClientSceneGraph->getContainer()->addObject(so1);
  656. Point3F start(0, 0, 0);
  657. Point3F end(0, 100, 0);
  658. RayInfo info;
  659. bool castCheck = gClientSceneGraph->getContainer()->castRay(start, end, MarkerObjectType, &info);
  660. EXPECT_EQ(so1->mNumCastRayCalls, 0);
  661. start = Point3F(SceneContainer::csmBinSize + 1, SceneContainer::csmBinSize + 1, 0);
  662. castCheck = gClientSceneGraph->getContainer()->castRay(start, end, MarkerObjectType, &info);
  663. EXPECT_EQ(so1->mNumCastRayCalls, 1);
  664. gClientSceneGraph->getContainer()->removeObject(so1);
  665. }
  666. TEST_F(SceneContainerTest, castRayRendered)
  667. {
  668. // Basically: only gets called on objects in the right bin
  669. SceneObjectTestVariant* so1 = NULL;
  670. Sim::findObject("SO1", so1);
  671. MatrixF m(1);
  672. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  673. so1->setTypeMask(MarkerObjectType);
  674. so1->setTransform(m);
  675. so1->setWorldBox(Box3F(m.getPosition(), m.getPosition() + Point3F(SceneContainer::csmBinSize - 2, SceneContainer::csmBinSize - 2, 10)));
  676. gClientSceneGraph->getContainer()->addObject(so1);
  677. Point3F start(0, 0, 0);
  678. Point3F end(0, 100, 0);
  679. RayInfo info;
  680. bool castCheck = gClientSceneGraph->getContainer()->castRayRendered(start, end, MarkerObjectType, &info);
  681. EXPECT_EQ(so1->mNumCastRayRenderedCalls, 0);
  682. start = Point3F(SceneContainer::csmBinSize + 1, SceneContainer::csmBinSize + 1, 0);
  683. castCheck = gClientSceneGraph->getContainer()->castRayRendered(start, end, MarkerObjectType, &info);
  684. EXPECT_EQ(so1->mNumCastRayRenderedCalls, 1);
  685. gClientSceneGraph->getContainer()->removeObject(so1);
  686. }
  687. TEST_F(SceneContainerTest, collideBox)
  688. {
  689. // Basically: only gets called on objects in the right bin
  690. SceneObjectTestVariant* so1 = NULL;
  691. Sim::findObject("SO1", so1);
  692. MatrixF m(1);
  693. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  694. so1->setTypeMask(MarkerObjectType);
  695. so1->setTransform(m);
  696. gClientSceneGraph->getContainer()->addObject(so1);
  697. Point3F start(0, 0, 0);
  698. Point3F end(0, 100, 0);
  699. RayInfo info;
  700. bool castCheck = gClientSceneGraph->getContainer()->collideBox(start, end, 0xFFFFFFFF, &info);
  701. EXPECT_EQ(so1->mNumCollideBoxCalls, 0);
  702. start = Point3F(SceneContainer::csmBinSize + 1, SceneContainer::csmBinSize + 1, 0);
  703. castCheck = gClientSceneGraph->getContainer()->collideBox(start, end, 0xFFFFFFFF, &info);
  704. EXPECT_EQ(so1->mNumCollideBoxCalls, 1);
  705. gClientSceneGraph->getContainer()->removeObject(so1);
  706. }
  707. TEST_F(SceneContainerTest, buildPolyList)
  708. {
  709. // Basically: only gets called on objects in the right bin
  710. SceneObjectTestVariant* so1 = NULL;
  711. Sim::findObject("SO1", so1);
  712. MatrixF m(1);
  713. m.setPosition(Point3F(SceneContainer::csmBinSize, SceneContainer::csmBinSize, 0));
  714. so1->setTypeMask(MarkerObjectType);
  715. so1->setTransform(m);
  716. gClientSceneGraph->getContainer()->addObject(so1);
  717. ClippedPolyList polyList;
  718. Box3F box(Point3F(0, 0, 0), Point3F(10, 10, 0));
  719. RayInfo info;
  720. bool castCheck = gClientSceneGraph->getContainer()->buildPolyList(PLC_Collision, box, 0xFFFFFFFF, &polyList);
  721. EXPECT_EQ(so1->mNumBuildPolyListCalls, 0);
  722. box = Box3F(Point3F(0, 0, 0), Point3F(100, 100, 0));
  723. castCheck = gClientSceneGraph->getContainer()->buildPolyList(PLC_Collision, box, 0xFFFFFFFF, &polyList);
  724. EXPECT_EQ(so1->mNumBuildPolyListCalls, 1);
  725. gClientSceneGraph->getContainer()->removeObject(so1);
  726. }
  727. TEST_F(SceneContainerTest, addObject)
  728. {
  729. // Set up the objects
  730. SceneObjectTestVariant* so1 = NULL;
  731. SceneObjectTestVariant* so2 = NULL;
  732. SceneObjectTestVariant* so3 = NULL;
  733. SceneObjectTestVariant* so4 = NULL;
  734. SceneObjectTestVariant* so5 = NULL;
  735. Sim::findObject("SO1", so1);
  736. Sim::findObject("SO2", so2);
  737. Sim::findObject("SO3", so3);
  738. Sim::findObject("SO4", so4);
  739. Sim::findObject("SO5", so5);
  740. so1->setTypeMask(MarkerObjectType);
  741. so3->setTypeMask(MarkerObjectType);
  742. so4->setTypeMask(MarkerObjectType);
  743. MatrixF m(1);
  744. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  745. so1->setTransform(m);
  746. m.setPosition(Point3F(0, SceneContainer::csmBinSize, 0));
  747. so2->setTransform(m);
  748. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, 0, 0));
  749. so3->setTransform(m);
  750. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, SceneContainer::csmBinSize * 2, 0));
  751. so4->setTransform(m);
  752. gClientSceneGraph->getContainer()->addObject(so1);
  753. gClientSceneGraph->getContainer()->addObject(so2);
  754. gClientSceneGraph->getContainer()->addObject(so3);
  755. gClientSceneGraph->getContainer()->addObject(so4);
  756. gClientSceneGraph->getContainer()->addObject(so5);
  757. EXPECT_EQ(so1->getContainer(), gClientSceneGraph->getContainer());
  758. EXPECT_EQ(so2->getContainer(), gClientSceneGraph->getContainer());
  759. EXPECT_EQ(so3->getContainer(), gClientSceneGraph->getContainer());
  760. EXPECT_EQ(so4->getContainer(), gClientSceneGraph->getContainer());
  761. EXPECT_EQ(so5->getContainer(), gClientSceneGraph->getContainer());
  762. // Should be put in correct bins
  763. U32 startIndex = so1->getRootContainerIndex();
  764. EXPECT_EQ(so2->getRootContainerIndex(), startIndex + 1);
  765. EXPECT_EQ(so3->getRootContainerIndex(), startIndex + 2);
  766. EXPECT_EQ(so4->getRootContainerIndex(), startIndex + 3);
  767. EXPECT_EQ(so5->getRootContainerIndex(), startIndex + 4);
  768. SceneBinListLookup lookup = {};
  769. lookup.mRange.minCoord[0] = 1;
  770. lookup.mRange.maxCoord[0] = 1;
  771. lookup.mRange.minCoord[1] = 0;
  772. lookup.mRange.maxCoord[1] = 0;
  773. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  774. lookup.mRange.minCoord[0] = 0;
  775. lookup.mRange.maxCoord[0] = 0;
  776. lookup.mRange.minCoord[1] = 1;
  777. lookup.mRange.maxCoord[1] = 1;
  778. EXPECT_EQ(so2->getContainerLookupInfo().mRange, lookup.mRange);
  779. lookup.mRange.minCoord[0] = 2;
  780. lookup.mRange.maxCoord[0] = 2;
  781. lookup.mRange.minCoord[1] = 0;
  782. lookup.mRange.maxCoord[1] = 0;
  783. EXPECT_EQ(so3->getContainerLookupInfo().mRange, lookup.mRange);
  784. lookup.mRange.minCoord[0] = 2;
  785. lookup.mRange.maxCoord[0] = 2;
  786. lookup.mRange.minCoord[1] = 2;
  787. lookup.mRange.maxCoord[1] = 2;
  788. EXPECT_EQ(so4->getContainerLookupInfo().mRange, lookup.mRange);
  789. lookup.mRange.minCoord[0] = 0;
  790. lookup.mRange.maxCoord[0] = 0;
  791. lookup.mRange.minCoord[1] = 0;
  792. lookup.mRange.maxCoord[1] = 0;
  793. EXPECT_EQ(so5->getContainerLookupInfo().mRange, lookup.mRange);
  794. // Check a bin
  795. Vector<SceneObject*> list;
  796. gClientSceneGraph->getContainer()->dumpBin(1, 0, list);
  797. EXPECT_EQ(list.size(), 1);
  798. EXPECT_EQ(list[0], so1);
  799. gClientSceneGraph->getContainer()->removeObject(so1);
  800. gClientSceneGraph->getContainer()->removeObject(so2);
  801. gClientSceneGraph->getContainer()->removeObject(so3);
  802. gClientSceneGraph->getContainer()->removeObject(so4);
  803. gClientSceneGraph->getContainer()->removeObject(so5);
  804. }
  805. TEST_F(SceneContainerTest, removeObject)
  806. {
  807. // Set up the objects
  808. SceneObjectTestVariant* so1 = NULL;
  809. SceneObjectTestVariant* so2 = NULL;
  810. SceneObjectTestVariant* so3 = NULL;
  811. Sim::findObject("SO1", so1);
  812. Sim::findObject("SO2", so2);
  813. Sim::findObject("SO3", so3);
  814. MatrixF m(1);
  815. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  816. so1->setTransform(m);
  817. m.setPosition(Point3F(0, SceneContainer::csmBinSize, 0));
  818. so2->setTransform(m);
  819. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, 0, 0));
  820. so3->setTransform(m);
  821. gClientSceneGraph->getContainer()->addObject(so1);
  822. gClientSceneGraph->getContainer()->addObject(so2);
  823. gClientSceneGraph->getContainer()->addObject(so3);
  824. EXPECT_EQ(so1->getContainer(), gClientSceneGraph->getContainer());
  825. EXPECT_EQ(so2->getContainer(), gClientSceneGraph->getContainer());
  826. EXPECT_EQ(so3->getContainer(), gClientSceneGraph->getContainer());
  827. // Should get removed correctly
  828. gClientSceneGraph->getContainer()->removeObject(so2);
  829. EXPECT_EQ(so1->getContainer(), gClientSceneGraph->getContainer());
  830. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  831. EXPECT_EQ(so3->getContainer(), gClientSceneGraph->getContainer());
  832. gClientSceneGraph->getContainer()->removeObject(so1);
  833. gClientSceneGraph->getContainer()->removeObject(so3);
  834. EXPECT_EQ(so1->getContainer(), (SceneContainer*)NULL);
  835. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  836. EXPECT_EQ(so3->getContainer(), (SceneContainer*)NULL);
  837. }
  838. TEST_F(SceneContainerTest, insertIntoBins)
  839. {
  840. // Set up the objects
  841. SceneObjectTestVariant* so1 = NULL;
  842. SceneObjectTestVariant* so2 = NULL;
  843. SceneObjectTestVariant* so3 = NULL;
  844. SceneObjectTestVariant* so4 = NULL;
  845. SceneObjectTestVariant* so5 = NULL;
  846. Sim::findObject("SO1", so1);
  847. Sim::findObject("SO2", so2);
  848. Sim::findObject("SO3", so3);
  849. Sim::findObject("SO4", so4);
  850. Sim::findObject("SO5", so5);
  851. so1->setTypeMask(MarkerObjectType);
  852. so3->setTypeMask(MarkerObjectType);
  853. so4->setTypeMask(MarkerObjectType);
  854. MatrixF m(1);
  855. m.setPosition(Point3F(SceneContainer::csmBinSize,0,0));
  856. so1->setTransform(m);
  857. m.setPosition(Point3F(0, SceneContainer::csmBinSize, 0));
  858. so2->setTransform(m);
  859. m.setPosition(Point3F(SceneContainer::csmBinSize*2, 0, 0));
  860. so3->setTransform(m);
  861. m.setPosition(Point3F(SceneContainer::csmBinSize*2, SceneContainer::csmBinSize*2, 0));
  862. so4->setTransform(m);
  863. gClientSceneGraph->getContainer()->insertIntoBins(so1);
  864. gClientSceneGraph->getContainer()->insertIntoBins(so2);
  865. gClientSceneGraph->getContainer()->insertIntoBins(so3);
  866. gClientSceneGraph->getContainer()->insertIntoBins(so4);
  867. gClientSceneGraph->getContainer()->insertIntoBins(so5);
  868. EXPECT_EQ(so1->getContainer(), (SceneContainer*)NULL);
  869. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  870. EXPECT_EQ(so3->getContainer(), (SceneContainer*)NULL);
  871. EXPECT_EQ(so4->getContainer(), (SceneContainer*)NULL);
  872. EXPECT_EQ(so5->getContainer(), (SceneContainer*)NULL);
  873. // Should be put in correct bins
  874. SceneBinListLookup lookup = {};
  875. lookup.mRange.minCoord[0] = 1;
  876. lookup.mRange.maxCoord[0] = 1;
  877. lookup.mRange.minCoord[1] = 0;
  878. lookup.mRange.maxCoord[1] = 0;
  879. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  880. lookup.mRange.minCoord[0] = 0;
  881. lookup.mRange.maxCoord[0] = 0;
  882. lookup.mRange.minCoord[1] = 1;
  883. lookup.mRange.maxCoord[1] = 1;
  884. EXPECT_EQ(so2->getContainerLookupInfo().mRange, lookup.mRange);
  885. lookup.mRange.minCoord[0] = 2;
  886. lookup.mRange.maxCoord[0] = 2;
  887. lookup.mRange.minCoord[1] = 0;
  888. lookup.mRange.maxCoord[1] = 0;
  889. EXPECT_EQ(so3->getContainerLookupInfo().mRange, lookup.mRange);
  890. lookup.mRange.minCoord[0] = 2;
  891. lookup.mRange.maxCoord[0] = 2;
  892. lookup.mRange.minCoord[1] = 2;
  893. lookup.mRange.maxCoord[1] = 2;
  894. EXPECT_EQ(so4->getContainerLookupInfo().mRange, lookup.mRange);
  895. lookup.mRange.minCoord[0] = 0;
  896. lookup.mRange.maxCoord[0] = 0;
  897. lookup.mRange.minCoord[1] = 0;
  898. lookup.mRange.maxCoord[1] = 0;
  899. EXPECT_EQ(so5->getContainerLookupInfo().mRange, lookup.mRange);
  900. // Check a bin
  901. Vector<SceneObject*> list;
  902. gClientSceneGraph->getContainer()->dumpBin(1, 0, list);
  903. EXPECT_EQ(list.size(), 1);
  904. EXPECT_EQ(list[0], so1);
  905. gClientSceneGraph->getContainer()->removeFromBins(so1);
  906. gClientSceneGraph->getContainer()->removeFromBins(so2);
  907. gClientSceneGraph->getContainer()->removeFromBins(so3);
  908. gClientSceneGraph->getContainer()->removeFromBins(so4);
  909. gClientSceneGraph->getContainer()->removeFromBins(so5);
  910. EXPECT_EQ(so1->getContainer(), (SceneContainer*)NULL);
  911. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  912. EXPECT_EQ(so3->getContainer(), (SceneContainer*)NULL);
  913. EXPECT_EQ(so4->getContainer(), (SceneContainer*)NULL);
  914. EXPECT_EQ(so5->getContainer(), (SceneContainer*)NULL);
  915. }
  916. TEST_F(SceneContainerTest, removeFromBins)
  917. {
  918. // Set up the objects
  919. SceneObjectTestVariant* so1 = NULL;
  920. SceneObjectTestVariant* so2 = NULL;
  921. SceneObjectTestVariant* so3 = NULL;
  922. SceneObjectTestVariant* so4 = NULL;
  923. SceneObjectTestVariant* so5 = NULL;
  924. Sim::findObject("SO1", so1);
  925. Sim::findObject("SO2", so2);
  926. Sim::findObject("SO3", so3);
  927. Sim::findObject("SO4", so4);
  928. Sim::findObject("SO5", so5);
  929. so1->setTypeMask(MarkerObjectType);
  930. so3->setTypeMask(MarkerObjectType);
  931. so4->setTypeMask(MarkerObjectType);
  932. MatrixF m(1);
  933. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  934. so1->setTransform(m);
  935. m.setPosition(Point3F(0, SceneContainer::csmBinSize*3, 0));
  936. so2->setTransform(m);
  937. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, 0, 0));
  938. so3->setTransform(m);
  939. m.setPosition(Point3F(SceneContainer::csmBinSize * 2, SceneContainer::csmBinSize * 2, 0));
  940. so4->setTransform(m);
  941. gClientSceneGraph->getContainer()->insertIntoBins(so1);
  942. gClientSceneGraph->getContainer()->insertIntoBins(so2);
  943. gClientSceneGraph->getContainer()->insertIntoBins(so3);
  944. gClientSceneGraph->getContainer()->insertIntoBins(so4);
  945. gClientSceneGraph->getContainer()->insertIntoBins(so5);
  946. gClientSceneGraph->getContainer()->removeFromBins(so1);
  947. gClientSceneGraph->getContainer()->removeFromBins(so2);
  948. gClientSceneGraph->getContainer()->removeFromBins(so3);
  949. gClientSceneGraph->getContainer()->removeFromBins(so4);
  950. gClientSceneGraph->getContainer()->removeFromBins(so5);
  951. EXPECT_EQ(so1->getContainer(), (SceneContainer*)NULL);
  952. EXPECT_EQ(so2->getContainer(), (SceneContainer*)NULL);
  953. EXPECT_EQ(so3->getContainer(), (SceneContainer*)NULL);
  954. EXPECT_EQ(so4->getContainer(), (SceneContainer*)NULL);
  955. EXPECT_EQ(so5->getContainer(), (SceneContainer*)NULL);
  956. }
  957. TEST_F(SceneContainerTest, checkBins)
  958. {
  959. // Set up the objects
  960. SceneObjectTestVariant* so1 = NULL;
  961. Sim::findObject("SO1", so1);
  962. MatrixF m(1);
  963. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  964. so1->setTransform(m);
  965. gClientSceneGraph->getContainer()->addObject(so1);
  966. EXPECT_EQ(so1->getContainer(), gClientSceneGraph->getContainer());
  967. // Should be put in correct bins
  968. SceneBinListLookup lookup = {};
  969. lookup.mRange.minCoord[0] = 1;
  970. lookup.mRange.maxCoord[0] = 1;
  971. lookup.mRange.minCoord[1] = 0;
  972. lookup.mRange.maxCoord[1] = 0;
  973. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  974. // Check a bin
  975. Vector<SceneObject*> list;
  976. gClientSceneGraph->getContainer()->dumpBin(1, 0, list);
  977. EXPECT_EQ(list.size(), 1);
  978. EXPECT_EQ(list[0], so1);
  979. // Move it
  980. m.setPosition(Point3F(SceneContainer::csmBinSize*2, 0, 0));
  981. so1->setTransform(m);
  982. gClientSceneGraph->getContainer()->checkBins(so1);
  983. lookup.mRange.minCoord[0] = 2;
  984. lookup.mRange.maxCoord[0] = 2;
  985. lookup.mRange.minCoord[1] = 0;
  986. lookup.mRange.maxCoord[1] = 0;
  987. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  988. gClientSceneGraph->getContainer()->dumpBin(2, 0, list);
  989. EXPECT_EQ(list.size(), 1);
  990. EXPECT_EQ(list[0], so1);
  991. gClientSceneGraph->getContainer()->removeObject(so1);
  992. }
  993. TEST_F(SceneContainerTest, initRadiusSearch)
  994. {
  995. // Set up the objects
  996. SceneObjectTestVariant* so1 = NULL;
  997. Sim::findObject("SO1", so1);
  998. MatrixF m(1);
  999. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  1000. so1->setTransform(m);
  1001. so1->setTypeMask(MarkerObjectType);
  1002. gClientSceneGraph->getContainer()->addObject(so1);
  1003. // Should be put in correct bins
  1004. SceneBinListLookup lookup = {};
  1005. lookup.mRange.minCoord[0] = 1;
  1006. lookup.mRange.maxCoord[0] = 1;
  1007. lookup.mRange.minCoord[1] = 0;
  1008. lookup.mRange.maxCoord[1] = 0;
  1009. EXPECT_EQ(so1->getContainerLookupInfo().mRange, lookup.mRange);
  1010. // Check a bin
  1011. Vector<SceneObject*> list;
  1012. gClientSceneGraph->getContainer()->initRadiusSearch(Point3F(0,0,0), 100.0f, MarkerObjectType);
  1013. EXPECT_EQ(gClientSceneGraph->getContainer()->getRadiusSearchList().size(), 1);
  1014. EXPECT_EQ(gClientSceneGraph->getContainer()->getRadiusSearchList()[0]->getPointer(), so1);
  1015. gClientSceneGraph->getContainer()->removeObject(so1);
  1016. }
  1017. TEST_F(SceneContainerTest, initTypeSearch)
  1018. {
  1019. // Set up the objects
  1020. SceneObjectTestVariant* so1 = NULL;
  1021. Sim::findObject("SO1", so1);
  1022. MatrixF m(1);
  1023. m.setPosition(Point3F(SceneContainer::csmBinSize, 0, 0));
  1024. so1->setTransform(m);
  1025. so1->setTypeMask(MarkerObjectType);
  1026. gClientSceneGraph->getContainer()->addObject(so1);
  1027. // Check
  1028. Vector<SceneObject*> list;
  1029. gClientSceneGraph->getContainer()->initTypeSearch(MarkerObjectType);
  1030. EXPECT_EQ(gClientSceneGraph->getContainer()->getRadiusSearchList().size(), 1);
  1031. EXPECT_EQ(gClientSceneGraph->getContainer()->getRadiusSearchList()[0]->getPointer(), so1);
  1032. gClientSceneGraph->getContainer()->removeObject(so1);
  1033. }
  1034. TEST_F(SceneContainerTest, getBinRange)
  1035. {
  1036. U32 minBin = 0;
  1037. U32 maxBin = 0;
  1038. SceneContainer::getBinRange(0, 0, minBin, maxBin);
  1039. SceneContainer::getBinRange(0, SceneContainer::csmBinSize, minBin, maxBin);
  1040. EXPECT_EQ(minBin == 0 && maxBin == 1, true);
  1041. SceneContainer::getBinRange(SceneContainer::csmBinSize, SceneContainer::csmBinSize, minBin, maxBin);
  1042. EXPECT_EQ(minBin == 1 && maxBin == 1, true);
  1043. SceneContainer::getBinRange(SceneContainer::csmBinSize*2, SceneContainer::csmBinSize*2, minBin, maxBin);
  1044. EXPECT_EQ(minBin == 2 && maxBin == 2, true);
  1045. SceneContainer::getBinRange(-1, -1, minBin, maxBin);
  1046. EXPECT_EQ(minBin == (SceneContainer::csmNumAxisBins-1) && maxBin == (SceneContainer::csmNumAxisBins - 1), true);
  1047. SceneContainer::getBinRange(SceneContainer::csmTotalAxisBinSize, SceneContainer::csmTotalAxisBinSize, minBin, maxBin);
  1048. EXPECT_EQ(minBin == 0 && maxBin == 0, true);
  1049. SceneContainer::getBinRange(SceneContainer::csmTotalAxisBinSize + SceneContainer::csmBinSize, SceneContainer::csmTotalAxisBinSize + SceneContainer::csmBinSize, minBin, maxBin);
  1050. EXPECT_EQ(minBin == 1 && maxBin == 1, true);
  1051. SceneContainer::getBinRange(-5, SceneContainer::csmTotalAxisBinSize + SceneContainer::csmBinSize, minBin, maxBin);
  1052. EXPECT_EQ(minBin == 15 && maxBin == 30, true);
  1053. }