2
0

BsUtilityTestSuite.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "UnitTests/BsUtilityTestSuite.h"
  4. #include "UnitTests/BsFileSystemTestSuite.h"
  5. #include "Utility/BsOctree.h"
  6. namespace bs
  7. {
  8. struct DebugOctreeElem
  9. {
  10. AABox box;
  11. mutable OctreeElementId octreeId;
  12. };
  13. struct DebugOctreeData
  14. {
  15. Vector<DebugOctreeElem> elements;
  16. };
  17. struct DebugOctreeOptions
  18. {
  19. enum { LoosePadding = 16 };
  20. enum { MinElementsPerNode = 8 };
  21. enum { MaxElementsPerNode = 16 };
  22. enum { MaxDepth = 12};
  23. static simd::AABox getBounds(UINT32 elem, void* context)
  24. {
  25. DebugOctreeData* octreeData = (DebugOctreeData*)context;
  26. return simd::AABox(octreeData->elements[elem].box);
  27. }
  28. static void setElementId(UINT32 elem, const OctreeElementId& id, void* context)
  29. {
  30. DebugOctreeData* octreeData = (DebugOctreeData*)context;
  31. octreeData->elements[elem].octreeId = id;
  32. }
  33. };
  34. typedef Octree<UINT32, DebugOctreeOptions> DebugOctree;
  35. void UtilityTestSuite::startUp()
  36. {
  37. SPtr<TestSuite> fileSystemTests = create<FileSystemTestSuite>();
  38. add(fileSystemTests);
  39. }
  40. void UtilityTestSuite::shutDown()
  41. {
  42. }
  43. UtilityTestSuite::UtilityTestSuite()
  44. {
  45. BS_ADD_TEST(UtilityTestSuite::testOctree);
  46. }
  47. void UtilityTestSuite::testOctree()
  48. {
  49. DebugOctreeData octreeData;
  50. DebugOctree octree(Vector3::ZERO, 800.0f, &octreeData);
  51. struct SizeAndCount
  52. {
  53. float sizeMin;
  54. float sizeMax;
  55. UINT32 count;
  56. };
  57. SizeAndCount types[]
  58. {
  59. { 0.02f, 0.2f, 2000 }, // Very small objects
  60. { 0.2f, 1.0f, 2000 }, // Small objects
  61. { 1.0f, 5.0f, 5000 }, // Medium sized objects
  62. { 5.0f, 30.0f, 4000 }, // Large objects
  63. { 30.0f, 100.0f, 2000 } // Very large objects
  64. };
  65. float placementExtents = 750.0f;
  66. for(UINT32 i = 0; i < sizeof(types)/sizeof(types[0]); i++)
  67. {
  68. for (UINT32 j = 0; j < types[i].count; j++)
  69. {
  70. Vector3 position(
  71. ((rand() / (float)RAND_MAX) * 2.0f - 1.0f) * placementExtents,
  72. ((rand() / (float)RAND_MAX) * 2.0f - 1.0f) * placementExtents,
  73. ((rand() / (float)RAND_MAX) * 2.0f - 1.0f) * placementExtents
  74. );
  75. Vector3 extents(
  76. types[i].sizeMin + ((rand() / (float)RAND_MAX)) * (types[i].sizeMax - types[i].sizeMin) * 0.5f,
  77. types[i].sizeMin + ((rand() / (float)RAND_MAX)) * (types[i].sizeMax - types[i].sizeMin) * 0.5f,
  78. types[i].sizeMin + ((rand() / (float)RAND_MAX)) * (types[i].sizeMax - types[i].sizeMin) * 0.5f
  79. );
  80. DebugOctreeElem elem;
  81. elem.box = AABox(position - extents, position + extents);
  82. UINT32 elemIdx = (UINT32)octreeData.elements.size();
  83. octreeData.elements.push_back(elem);
  84. octree.addElement(elemIdx);
  85. }
  86. }
  87. DebugOctreeElem manualElems[3];
  88. manualElems[0].box = AABox(Vector3(100.0f, 100.0f, 100.f), Vector3(110.0f, 115.0f, 110.0f));
  89. manualElems[1].box = AABox(Vector3(200.0f, 100.0f, 100.f), Vector3(250.0f, 150.0f, 150.0f));
  90. manualElems[2].box = AABox(Vector3(90.0f, 90.0f, 90.f), Vector3(105.0f, 105.0f, 110.0f));
  91. for(UINT32 i = 0; i < 3; i++)
  92. {
  93. UINT32 elemIdx = (UINT32)octreeData.elements.size();
  94. octreeData.elements.push_back(manualElems[i]);
  95. octree.addElement(elemIdx);
  96. }
  97. AABox queryBounds = manualElems[0].box;
  98. DebugOctree::BoxIntersectIterator interIter(octree, queryBounds);
  99. Vector<UINT32> overlapElements;
  100. while(interIter.moveNext())
  101. {
  102. UINT32 element = interIter.getElement();
  103. overlapElements.push_back(element);
  104. // Manually check for intersections
  105. BS_TEST_ASSERT(octreeData.elements[element].box.intersects(queryBounds));
  106. }
  107. // Ensure that all we have found all possible overlaps by manually testing all elements
  108. UINT32 elemIdx = 0;
  109. for(auto& entry : octreeData.elements)
  110. {
  111. if(entry.box.intersects(queryBounds))
  112. {
  113. auto iterFind = std::find(overlapElements.begin(), overlapElements.end(), elemIdx);
  114. BS_TEST_ASSERT(iterFind != overlapElements.end());
  115. }
  116. elemIdx++;
  117. }
  118. // Ensure nothing goes wrong during element removal
  119. for(auto& entry : octreeData.elements)
  120. octree.removeElement(entry.octreeId);
  121. }
  122. }