From 06f56d13d14cd4b03617f7a2a8cbf6bea0fcc36c Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Tue, 8 Dec 2015 11:14:01 +0100 Subject: [PATCH 01/10] added some octTreeTest tests and a few comments in OctTree --- src/Engine/Core/OctTree.cpp | 2 ++ src/Tests/OctTreeTest.cpp | 43 ++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/Engine/Core/OctTree.cpp b/src/Engine/Core/OctTree.cpp index f98720be..7481e770 100644 --- a/src/Engine/Core/OctTree.cpp +++ b/src/Engine/Core/OctTree.cpp @@ -74,6 +74,7 @@ OctTree::~OctTree() { for (OctTree*& c : m_Children) { if (c != nullptr) { + //recursively delete (this calls the deconstructor again) delete c; c = nullptr; } @@ -166,6 +167,7 @@ void OctTree::AddBox(const AABB& box) } } +//remove the content (boxes) in the tree, but dont rememove the tree-structure void OctTree::ClearBoxes() { if (hasChildren()) { diff --git a/src/Tests/OctTreeTest.cpp b/src/Tests/OctTreeTest.cpp index 5392e63c..aad95381 100644 --- a/src/Tests/OctTreeTest.cpp +++ b/src/Tests/OctTreeTest.cpp @@ -2,13 +2,55 @@ using boost::unit_test_framework::test_suite; using boost::unit_test_framework::test_case; #include //srand +//HACK! Needed for white box testing +//else we would have to "open up" the octTree class more with get/sets, public methods, etc. which is not good encapsulation-wise +//friend class and refactoringIntoNewClass is some extra work and needs to be updated when the original class is updated, and can contain bugs that +//isnt in the original class +//Reflection-inspection seems to be only available for C# +//http://stackoverflow.com/questions/6778496/how-to-do-unit-testing-on-private-members-and-methods-of-c-classes +//http://stackoverflow.com/questions/3676664/unit-testing-of-private-methods +#define private public + #include BOOST_AUTO_TEST_SUITE(octTreeTests) BOOST_AUTO_TEST_CASE(octTreeTest) { + //white box testing + //http://softwaretestingfundamentals.com/differences-between-black-box-testing-and-white-box-testing/ + //http://technologyconversations.com/2013/12/11/black-box-vs-white-box-testing/ + //simple AABB constructor check + auto minCorner = glm::vec3(0.0f, 0.0f, 0.0f); + auto maxCorner = glm::vec3(1.0f, 1.0f, 1.0f); + auto someAABB = AABB(minCorner,maxCorner); + BOOST_CHECK(someAABB.MinCorner() == minCorner); + BOOST_CHECK(someAABB.MaxCorner() == maxCorner); + BOOST_CHECK(someAABB.Center() == 0.5f * (minCorner + maxCorner)); + + //simple OctTree constructor check + auto someOctTree = OctTree(someAABB, 5); + BOOST_CHECK(someOctTree.m_Children[0] != nullptr); + //TODO: a check so it split the tree properly + + + + + //advanced AddBox check + //add a boxcontainer - which crosses the mid-split + auto someAABB2 = AABB(glm::vec3(0.45f, 0.45f, 0.45f), glm::vec3(0.55f, 0.55f, 0.55f)); + someOctTree.AddBox(someAABB2); + //clear the boxcontainer + //need to check so it added the box properly + + + someOctTree.ClearBoxes(); + //add a boxcontainer + someOctTree.AddBox(someAABB2); + + + //simple destructor check in the end, just look for memleaks, then it didnt clear the AABB structure } BOOST_AUTO_TEST_CASE(octTreeTest2) @@ -17,4 +59,3 @@ BOOST_AUTO_TEST_CASE(octTreeTest2) } BOOST_AUTO_TEST_SUITE_END() - From 75402b0f938eb166c5080c37cc7bb2df8750ec1b Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 9 Dec 2015 10:08:08 +0100 Subject: [PATCH 02/10] Working on OctTree tests --- src/Engine/Core/OctTree.cpp | 49 +++--- src/Tests/OctTreeTest.cpp | 6 +- src/Tests/OctTreeTestGameClass.cpp | 78 +++++++++ src/Tests/OctTreeTestGameClass.h | 35 ++++ src/Tests/OctTreeTestGameMain.cpp | 104 ++++++++++++ src/Tests/OctTreeTestHardCodedTestWorld.h | 195 ++++++++++++++++++++++ 6 files changed, 445 insertions(+), 22 deletions(-) create mode 100644 src/Tests/OctTreeTestGameClass.cpp create mode 100644 src/Tests/OctTreeTestGameClass.h create mode 100644 src/Tests/OctTreeTestGameMain.cpp create mode 100644 src/Tests/OctTreeTestHardCodedTestWorld.h diff --git a/src/Engine/Core/OctTree.cpp b/src/Engine/Core/OctTree.cpp index af6cc3a8..4e5cdfaa 100644 --- a/src/Engine/Core/OctTree.cpp +++ b/src/Engine/Core/OctTree.cpp @@ -7,17 +7,17 @@ namespace { -//To be able to sort nodes based on distance to ray origin. -struct ChildInfo -{ - int Index; - float Distance; -}; + //To be able to sort nodes based on distance to ray origin. + struct ChildInfo + { + int Index; + float Distance; + }; -bool isFirstLower(const ChildInfo& first, const ChildInfo& second) -{ - return first.Distance < second.Distance; -} + bool isFirstLower(const ChildInfo& first, const ChildInfo& second) + { + return first.Distance < second.Distance; + } } @@ -32,28 +32,31 @@ OctTree::OctTree(const AABB& octTreeBounds, int subDivisions) for (OctTree*& c : m_Children) { c = nullptr; } - } else { + } + else { --subDivisions; + const glm::vec3& parentMin = m_Box.MinCorner(); + const glm::vec3& parentMax = m_Box.MaxCorner(); + const glm::vec3& parentCenter = m_Box.Center(); for (int i = 0; i < 8; ++i) { glm::vec3 minPos, maxPos; - const glm::vec3& parentMin = m_Box.MinCorner(); - const glm::vec3& parentMax = m_Box.MaxCorner(); - const glm::vec3& parentCenter = m_Box.Center(); std::bitset<3> bits(i); //If child is 4,5,6,7. if (bits.test(2)) { minPos.x = parentCenter.x; maxPos.x = parentMax.x; - } else { + } + else { minPos.x = parentMin.x; maxPos.x = parentCenter.x; } - + //If child is 2,3,6,7 if (bits.test(1)) { minPos.y = parentCenter.y; maxPos.y = parentMax.y; - } else { + } + else { minPos.y = parentMin.y; maxPos.y = parentCenter.y; } @@ -61,7 +64,8 @@ OctTree::OctTree(const AABB& octTreeBounds, int subDivisions) if (bits.test(0)) { minPos.z = parentCenter.z; maxPos.z = parentMax.z; - } else { + } + else { minPos.z = parentMin.z; maxPos.z = parentCenter.z; } @@ -107,7 +111,8 @@ bool OctTree::rayCollides(const Ray& ray, Output& data) const return true; } } - } else { + } + else { //Check against boxes in the node. float minDist = INFINITY; bool intersected = false; @@ -162,7 +167,8 @@ void OctTree::AddBox(const AABB& box) default: break; } - } else { + } + else { m_ContainingBoxes.push_back(box); } } @@ -175,7 +181,8 @@ void OctTree::ClearBoxes() for (OctTree*& c : m_Children) { c->ClearBoxes(); } - } else { + } + else { m_ContainingBoxes.clear(); } } diff --git a/src/Tests/OctTreeTest.cpp b/src/Tests/OctTreeTest.cpp index aad95381..fee2932f 100644 --- a/src/Tests/OctTreeTest.cpp +++ b/src/Tests/OctTreeTest.cpp @@ -2,6 +2,7 @@ using boost::unit_test_framework::test_suite; using boost::unit_test_framework::test_case; #include //srand +#include "OctTreeTestGameClass.h" //HACK! Needed for white box testing //else we would have to "open up" the octTree class more with get/sets, public methods, etc. which is not good encapsulation-wise //friend class and refactoringIntoNewClass is some extra work and needs to be updated when the original class is updated, and can contain bugs that @@ -10,7 +11,6 @@ using boost::unit_test_framework::test_case; //http://stackoverflow.com/questions/6778496/how-to-do-unit-testing-on-private-members-and-methods-of-c-classes //http://stackoverflow.com/questions/3676664/unit-testing-of-private-methods #define private public - #include BOOST_AUTO_TEST_SUITE(octTreeTests) @@ -55,6 +55,10 @@ BOOST_AUTO_TEST_CASE(octTreeTest) BOOST_AUTO_TEST_CASE(octTreeTest2) { + Game game(0, nullptr); + while (game.Running()) { + game.Tick(); + } } diff --git a/src/Tests/OctTreeTestGameClass.cpp b/src/Tests/OctTreeTestGameClass.cpp new file mode 100644 index 00000000..4a6236c2 --- /dev/null +++ b/src/Tests/OctTreeTestGameClass.cpp @@ -0,0 +1,78 @@ +#include "OctTreeTestGameClass.h" + +Game::Game(int argc, char* argv[]) +{ + ResourceManager::RegisterType("ConfigFile"); + ResourceManager::RegisterType("Model"); + ResourceManager::RegisterType("Texture"); + + m_Config = ResourceManager::Load("Config.ini"); + LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); + + // Create the core event broker + m_EventBroker = new EventBroker(); + + m_RenderQueueFactory = new RenderQueueFactory(); + + // Create the renderer + m_Renderer = new Renderer(); + m_Renderer->SetFullscreen(m_Config->Get("Video.Fullscreen", false)); + m_Renderer->SetVSYNC(m_Config->Get("Video.VSYNC", false)); + m_Renderer->SetResolution(Rectangle( + 0, + 0, + m_Config->Get("Video.Width", 1280), + m_Config->Get("Video.Height", 720) + )); + m_Renderer->Initialize(); + + // Create input manager + m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); + + // Create the root level GUI frame + m_FrameStack = new GUI::Frame(m_EventBroker); + m_FrameStack->Width = m_Renderer->Resolution().Width; + m_FrameStack->Height = m_Renderer->Resolution().Height; + + // Create a TEST WORLD + m_World = new HardcodedTestWorld(); + + m_LastTime = glfwGetTime(); +} + +Game::~Game() +{ + delete m_FrameStack; + delete m_EventBroker; +} + +void Game::Tick() +{ + double currentTime = glfwGetTime(); + double dt = currentTime - m_LastTime; + m_LastTime = currentTime; + + m_EventBroker->Swap(); + m_InputManager->Update(dt); + m_Renderer->Update(dt); + m_EventBroker->Swap(); + + //movement + //auto transf = m_World->GetComponent(m_World->OctTreeEntityIdSaved, "Transform"); + //((glm::vec3&)transf["Position"]).x += 0.001f; + + m_RenderQueueFactory->Update(m_World); + + //wireframe + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); + + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + + m_EventBroker->Swap(); + m_EventBroker->Clear(); + + glfwPollEvents(); +} diff --git a/src/Tests/OctTreeTestGameClass.h b/src/Tests/OctTreeTestGameClass.h new file mode 100644 index 00000000..9f4ae8c7 --- /dev/null +++ b/src/Tests/OctTreeTestGameClass.h @@ -0,0 +1,35 @@ +#ifndef Game_h__ +#define Game_h__ + +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" +#include "Core/EventBroker.h" +#include "Rendering/Renderer.h" +#include "Core/InputManager.h" +#include "GUI/Frame.h" +#include "Core/World.h" +#include "Rendering/RenderQueueFactory.h" + +#include "OctTreeTestHardCodedTestWorld.h" + +class Game +{ +public: + Game(int argc, char* argv[]); + ~Game(); + + bool Running() const { return !glfwWindowShouldClose(m_Renderer->Window()); } + void Tick(); + +private: + double m_LastTime; + ConfigFile* m_Config = nullptr; + EventBroker* m_EventBroker; + IRenderer* m_Renderer; + InputManager* m_InputManager; + GUI::Frame* m_FrameStack; + HardcodedTestWorld* m_World; + RenderQueueFactory* m_RenderQueueFactory; +}; + +#endif diff --git a/src/Tests/OctTreeTestGameMain.cpp b/src/Tests/OctTreeTestGameMain.cpp new file mode 100644 index 00000000..ab13e930 --- /dev/null +++ b/src/Tests/OctTreeTestGameMain.cpp @@ -0,0 +1,104 @@ +//#define BOOST_TEST_MODULE collTest +#include +#include +using boost::unit_test_framework::test_suite; +using boost::unit_test_framework::test_case; +#include +#include "Engine/Core/AABB.h" +#include "Engine/Core/Ray.h" +#include //srand +#include "Engine/Core/OctTree.h" + +//vs memleaks +//#define _CRTDBG_MAP_ALLOC +//#include +//#include +//#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) +//#define new DEBUG_CLIENTBLOCK + +BOOST_AUTO_TEST_SUITE(collisionTests) + +BOOST_AUTO_TEST_CASE(collisionTest) +{ + //memleak + int* globalLeak = new int[5]; + + //fixed seed + srand(2); + Ray ray; + AABB someAABB; + glm::vec3 minPos; + glm::vec3 maxPos; + bool z; + int test = 0; + for (size_t i = 0; i < 10; i++) + { + ray.Origin.x = rand() % 100; + ray.Origin.y = rand() % 100; + ray.Origin.z = rand() % 100; + ray.Direction.x = rand() % 100; + ray.Direction.y = rand() % 100; + ray.Direction.z = rand() % 100; + minPos.x = rand() % 100; + minPos.y = rand() % 100; + minPos.z = rand() % 100; + maxPos.x = rand() % 100; + maxPos.y = rand() % 100; + maxPos.z = rand() % 100; + + someAABB = AABB(minPos, maxPos); + z = Collision::RayVsAABB(ray, someAABB); + if (z) ++test; + } + BOOST_CHECK(test >= 0); + + //_CrtDumpMemoryLeaks(); +} + +BOOST_AUTO_TEST_CASE(collisionTest2) +{ + //fixed seed + srand(2); + Ray ray; + AABB someAABB; + glm::vec3 minPos; + glm::vec3 maxPos; + bool z; + int test = 0; + for (size_t i = 0; i < 1000000; i++) + { + ray.Origin.x = rand() % 100; + ray.Origin.y = rand() % 100; + ray.Origin.z = rand() % 100; + ray.Direction.x = rand() % 100; + ray.Direction.y = rand() % 100; + ray.Direction.z = rand() % 100; + minPos.x = rand() % 100; + minPos.y = rand() % 100; + minPos.z = rand() % 100; + maxPos.x = rand() % 100; + maxPos.y = rand() % 100; + maxPos.z = rand() % 100; + + someAABB = AABB(minPos, maxPos); + z = Collision::RayAABBIntr(ray, someAABB); + if (z) ++test; + } + BOOST_CHECK(test >= 0); +} + +BOOST_AUTO_TEST_CASE(octTest) +{ + glm::vec3 mini = glm::vec3(-1, -1, -1); + glm::vec3 maxi = glm::vec3(1, 1, 1); + OctTree tree(AABB(mini, maxi), 2); + tree.AddBox(AABB(mini, -0.9f*maxi)); + OctTree::Output data; + glm::vec3 origin = 3.0f * mini; + BOOST_CHECK(tree.RayCollides({origin , glm::normalize(mini - origin) }, data)); + tree.ClearBoxes(); + BOOST_CHECK(!tree.RayCollides({ origin , glm::normalize(mini - origin) }, data)); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h new file mode 100644 index 00000000..f5caf308 --- /dev/null +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -0,0 +1,195 @@ +#include +#include +#include +#include "GLM.h" +#include "Core/World.h" +#include "Core/Util/Any.h" + +//octTree +//#include + +//last! +#define private public +#include + +class HardcodedTestWorld : public World +{ +public: + EntityID OctTreeEntityIdSaved; + + //constructor + HardcodedTestWorld() + : World() + { + registerTestComponents(); + createTestEntities(); + } + +private: + void registerTestComponents() + { + ComponentWrapperFactory f; + + + f = ComponentWrapperFactory("Test"); + f.AddProperty("TestInteger", 1337); + f.AddProperty("TestFloat", 13.37f); + f.AddProperty("TestString", std::string("Carlito")); + RegisterComponent(f); + + f = ComponentWrapperFactory("Debug"); + f.AddProperty("Name", std::string("Unnamed")); + RegisterComponent(f); + + f = ComponentWrapperFactory("Transform"); + f.AddProperty("Position", glm::vec3(0.f, 0.f, 0.f)); + f.AddProperty("Orientation", glm::quat()); + f.AddProperty("Scale", glm::vec3(1.f, 1.f, 1.f)); + RegisterComponent(f); + + f = ComponentWrapperFactory("Model"); + f.AddProperty("Resource", std::string()); + f.AddProperty("Color", glm::vec4(1.f, 1.f, 1.f, 1.f)); + f.AddProperty("Visible", true); + RegisterComponent(f); + } + + void createTestEntities() + { + World& world = *this; + + // Create an entity + EntityID e = world.CreateEntity(); + + // Attach a Debug component + ComponentWrapper debug = world.AttachComponent(e, "Debug"); + // Set the Name field of the Debug component using subscript operator + debug["Name"] = "Carlito"; + + // Attach a Transform component + world.AttachComponent(e, "Transform"); + // Fetch the component based on EntityID and component type + ComponentWrapper transform = world.GetComponent(e, "Transform"); + // Set the fields of the Transform component + transform["Position"] = glm::vec3(0.f, 0.f, 0.f); + transform["Scale"] = glm::vec3(1.f, 1.f, 1.f); + + // Move on the X axis by fetching field as reference + ((glm::vec3&)transform["Position"]).x += 10.f; + // Shrink by a factor of 100 + ((glm::vec3&)transform["Scale"]) /= 100.f; + + // Loop through all Transform components and print them + for (auto& transform : world.GetComponents("Transform")) { + glm::vec3 pos = transform["Position"]; + std::cout << "Position: " << pos.x << " " << pos.y << " " << pos.z << std::endl; + glm::vec3 scale = transform["Scale"]; + std::cout << "Scale: " << scale.x << " " << scale.y << " " << scale.z << std::endl; + + // Fetch the Debug component also present in this entity + ComponentWrapper debug = world.GetComponent(transform.EntityID, "Debug"); + std::cout << "Name: " << (std::string)debug["Name"] << std::endl; + } + + //Create some test widgets + //{ + // EntityID entityScaleWidget = world.CreateEntity(); + // ComponentWrapper transform = world.AttachComponent(entityScaleWidget, "Transform"); + // transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f); + // ComponentWrapper model = world.AttachComponent(entityScaleWidget, "Model"); + // model["Resource"] = "Models/ScaleWidget.obj"; + //} + //{ + // EntityID entityRotationWidget = world.CreateEntity(); + // ComponentWrapper transform = world.AttachComponent(entityRotationWidget, "Transform"); + // transform["Position"] = glm::vec3(1.5f, 0.f, 0.f); + // ComponentWrapper model = world.AttachComponent(entityRotationWidget, "Model"); + // model["Resource"] = "Models/RotationWidget.obj"; + //} + //{ + // EntityID entityDummyScene = world.CreateEntity(); + // ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); + // transform["Position"] = glm::vec3(0, 0.f, 0.f); + // ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); + // model["Resource"] = "Models/DummyScene.obj"; + //} + + //add octTree + { + //ComponentWrapper debug = world.AttachComponent(e, "Debug"); + //// Set the Name field of the Debug component using subscript operator + //debug["Name"] = "Blah"; + auto minCorner = glm::vec3(0.0f, 0.0f, 0.0f); + auto maxCorner = glm::vec3(1.0f, 1.0f, 1.0f); + auto someAABB = AABB(minCorner, maxCorner); + + auto someOctTree = OctTree(someAABB, 2); + + //auto min1 = someOctTree.m_Children[i]->m_Box.MinCorner(); + //auto max1 = someOctTree.m_Children[i]->m_Box.MaxCorner(); + + float boxDrawFactor = 1.05f; + auto halfSizeFactor = 0.0f; + halfSizeFactor = someAABB.HalfSize().x; + + //the first box first + EntityID entityDummyScene = world.CreateEntity(); + + ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); + transform["Position"] = someAABB.Center()*1.0f; + transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSizeFactor*boxDrawFactor; + + ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); + model["Resource"] = "Models/Core/UnitBox.obj"; + model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + + //just draw the first 8 children - looks nicer in code if i split it this way + for (size_t i = 0; i < 8; i++) + { + auto cen1 = someOctTree.m_Children[i]->m_Box.Center(); + halfSizeFactor = someOctTree.m_Children[i]->m_Box.HalfSize().x; + + EntityID entityDummyScene = world.CreateEntity(); + + ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); + transform["Position"] = cen1*1.0f; + transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*0.97f*halfSizeFactor*boxDrawFactor; + + ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); + model["Resource"] = "Models/Core/UnitBox.obj"; + model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + + //OutputDebugStringA((std::to_string(cen1.x) + std::to_string(cen1.y) + std::to_string(cen1.z)).c_str()); + //OctTreeEntityIdSaved = entityDummyScene; + } + + //then draw the childrens children + //for (size_t j = 0; j < 8; j++) + //{ + // auto someChild = someOctTree.m_Children[j]; + + // for (size_t i = 0; i < 8; i++) + // { + // auto cen1 = someChild->m_Children[i]->m_Box.Center(); + // auto boxScale = someChild->m_Children[i]->m_Box.HalfSize(); + + // EntityID entityDummyScene = world.CreateEntity(); + + // ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); + // transform["Position"] = cen1*1.0f; + // transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*0.97f*boxScale*boxDrawFactor; + + // ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); + // model["Resource"] = "Models/Core/UnitBox.obj"; + // model["Color"] = glm::vec4(0.0f, 1.0f, 0.0f, 1.0f); + // //OctTreeEntityIdSaved = entityDummyScene; + // } + + //} + + + } + + + } +}; \ No newline at end of file From 1d0810db1094e3c67aaefdf8c9a81a7ab6fc167b Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 9 Dec 2015 10:24:06 +0100 Subject: [PATCH 03/10] OctTree is now drawn perfectly --- src/Tests/OctTreeTestHardCodedTestWorld.h | 44 +++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index f5caf308..4ce0c587 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -128,7 +128,7 @@ private: //auto min1 = someOctTree.m_Children[i]->m_Box.MinCorner(); //auto max1 = someOctTree.m_Children[i]->m_Box.MaxCorner(); - float boxDrawFactor = 1.05f; + float boxDrawFactor = 1.00f; auto halfSizeFactor = 0.0f; halfSizeFactor = someAABB.HalfSize().x; @@ -137,10 +137,10 @@ private: ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); transform["Position"] = someAABB.Center()*1.0f; - transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSizeFactor*boxDrawFactor; + transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSizeFactor*boxDrawFactor*2.0f; ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; + model["Resource"] = "Models/Core/UnitBox2.obj"; model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); //just draw the first 8 children - looks nicer in code if i split it this way @@ -153,10 +153,10 @@ private: ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); transform["Position"] = cen1*1.0f; - transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*0.97f*halfSizeFactor*boxDrawFactor; + transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSizeFactor*boxDrawFactor*2.0f; ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; + model["Resource"] = "Models/Core/UnitBox2.obj"; model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); //OutputDebugStringA((std::to_string(cen1.x) + std::to_string(cen1.y) + std::to_string(cen1.z)).c_str()); @@ -164,28 +164,28 @@ private: } //then draw the childrens children - //for (size_t j = 0; j < 8; j++) - //{ - // auto someChild = someOctTree.m_Children[j]; + for (size_t j = 0; j < 8; j++) + { + auto someChild = someOctTree.m_Children[j]; - // for (size_t i = 0; i < 8; i++) - // { - // auto cen1 = someChild->m_Children[i]->m_Box.Center(); - // auto boxScale = someChild->m_Children[i]->m_Box.HalfSize(); + for (size_t i = 0; i < 8; i++) + { + auto cen1 = someChild->m_Children[i]->m_Box.Center(); + halfSizeFactor = someChild->m_Children[i]->m_Box.HalfSize().x; - // EntityID entityDummyScene = world.CreateEntity(); + EntityID entityDummyScene = world.CreateEntity(); - // ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); - // transform["Position"] = cen1*1.0f; - // transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*0.97f*boxScale*boxDrawFactor; + ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); + transform["Position"] = cen1*1.0f; + transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSizeFactor*boxDrawFactor*2.0f; - // ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - // model["Resource"] = "Models/Core/UnitBox.obj"; - // model["Color"] = glm::vec4(0.0f, 1.0f, 0.0f, 1.0f); - // //OctTreeEntityIdSaved = entityDummyScene; - // } + ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); + model["Resource"] = "Models/Core/UnitBox2.obj"; + model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + //OctTreeEntityIdSaved = entityDummyScene; + } - //} + } } From ed5cd392ab46c8cb1b681cbdb969ec258bfbd8a7 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 9 Dec 2015 13:29:15 +0100 Subject: [PATCH 04/10] Further work in testing OctTree --- src/Tests/OctTreeTestGameClass.cpp | 11 ++ src/Tests/OctTreeTestGameClass.h | 3 + src/Tests/OctTreeTestGameMain.cpp | 6 +- src/Tests/OctTreeTestHardCodedTestWorld.h | 163 ++++++---------------- 4 files changed, 60 insertions(+), 123 deletions(-) diff --git a/src/Tests/OctTreeTestGameClass.cpp b/src/Tests/OctTreeTestGameClass.cpp index 4a6236c2..918782ec 100644 --- a/src/Tests/OctTreeTestGameClass.cpp +++ b/src/Tests/OctTreeTestGameClass.cpp @@ -58,9 +58,20 @@ void Game::Tick() m_EventBroker->Swap(); //movement + minPos.x += 0.001f; + //frameCounter++; + //if (frameCounter > 50) { + // m_World->createTestEntities(AABB(minPos, glm::vec3(0.1f, 0.4f, 0.6f))); + // frameCounter = 0; + //} //auto transf = m_World->GetComponent(m_World->OctTreeEntityIdSaved, "Transform"); //((glm::vec3&)transf["Position"]).x += 0.001f; + //for (auto oneModel : m_World->allModels) + //{ + + //} + m_RenderQueueFactory->Update(m_World); //wireframe diff --git a/src/Tests/OctTreeTestGameClass.h b/src/Tests/OctTreeTestGameClass.h index 9f4ae8c7..887ad59b 100644 --- a/src/Tests/OctTreeTestGameClass.h +++ b/src/Tests/OctTreeTestGameClass.h @@ -30,6 +30,9 @@ private: GUI::Frame* m_FrameStack; HardcodedTestWorld* m_World; RenderQueueFactory* m_RenderQueueFactory; + + int frameCounter = 0; + glm::vec3 minPos = glm::vec3(-0.2f, 0.2f, 0.3f); }; #endif diff --git a/src/Tests/OctTreeTestGameMain.cpp b/src/Tests/OctTreeTestGameMain.cpp index ab13e930..9266754e 100644 --- a/src/Tests/OctTreeTestGameMain.cpp +++ b/src/Tests/OctTreeTestGameMain.cpp @@ -16,9 +16,9 @@ using boost::unit_test_framework::test_case; //#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) //#define new DEBUG_CLIENTBLOCK -BOOST_AUTO_TEST_SUITE(collisionTests) +BOOST_AUTO_TEST_SUITE(cTest) -BOOST_AUTO_TEST_CASE(collisionTest) +BOOST_AUTO_TEST_CASE(cTest) { //memleak int* globalLeak = new int[5]; @@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(collisionTest) //_CrtDumpMemoryLeaks(); } -BOOST_AUTO_TEST_CASE(collisionTest2) +BOOST_AUTO_TEST_CASE(cTest2) { //fixed seed srand(2); diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index 4ce0c587..1e785994 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -8,6 +8,7 @@ //octTree //#include +#include //last! #define private public #include @@ -15,14 +16,20 @@ class HardcodedTestWorld : public World { public: + struct LinkOctTreeAndModel { + EntityID entId; + }; EntityID OctTreeEntityIdSaved; + //std::vector allModels; + //ComponentWrapper moveModel; + //OctTree* someOctTreePointer; //constructor HardcodedTestWorld() : World() { registerTestComponents(); - createTestEntities(); + //createTestEntities(); } private: @@ -54,142 +61,58 @@ private: RegisterComponent(f); } - void createTestEntities() + void createTestEntities(AABB anotherBox) { World& world = *this; - - // Create an entity - EntityID e = world.CreateEntity(); - - // Attach a Debug component - ComponentWrapper debug = world.AttachComponent(e, "Debug"); - // Set the Name field of the Debug component using subscript operator - debug["Name"] = "Carlito"; - - // Attach a Transform component - world.AttachComponent(e, "Transform"); - // Fetch the component based on EntityID and component type - ComponentWrapper transform = world.GetComponent(e, "Transform"); - // Set the fields of the Transform component - transform["Position"] = glm::vec3(0.f, 0.f, 0.f); - transform["Scale"] = glm::vec3(1.f, 1.f, 1.f); - - // Move on the X axis by fetching field as reference - ((glm::vec3&)transform["Position"]).x += 10.f; - // Shrink by a factor of 100 - ((glm::vec3&)transform["Scale"]) /= 100.f; - - // Loop through all Transform components and print them - for (auto& transform : world.GetComponents("Transform")) { - glm::vec3 pos = transform["Position"]; - std::cout << "Position: " << pos.x << " " << pos.y << " " << pos.z << std::endl; - glm::vec3 scale = transform["Scale"]; - std::cout << "Scale: " << scale.x << " " << scale.y << " " << scale.z << std::endl; - - // Fetch the Debug component also present in this entity - ComponentWrapper debug = world.GetComponent(transform.EntityID, "Debug"); - std::cout << "Name: " << (std::string)debug["Name"] << std::endl; - } - - //Create some test widgets - //{ - // EntityID entityScaleWidget = world.CreateEntity(); - // ComponentWrapper transform = world.AttachComponent(entityScaleWidget, "Transform"); - // transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f); - // ComponentWrapper model = world.AttachComponent(entityScaleWidget, "Model"); - // model["Resource"] = "Models/ScaleWidget.obj"; - //} - //{ - // EntityID entityRotationWidget = world.CreateEntity(); - // ComponentWrapper transform = world.AttachComponent(entityRotationWidget, "Transform"); - // transform["Position"] = glm::vec3(1.5f, 0.f, 0.f); - // ComponentWrapper model = world.AttachComponent(entityRotationWidget, "Model"); - // model["Resource"] = "Models/RotationWidget.obj"; - //} - //{ - // EntityID entityDummyScene = world.CreateEntity(); - // ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); - // transform["Position"] = glm::vec3(0, 0.f, 0.f); - // ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - // model["Resource"] = "Models/DummyScene.obj"; - //} - + //add octTree { - //ComponentWrapper debug = world.AttachComponent(e, "Debug"); - //// Set the Name field of the Debug component using subscript operator - //debug["Name"] = "Blah"; - auto minCorner = glm::vec3(0.0f, 0.0f, 0.0f); - auto maxCorner = glm::vec3(1.0f, 1.0f, 1.0f); - auto someAABB = AABB(minCorner, maxCorner); + auto someAABB = AABB(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)); + OctTree someOctTree = OctTree(someAABB, 2); + //add a box + //auto anotherBox = AABB(glm::vec3(-0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.4f, 0.6f)); + //note: have to delete the box in the tree first, since were trying to move the box + someOctTree.ClearBoxes(); + someOctTree.AddBox(anotherBox); - auto someOctTree = OctTree(someAABB, 2); + //the main box first + AddBoxModel(someAABB.Center(), someAABB.HalfSize().x, someOctTree.m_ContainingBoxes.size()); - //auto min1 = someOctTree.m_Children[i]->m_Box.MinCorner(); - //auto max1 = someOctTree.m_Children[i]->m_Box.MaxCorner(); + //draw anotherbox + AddBoxModel(anotherBox.Center(), anotherBox.HalfSize().x, 0); - float boxDrawFactor = 1.00f; - auto halfSizeFactor = 0.0f; - halfSizeFactor = someAABB.HalfSize().x; - - //the first box first - EntityID entityDummyScene = world.CreateEntity(); - - ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); - transform["Position"] = someAABB.Center()*1.0f; - transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSizeFactor*boxDrawFactor*2.0f; - - ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox2.obj"; - model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); - - //just draw the first 8 children - looks nicer in code if i split it this way - for (size_t i = 0; i < 8; i++) - { - auto cen1 = someOctTree.m_Children[i]->m_Box.Center(); - halfSizeFactor = someOctTree.m_Children[i]->m_Box.HalfSize().x; - - EntityID entityDummyScene = world.CreateEntity(); - - ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); - transform["Position"] = cen1*1.0f; - transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSizeFactor*boxDrawFactor*2.0f; - - ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox2.obj"; - model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); - - //OutputDebugStringA((std::to_string(cen1.x) + std::to_string(cen1.y) + std::to_string(cen1.z)).c_str()); - //OctTreeEntityIdSaved = entityDummyScene; - } - - //then draw the childrens children + //draw the octTree for (size_t j = 0; j < 8; j++) { + AddBoxModel(someOctTree.m_Children[j]->m_Box.Center(), + someOctTree.m_Children[j]->m_Box.HalfSize().x, someOctTree.m_Children[j]->m_ContainingBoxes.size()); + auto someChild = someOctTree.m_Children[j]; for (size_t i = 0; i < 8; i++) { - auto cen1 = someChild->m_Children[i]->m_Box.Center(); - halfSizeFactor = someChild->m_Children[i]->m_Box.HalfSize().x; - - EntityID entityDummyScene = world.CreateEntity(); - - ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); - transform["Position"] = cen1*1.0f; - transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSizeFactor*boxDrawFactor*2.0f; - - ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox2.obj"; - model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); - //OctTreeEntityIdSaved = entityDummyScene; + AddBoxModel(someChild->m_Children[i]->m_Box.Center(), + someChild->m_Children[i]->m_Box.HalfSize().x, someChild->m_Children[i]->m_ContainingBoxes.size()); } - } - - } + }//end CreateEnt + void AddBoxModel(const glm::vec3 ¢er, const float &halfSize, const int &contBoxes) { + World& world = *this; + EntityID entityDummyScene = world.CreateEntity(); + + ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); + transform["Position"] = center; + transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSize*2.0f; + ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); + model["Resource"] = "Models/Core/UnitBox2.obj"; + model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + if (contBoxes != 0) + model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); + + //extra + //allModels.push_back(model); } }; \ No newline at end of file From 8949db5456161fbc7a8814757b06c6a8a9c9e611 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 9 Dec 2015 13:56:59 +0100 Subject: [PATCH 05/10] Little more work with OctTreeTest --- src/Tests/OctTreeTest.cpp | 9 ++- src/Tests/OctTreeTestGameMain.cpp | 83 ----------------------- src/Tests/OctTreeTestHardCodedTestWorld.h | 14 ++-- 3 files changed, 11 insertions(+), 95 deletions(-) diff --git a/src/Tests/OctTreeTest.cpp b/src/Tests/OctTreeTest.cpp index fee2932f..962db3d4 100644 --- a/src/Tests/OctTreeTest.cpp +++ b/src/Tests/OctTreeTest.cpp @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(octTreeTest) BOOST_CHECK(someAABB.Center() == 0.5f * (minCorner + maxCorner)); //simple OctTree constructor check - auto someOctTree = OctTree(someAABB, 5); + OctTree someOctTree(someAABB, 5); BOOST_CHECK(someOctTree.m_Children[0] != nullptr); //TODO: a check so it split the tree properly @@ -40,14 +40,13 @@ BOOST_AUTO_TEST_CASE(octTreeTest) //advanced AddBox check //add a boxcontainer - which crosses the mid-split auto someAABB2 = AABB(glm::vec3(0.45f, 0.45f, 0.45f), glm::vec3(0.55f, 0.55f, 0.55f)); - someOctTree.AddBox(someAABB2); + someOctTree.AddDynamicObject(someAABB2); //clear the boxcontainer //need to check so it added the box properly - - someOctTree.ClearBoxes(); + someOctTree.ClearDynamicObjects(); //add a boxcontainer - someOctTree.AddBox(someAABB2); + someOctTree.AddDynamicObject(someAABB2); //simple destructor check in the end, just look for memleaks, then it didnt clear the AABB structure diff --git a/src/Tests/OctTreeTestGameMain.cpp b/src/Tests/OctTreeTestGameMain.cpp index 9266754e..5dd23cf2 100644 --- a/src/Tests/OctTreeTestGameMain.cpp +++ b/src/Tests/OctTreeTestGameMain.cpp @@ -17,88 +17,5 @@ using boost::unit_test_framework::test_case; //#define new DEBUG_CLIENTBLOCK BOOST_AUTO_TEST_SUITE(cTest) - -BOOST_AUTO_TEST_CASE(cTest) -{ - //memleak - int* globalLeak = new int[5]; - - //fixed seed - srand(2); - Ray ray; - AABB someAABB; - glm::vec3 minPos; - glm::vec3 maxPos; - bool z; - int test = 0; - for (size_t i = 0; i < 10; i++) - { - ray.Origin.x = rand() % 100; - ray.Origin.y = rand() % 100; - ray.Origin.z = rand() % 100; - ray.Direction.x = rand() % 100; - ray.Direction.y = rand() % 100; - ray.Direction.z = rand() % 100; - minPos.x = rand() % 100; - minPos.y = rand() % 100; - minPos.z = rand() % 100; - maxPos.x = rand() % 100; - maxPos.y = rand() % 100; - maxPos.z = rand() % 100; - - someAABB = AABB(minPos, maxPos); - z = Collision::RayVsAABB(ray, someAABB); - if (z) ++test; - } - BOOST_CHECK(test >= 0); - - //_CrtDumpMemoryLeaks(); -} - -BOOST_AUTO_TEST_CASE(cTest2) -{ - //fixed seed - srand(2); - Ray ray; - AABB someAABB; - glm::vec3 minPos; - glm::vec3 maxPos; - bool z; - int test = 0; - for (size_t i = 0; i < 1000000; i++) - { - ray.Origin.x = rand() % 100; - ray.Origin.y = rand() % 100; - ray.Origin.z = rand() % 100; - ray.Direction.x = rand() % 100; - ray.Direction.y = rand() % 100; - ray.Direction.z = rand() % 100; - minPos.x = rand() % 100; - minPos.y = rand() % 100; - minPos.z = rand() % 100; - maxPos.x = rand() % 100; - maxPos.y = rand() % 100; - maxPos.z = rand() % 100; - - someAABB = AABB(minPos, maxPos); - z = Collision::RayAABBIntr(ray, someAABB); - if (z) ++test; - } - BOOST_CHECK(test >= 0); -} - -BOOST_AUTO_TEST_CASE(octTest) -{ - glm::vec3 mini = glm::vec3(-1, -1, -1); - glm::vec3 maxi = glm::vec3(1, 1, 1); - OctTree tree(AABB(mini, maxi), 2); - tree.AddBox(AABB(mini, -0.9f*maxi)); - OctTree::Output data; - glm::vec3 origin = 3.0f * mini; - BOOST_CHECK(tree.RayCollides({origin , glm::normalize(mini - origin) }, data)); - tree.ClearBoxes(); - BOOST_CHECK(!tree.RayCollides({ origin , glm::normalize(mini - origin) }, data)); -} - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index 1e785994..dbdbcb45 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -29,7 +29,7 @@ public: : World() { registerTestComponents(); - //createTestEntities(); + createTestEntities(AABB(glm::vec3(-0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.4f, 0.6f))); } private: @@ -68,15 +68,15 @@ private: //add octTree { auto someAABB = AABB(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)); - OctTree someOctTree = OctTree(someAABB, 2); + OctTree someOctTree(someAABB, 2); //add a box //auto anotherBox = AABB(glm::vec3(-0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.4f, 0.6f)); //note: have to delete the box in the tree first, since were trying to move the box - someOctTree.ClearBoxes(); - someOctTree.AddBox(anotherBox); + someOctTree.ClearDynamicObjects(); + someOctTree.AddDynamicObject(anotherBox); //the main box first - AddBoxModel(someAABB.Center(), someAABB.HalfSize().x, someOctTree.m_ContainingBoxes.size()); + AddBoxModel(someAABB.Center(), someAABB.HalfSize().x, someOctTree.m_DynamicObjects.size()); //draw anotherbox AddBoxModel(anotherBox.Center(), anotherBox.HalfSize().x, 0); @@ -85,14 +85,14 @@ private: for (size_t j = 0; j < 8; j++) { AddBoxModel(someOctTree.m_Children[j]->m_Box.Center(), - someOctTree.m_Children[j]->m_Box.HalfSize().x, someOctTree.m_Children[j]->m_ContainingBoxes.size()); + someOctTree.m_Children[j]->m_Box.HalfSize().x, someOctTree.m_Children[j]->m_DynamicObjects.size()); auto someChild = someOctTree.m_Children[j]; for (size_t i = 0; i < 8; i++) { AddBoxModel(someChild->m_Children[i]->m_Box.Center(), - someChild->m_Children[i]->m_Box.HalfSize().x, someChild->m_Children[i]->m_ContainingBoxes.size()); + someChild->m_Children[i]->m_Box.HalfSize().x, someChild->m_Children[i]->m_DynamicObjects.size()); } } } From bc8a922b77f39259e4312c242a0325ceaa7a1787 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 9 Dec 2015 17:57:32 +0100 Subject: [PATCH 06/10] Merging octTreeTests a bit --- src/Tests/OctTreeTest.cpp | 18 +--- src/Tests/OctTreeTestGameClass.cpp | 101 ++++++++++++++++++---- src/Tests/OctTreeTestGameClass.h | 15 +++- src/Tests/OctTreeTestHardCodedTestWorld.h | 68 +++++++++------ 4 files changed, 142 insertions(+), 60 deletions(-) diff --git a/src/Tests/OctTreeTest.cpp b/src/Tests/OctTreeTest.cpp index 962db3d4..b0b5c25d 100644 --- a/src/Tests/OctTreeTest.cpp +++ b/src/Tests/OctTreeTest.cpp @@ -32,33 +32,17 @@ BOOST_AUTO_TEST_CASE(octTreeTest) //simple OctTree constructor check OctTree someOctTree(someAABB, 5); BOOST_CHECK(someOctTree.m_Children[0] != nullptr); - //TODO: a check so it split the tree properly - - - - - //advanced AddBox check - //add a boxcontainer - which crosses the mid-split - auto someAABB2 = AABB(glm::vec3(0.45f, 0.45f, 0.45f), glm::vec3(0.55f, 0.55f, 0.55f)); - someOctTree.AddDynamicObject(someAABB2); - //clear the boxcontainer - //need to check so it added the box properly - - someOctTree.ClearDynamicObjects(); - //add a boxcontainer - someOctTree.AddDynamicObject(someAABB2); - //simple destructor check in the end, just look for memleaks, then it didnt clear the AABB structure } BOOST_AUTO_TEST_CASE(octTreeTest2) { + //octtree ritningen osv Game game(0, nullptr); while (game.Running()) { game.Tick(); } - } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/Tests/OctTreeTestGameClass.cpp b/src/Tests/OctTreeTestGameClass.cpp index 918782ec..e79f645b 100644 --- a/src/Tests/OctTreeTestGameClass.cpp +++ b/src/Tests/OctTreeTestGameClass.cpp @@ -1,6 +1,6 @@ #include "OctTreeTestGameClass.h" -Game::Game(int argc, char* argv[]) +Game::Game(int argc, char* argv[]) : someOctTree(AABB(-0.5f*worldSize, 0.5f*worldSize), 2) { ResourceManager::RegisterType("ConfigFile"); ResourceManager::RegisterType("Model"); @@ -57,31 +57,100 @@ void Game::Tick() m_Renderer->Update(dt); m_EventBroker->Swap(); - //movement - minPos.x += 0.001f; - //frameCounter++; - //if (frameCounter > 50) { - // m_World->createTestEntities(AABB(minPos, glm::vec3(0.1f, 0.4f, 0.6f))); - // frameCounter = 0; - //} - //auto transf = m_World->GetComponent(m_World->OctTreeEntityIdSaved, "Transform"); - //((glm::vec3&)transf["Position"]).x += 0.001f; +#define TEST2 +#ifdef TEST1 + //add/move the trigger box + auto pos = m_Renderer->Camera()->Forward() + m_Renderer->Camera()->Position(); + AABB boxi; + boxi.CreateFromCenter(pos, maxPos - minPos); + frameCounter++; + if (frameCounter > 50) { + m_World->someOctTree.ClearDynamicObjects(); + m_World->someOctTree.AddDynamicObject(boxi); + frameCounter = 0; + } + ComponentWrapper transform = m_World->GetComponent(m_World->anotherBoxTransformId, "Transform"); + transform["Position"] = boxi.Center(); - //for (auto oneModel : m_World->allModels) - //{ + //check all children again in the tree if they have a box in them or not, and colormark them if they do + //contentboxarna får man ut - inte childboxarna! + std::vector boxIndex; + boxIndex = m_World->someOctTree.childIndicesContainingBox(boxi); - //} + for (auto& oneLinkedObject : m_World->linkOM) + { + ComponentWrapper model = m_World->GetComponent(oneLinkedObject.entId, "Model"); + model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); + if (oneLinkedObject.child->m_DynamicObjects.size() != 0) { + model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + } + //next check if the childIndicesContainingBox method returns the correct boxes + //REQUIRED: childIndicesContainingBox must be public to test this! + for each (auto someBoxIndex in boxIndex) + { + glm::vec3 pos = m_World->someOctTree.m_Children[someBoxIndex]->m_Box.Center(); + if (abs(pos.x - oneLinkedObject.posxyz.x) < 0.005f && + abs(pos.y - oneLinkedObject.posxyz.y) < 0.005f && + abs(pos.z - oneLinkedObject.posxyz.z) < 0.005f) { + model["Color"] = glm::vec4(0.0f, 1.0f, 0.0f, 1.0f); + + } + } + } m_RenderQueueFactory->Update(m_World); //wireframe glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif +#ifdef TEST2 + + //only add 1 for now... + //grey box + AABB aabb; + aabb.CreateFromCenter(glm::vec3(0.f, 2.f, 0.f), glm::vec3(1.f, 1.f, 1.f)); + + const glm::vec4 redCol = glm::vec4(1, 0.2f, 0, 1); + const glm::vec4 greenCol = glm::vec4(0.1f, 1.0f, 0.25f, 1); + const glm::vec3 boxSize = 0.1f*glm::vec3(1.0f, 1.0f, 1.0f); + + if (!m_UpdatedOnce) { + someOctTree.AddStaticObject(aabb); + m_BoxID = m_World->CreateEntity(); + ComponentWrapper transform = m_World->AttachComponent(m_BoxID, "Transform"); + transform["Scale"] = boxSize; + ComponentWrapper model = m_World->AttachComponent(m_BoxID, "Model"); + model["Resource"] = "Models/Core/UnitBox.obj"; + m_UpdatedOnce = true; + m_World->createTestEntitiesTest2(); + } + + //red box + AABB redBox; + auto boxPos = m_Renderer->Camera()->Position() + 1.2f*m_Renderer->Camera()->Forward(); + redBox.CreateFromCenter(boxPos, boxSize); + ComponentWrapper transform = m_World->GetComponent(m_BoxID, "Transform"); + transform["Position"] = boxPos; + ComponentWrapper model = m_World->GetComponent(m_BoxID, "Model"); + if (someOctTree.BoxCollides(redBox, AABB())) { + //if (Collision::AABBVsAABB(redBox, aabb)) { + m_Renderer->Camera()->SetPosition(m_PrevPos); + m_Renderer->Camera()->SetOrientation(m_PrevOri); + model["Color"] = greenCol; + } + else { + model["Color"] = redCol; + } + + m_PrevPos = m_Renderer->Camera()->Position(); + m_PrevOri = m_Renderer->Camera()->Orientation(); + someOctTree.ClearObjects(); + + m_RenderQueueFactory->Update(m_World); +#endif m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - m_EventBroker->Swap(); m_EventBroker->Clear(); diff --git a/src/Tests/OctTreeTestGameClass.h b/src/Tests/OctTreeTestGameClass.h index 887ad59b..8ca34510 100644 --- a/src/Tests/OctTreeTestGameClass.h +++ b/src/Tests/OctTreeTestGameClass.h @@ -11,6 +11,7 @@ #include "Rendering/RenderQueueFactory.h" #include "OctTreeTestHardCodedTestWorld.h" +#include "Core\Collision.h" class Game { @@ -31,8 +32,20 @@ private: HardcodedTestWorld* m_World; RenderQueueFactory* m_RenderQueueFactory; + //Test1 int frameCounter = 0; - glm::vec3 minPos = glm::vec3(-0.2f, 0.2f, 0.3f); + glm::vec3 minPos = glm::vec3(0.1f, 0.1f, 0.1f); + glm::vec3 maxPos = glm::vec3(0.2f, 0.2f, 0.2f); + + //Test2 + bool m_UpdatedOnce = false; + unsigned int m_BoxID; + glm::vec3 m_PrevPos; + glm::quat m_PrevOri; + + glm::vec3 worldSize = glm::vec3(50, 50, 50); + OctTree someOctTree; + }; #endif diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index dbdbcb45..ff7b56cc 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -5,9 +5,6 @@ #include "Core/World.h" #include "Core/Util/Any.h" -//octTree -//#include - #include //last! #define private public @@ -18,18 +15,26 @@ class HardcodedTestWorld : public World public: struct LinkOctTreeAndModel { EntityID entId; + OctTree* child; + glm::vec3 posxyz; + LinkOctTreeAndModel(EntityID eId, OctTree* ch, glm::vec3 pos) + { + entId = eId; + child = ch; + posxyz = pos; + } }; - EntityID OctTreeEntityIdSaved; - //std::vector allModels; - //ComponentWrapper moveModel; - //OctTree* someOctTreePointer; + EntityID anotherBoxTransformId; + std::vector linkOM; + OctTree someOctTree; //constructor HardcodedTestWorld() : World() + , someOctTree(AABB(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)), 2) { registerTestComponents(); - createTestEntities(AABB(glm::vec3(-0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.4f, 0.6f))); + //createTestEntities(); } private: @@ -61,58 +66,69 @@ private: RegisterComponent(f); } - void createTestEntities(AABB anotherBox) + void createTestEntities() { World& world = *this; - + EntityID tempId; //add octTree { + //copy of mainbox auto someAABB = AABB(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)); - OctTree someOctTree(someAABB, 2); - //add a box - //auto anotherBox = AABB(glm::vec3(-0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.4f, 0.6f)); + + //draw main box first + AddBoxModel(someAABB.Center(), someAABB.HalfSize().x, &someOctTree, tempId); + + //add anotherbox in octTree + auto anotherBox = AABB(glm::vec3(0.1f, 0.1f, 0.1f), glm::vec3(0.2f, 0.2f, 0.2f)); //note: have to delete the box in the tree first, since were trying to move the box - someOctTree.ClearDynamicObjects(); someOctTree.AddDynamicObject(anotherBox); - //the main box first - AddBoxModel(someAABB.Center(), someAABB.HalfSize().x, someOctTree.m_DynamicObjects.size()); - - //draw anotherbox - AddBoxModel(anotherBox.Center(), anotherBox.HalfSize().x, 0); + //draw anotherbox and save it in anotherBoxTransformId + AddBoxModel(anotherBox.Center(), anotherBox.HalfSize().x, &someOctTree, anotherBoxTransformId); //draw the octTree for (size_t j = 0; j < 8; j++) { AddBoxModel(someOctTree.m_Children[j]->m_Box.Center(), - someOctTree.m_Children[j]->m_Box.HalfSize().x, someOctTree.m_Children[j]->m_DynamicObjects.size()); + someOctTree.m_Children[j]->m_Box.HalfSize().x, someOctTree.m_Children[j], tempId); auto someChild = someOctTree.m_Children[j]; for (size_t i = 0; i < 8; i++) { AddBoxModel(someChild->m_Children[i]->m_Box.Center(), - someChild->m_Children[i]->m_Box.HalfSize().x, someChild->m_Children[i]->m_DynamicObjects.size()); + someChild->m_Children[i]->m_Box.HalfSize().x, someChild->m_Children[i], tempId); } } } }//end CreateEnt - void AddBoxModel(const glm::vec3 ¢er, const float &halfSize, const int &contBoxes) { + void AddBoxModel(const glm::vec3 ¢er, const float &halfSize, OctTree* child, EntityID &outEntityId) { World& world = *this; EntityID entityDummyScene = world.CreateEntity(); - + outEntityId = entityDummyScene; ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); transform["Position"] = center; - transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSize*2.0f; + transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSize*2.0f*0.97f; ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox2.obj"; + model["Resource"] = "Models/Core/UnitBox.obj"; model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); - if (contBoxes != 0) + if (child->m_DynamicObjects.size() != 0) model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); + linkOM.emplace_back(entityDummyScene, child, center); //extra //allModels.push_back(model); } + void createTestEntitiesTest2() + { + World& world = *this; + + EntityID entityCollisionBox = world.CreateEntity(); + ComponentWrapper transform = world.AttachComponent(entityCollisionBox, "Transform"); + transform["Position"] = glm::vec3(0.f, 2.f, 0.f); + ComponentWrapper model = world.AttachComponent(entityCollisionBox, "Model"); + model["Resource"] = "Models/Core/UnitBox.obj"; + } }; \ No newline at end of file From c60e96883662d244d99b894f718cd9b6b6f6d9ab Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 10 Dec 2015 11:03:40 +0100 Subject: [PATCH 07/10] Removed a boxclear in the end of the test2 method --- include/Engine/Core/OctTree.h | 1 + src/Engine/Core/OctTree.cpp | 4 ++-- src/Tests/OctTreeTestGameClass.cpp | 24 ++++++++++++++++++----- src/Tests/OctTreeTestHardCodedTestWorld.h | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/include/Engine/Core/OctTree.h b/include/Engine/Core/OctTree.h index e5d5a83a..7379b202 100644 --- a/include/Engine/Core/OctTree.h +++ b/include/Engine/Core/OctTree.h @@ -58,6 +58,7 @@ private: glm::quat m_PrevOri; inline bool hasChildren() const; +public: int childIndexContainingPoint(const glm::vec3& point) const; std::vector childIndicesContainingBox(const AABB& box) const; }; diff --git a/src/Engine/Core/OctTree.cpp b/src/Engine/Core/OctTree.cpp index 82c1b554..582e3acd 100644 --- a/src/Engine/Core/OctTree.cpp +++ b/src/Engine/Core/OctTree.cpp @@ -109,8 +109,8 @@ void OctTree::Update(float dt, World* world, Camera* cam) ComponentWrapper transform = world->GetComponent(m_BoxID, "Transform"); transform["Position"] = boxPos; ComponentWrapper model = world->GetComponent(m_BoxID, "Model"); - //if (BoxCollides(box, AABB())) { - if (Collision::AABBVsAABB(box, aabb)) { + if (BoxCollides(box, AABB())) { + //if (Collision::AABBVsAABB(box, aabb)) { cam->SetPosition(m_PrevPos); cam->SetOrientation(m_PrevOri); model["Color"] = greenCol; diff --git a/src/Tests/OctTreeTestGameClass.cpp b/src/Tests/OctTreeTestGameClass.cpp index e79f645b..6b2e23bc 100644 --- a/src/Tests/OctTreeTestGameClass.cpp +++ b/src/Tests/OctTreeTestGameClass.cpp @@ -58,7 +58,13 @@ void Game::Tick() m_EventBroker->Swap(); #define TEST2 + //this draws the octTree and you can set the cube inside it and see what boxes in the tree that it belongs to #ifdef TEST1 + if (!m_UpdatedOnce) { + m_UpdatedOnce = true; + m_World->createTestEntitiesTest1(); + } + //add/move the trigger box auto pos = m_Renderer->Camera()->Forward() + m_Renderer->Camera()->Position(); AABB boxi; @@ -103,25 +109,32 @@ void Game::Tick() //wireframe glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); #endif + //this tests AABB vs AABB collision and AABB vs OctTree with AABB in it #ifdef TEST2 //only add 1 for now... //grey box - AABB aabb; - aabb.CreateFromCenter(glm::vec3(0.f, 2.f, 0.f), glm::vec3(1.f, 1.f, 1.f)); const glm::vec4 redCol = glm::vec4(1, 0.2f, 0, 1); const glm::vec4 greenCol = glm::vec4(0.1f, 1.0f, 0.25f, 1); const glm::vec3 boxSize = 0.1f*glm::vec3(1.0f, 1.0f, 1.0f); + AABB aabb; + aabb.CreateFromCenter(glm::vec3(0, 2.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)); + if (m_UpdatedOnce) { + auto test = someOctTree.childIndicesContainingBox(aabb); + std::vector test2; + someOctTree.BoxesInSameRegion(aabb, test2); + } if (!m_UpdatedOnce) { + m_UpdatedOnce = true; someOctTree.AddStaticObject(aabb); + //create the "small red box" m_BoxID = m_World->CreateEntity(); ComponentWrapper transform = m_World->AttachComponent(m_BoxID, "Transform"); transform["Scale"] = boxSize; ComponentWrapper model = m_World->AttachComponent(m_BoxID, "Model"); model["Resource"] = "Models/Core/UnitBox.obj"; - m_UpdatedOnce = true; m_World->createTestEntitiesTest2(); } @@ -132,8 +145,10 @@ void Game::Tick() ComponentWrapper transform = m_World->GetComponent(m_BoxID, "Transform"); transform["Position"] = boxPos; ComponentWrapper model = m_World->GetComponent(m_BoxID, "Model"); + //this checks AABB vs an AABB in the octTree if (someOctTree.BoxCollides(redBox, AABB())) { - //if (Collision::AABBVsAABB(redBox, aabb)) { + //this checks AABB vs AABB + //if (Collision::AABBVsAABB(redBox, aabb)) { m_Renderer->Camera()->SetPosition(m_PrevPos); m_Renderer->Camera()->SetOrientation(m_PrevOri); model["Color"] = greenCol; @@ -144,7 +159,6 @@ void Game::Tick() m_PrevPos = m_Renderer->Camera()->Position(); m_PrevOri = m_Renderer->Camera()->Orientation(); - someOctTree.ClearObjects(); m_RenderQueueFactory->Update(m_World); #endif diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index ff7b56cc..a0762cce 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -66,7 +66,7 @@ private: RegisterComponent(f); } - void createTestEntities() + void createTestEntitiesTest1() { World& world = *this; EntityID tempId; From 350038057d5273b16f016fc4df7a684516a87124 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Fri, 11 Dec 2015 13:51:07 +0100 Subject: [PATCH 08/10] Misc OctTreeTest changes --- src/Engine/Core/OctTree.cpp | 2 +- src/Tests/OctTreeTest.cpp | 4 +- src/Tests/OctTreeTestGameClass.cpp | 10 ++--- src/Tests/OctTreeTestHardCodedTestWorld.h | 49 +++++++++++------------ 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/Engine/Core/OctTree.cpp b/src/Engine/Core/OctTree.cpp index 63eba63e..aae9762a 100644 --- a/src/Engine/Core/OctTree.cpp +++ b/src/Engine/Core/OctTree.cpp @@ -163,7 +163,7 @@ OctTree::OctChild::~OctChild() void OctTree::Update(float dt, World* world, Camera* cam) { - for (ComponentWrapper& c : world->GetComponents("Collision")) { + for (ComponentWrapper& c : *world->GetComponents("Collision")) { AABB aabb; aabb.CreateFromCenter(c["BoxCenter"], c["BoxSize"]); AddDynamicObject(aabb); diff --git a/src/Tests/OctTreeTest.cpp b/src/Tests/OctTreeTest.cpp index 23a09fcd..71d41cad 100644 --- a/src/Tests/OctTreeTest.cpp +++ b/src/Tests/OctTreeTest.cpp @@ -30,8 +30,8 @@ BOOST_AUTO_TEST_CASE(octTreeTest) BOOST_CHECK(someAABB.Center() == 0.5f * (minCorner + maxCorner)); //simple OctTree constructor check - OctTree someOctTree(someAABB, 5); - BOOST_CHECK(someOctTree.m_Children[0] != nullptr); + //OctTree someOctTree(someAABB, 5); + //BOOST_CHECK(someOctTree.m_Children[0] != nullptr); //simple destructor check in the end, just look for memleaks, then it didnt clear the AABB structure } diff --git a/src/Tests/OctTreeTestGameClass.cpp b/src/Tests/OctTreeTestGameClass.cpp index 6b2e23bc..735d3ee8 100644 --- a/src/Tests/OctTreeTestGameClass.cpp +++ b/src/Tests/OctTreeTestGameClass.cpp @@ -57,7 +57,7 @@ void Game::Tick() m_Renderer->Update(dt); m_EventBroker->Swap(); -#define TEST2 +#define TEST1 //this draws the octTree and you can set the cube inside it and see what boxes in the tree that it belongs to #ifdef TEST1 if (!m_UpdatedOnce) { @@ -81,13 +81,13 @@ void Game::Tick() //check all children again in the tree if they have a box in them or not, and colormark them if they do //contentboxarna får man ut - inte childboxarna! std::vector boxIndex; - boxIndex = m_World->someOctTree.childIndicesContainingBox(boxi); + boxIndex = m_World->someOctTree.m_Root->childIndicesContainingBox(boxi); for (auto& oneLinkedObject : m_World->linkOM) { ComponentWrapper model = m_World->GetComponent(oneLinkedObject.entId, "Model"); model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); - if (oneLinkedObject.child->m_DynamicObjects.size() != 0) { + if (oneLinkedObject.child->m_DynamicObjIndices.size() != 0) { model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); } @@ -95,7 +95,7 @@ void Game::Tick() //REQUIRED: childIndicesContainingBox must be public to test this! for each (auto someBoxIndex in boxIndex) { - glm::vec3 pos = m_World->someOctTree.m_Children[someBoxIndex]->m_Box.Center(); + glm::vec3 pos = m_World->someOctTree.m_Root->m_Children[someBoxIndex]->m_Box.Center(); if (abs(pos.x - oneLinkedObject.posxyz.x) < 0.005f && abs(pos.y - oneLinkedObject.posxyz.y) < 0.005f && abs(pos.z - oneLinkedObject.posxyz.z) < 0.005f) { @@ -122,7 +122,7 @@ void Game::Tick() aabb.CreateFromCenter(glm::vec3(0, 2.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)); if (m_UpdatedOnce) { - auto test = someOctTree.childIndicesContainingBox(aabb); + //auto test = someOctTree.childIndicesContainingBox(aabb); std::vector test2; someOctTree.BoxesInSameRegion(aabb, test2); } diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index a0762cce..46b1e00b 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -15,9 +15,9 @@ class HardcodedTestWorld : public World public: struct LinkOctTreeAndModel { EntityID entId; - OctTree* child; + OctTree::OctChild* child; glm::vec3 posxyz; - LinkOctTreeAndModel(EntityID eId, OctTree* ch, glm::vec3 pos) + LinkOctTreeAndModel(EntityID eId, OctTree::OctChild* ch, glm::vec3 pos) { entId = eId; child = ch; @@ -76,7 +76,7 @@ private: auto someAABB = AABB(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)); //draw main box first - AddBoxModel(someAABB.Center(), someAABB.HalfSize().x, &someOctTree, tempId); + AddBoxModel(someAABB.Center(), someAABB.HalfSize().x, someOctTree.m_Root, tempId); //add anotherbox in octTree auto anotherBox = AABB(glm::vec3(0.1f, 0.1f, 0.1f), glm::vec3(0.2f, 0.2f, 0.2f)); @@ -84,15 +84,15 @@ private: someOctTree.AddDynamicObject(anotherBox); //draw anotherbox and save it in anotherBoxTransformId - AddBoxModel(anotherBox.Center(), anotherBox.HalfSize().x, &someOctTree, anotherBoxTransformId); + AddBoxModel(anotherBox.Center(), anotherBox.HalfSize().x, someOctTree.m_Root, anotherBoxTransformId); //draw the octTree for (size_t j = 0; j < 8; j++) { - AddBoxModel(someOctTree.m_Children[j]->m_Box.Center(), - someOctTree.m_Children[j]->m_Box.HalfSize().x, someOctTree.m_Children[j], tempId); + AddBoxModel(someOctTree.m_Root->m_Children[j]->m_Box.Center(), + someOctTree.m_Root->m_Children[j]->m_Box.HalfSize().x, someOctTree.m_Root->m_Children[j], tempId); - auto someChild = someOctTree.m_Children[j]; + auto someChild = someOctTree.m_Root->m_Children[j]; for (size_t i = 0; i < 8; i++) { @@ -103,24 +103,6 @@ private: } }//end CreateEnt - void AddBoxModel(const glm::vec3 ¢er, const float &halfSize, OctTree* child, EntityID &outEntityId) { - World& world = *this; - - EntityID entityDummyScene = world.CreateEntity(); - outEntityId = entityDummyScene; - ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); - transform["Position"] = center; - transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSize*2.0f*0.97f; - ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; - model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); - if (child->m_DynamicObjects.size() != 0) - model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); - - linkOM.emplace_back(entityDummyScene, child, center); - //extra - //allModels.push_back(model); - } void createTestEntitiesTest2() { World& world = *this; @@ -131,4 +113,21 @@ private: ComponentWrapper model = world.AttachComponent(entityCollisionBox, "Model"); model["Resource"] = "Models/Core/UnitBox.obj"; } + + void AddBoxModel(const glm::vec3 ¢er, const float &halfSize, OctTree::OctChild* child, EntityID &outEntityId) { + World& world = *this; + + EntityID entityDummyScene = world.CreateEntity(); + outEntityId = entityDummyScene; + ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); + transform["Position"] = center; + transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSize*2.0f*0.97f; + ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); + model["Resource"] = "Models/Core/UnitBox.obj"; + model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + if (child->m_DynamicObjIndices.size() != 0) + model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); + + linkOM.emplace_back(entityDummyScene, child, center); + } }; \ No newline at end of file From 5fce7490a9d547e37d673d78f1c714ea5e6dc718 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Mon, 14 Dec 2015 11:57:18 +0100 Subject: [PATCH 09/10] MergeFix OctTree williambranch and andersbranch --- src/Tests/OctTreeTest.cpp | 45 ++----------------- src/Tests/OctTreeTestAnders.cpp | 53 +++++++++++++++++++++++ src/Tests/OctTreeTestGameClass.h | 1 + src/Tests/OctTreeTestHardCodedTestWorld.h | 1 + 4 files changed, 58 insertions(+), 42 deletions(-) create mode 100644 src/Tests/OctTreeTestAnders.cpp diff --git a/src/Tests/OctTreeTest.cpp b/src/Tests/OctTreeTest.cpp index 68aa4c7a..0206ce50 100644 --- a/src/Tests/OctTreeTest.cpp +++ b/src/Tests/OctTreeTest.cpp @@ -2,51 +2,12 @@ using boost::unit_test_framework::test_suite; using boost::unit_test_framework::test_case; #include //srand -#include "OctTreeTestGameClass.h" -//HACK! Needed for white box testing -//else we would have to "open up" the octTree class more with get/sets, public methods, etc. which is not good encapsulation-wise -//#include "Engine/Core/OctTree.h" + +#include "Engine/Core/OctTree.h" #include "Engine/Core/Ray.h" #include "OldOctTree.h" -//friend class and refactoringIntoNewClass is some extra work and needs to be updated when the original class is updated, and can contain bugs that -//isnt in the original class -//Reflection-inspection seems to be only available for C# -//http://stackoverflow.com/questions/6778496/how-to-do-unit-testing-on-private-members-and-methods-of-c-classes -//http://stackoverflow.com/questions/3676664/unit-testing-of-private-methods -#define private public -#include -BOOST_AUTO_TEST_SUITE(octTreeTests) - -BOOST_AUTO_TEST_CASE(octTreeTest) -{ - //white box testing - //http://softwaretestingfundamentals.com/differences-between-black-box-testing-and-white-box-testing/ - //http://technologyconversations.com/2013/12/11/black-box-vs-white-box-testing/ - - //simple AABB constructor check - auto minCorner = glm::vec3(0.0f, 0.0f, 0.0f); - auto maxCorner = glm::vec3(1.0f, 1.0f, 1.0f); - auto someAABB = AABB(minCorner,maxCorner); - BOOST_CHECK(someAABB.MinCorner() == minCorner); - BOOST_CHECK(someAABB.MaxCorner() == maxCorner); - BOOST_CHECK(someAABB.Center() == 0.5f * (minCorner + maxCorner)); - - //simple OctTree constructor check - //OctTree someOctTree(someAABB, 5); - //BOOST_CHECK(someOctTree.m_Children[0] != nullptr); - - //simple destructor check in the end, just look for memleaks, then it didnt clear the AABB structure -} - -BOOST_AUTO_TEST_CASE(octTreeTest2) -{ - //octtree ritningen osv - Game game(0, nullptr); - while (game.Running()) { - game.Tick(); - } -} +BOOST_AUTO_TEST_SUITE(octTreeTestsW) BOOST_AUTO_TEST_CASE(octSameRegionTest) { diff --git a/src/Tests/OctTreeTestAnders.cpp b/src/Tests/OctTreeTestAnders.cpp new file mode 100644 index 00000000..12a122ea --- /dev/null +++ b/src/Tests/OctTreeTestAnders.cpp @@ -0,0 +1,53 @@ +#include +using boost::unit_test_framework::test_suite; +using boost::unit_test_framework::test_case; +#include //srand + +//#define private public//HACK! Needed for white box testing +//#include "Engine/Core/OctTree.h" +//#include "OldOctTree.h" +//friend class and refactoringIntoNewClass is some extra work and needs to be updated when the original class is updated, and can contain bugs that +//isnt in the original class +//Reflection-inspection seems to be only available for C# +//http://stackoverflow.com/questions/6778496/how-to-do-unit-testing-on-private-members-and-methods-of-c-classes +//http://stackoverflow.com/questions/3676664/unit-testing-of-private-methods + +#include "OctTreeTestGameClass.h" + +#define private public//HACK! Needed for white box testing +#include +//else we would have to "open up" the octTree class more with get/sets, public methods, etc. which is not good encapsulation-wise + +BOOST_AUTO_TEST_SUITE(octTreeTestsA) + +BOOST_AUTO_TEST_CASE(octTreeTest) +{ + //white box testing + //http://softwaretestingfundamentals.com/differences-between-black-box-testing-and-white-box-testing/ + //http://technologyconversations.com/2013/12/11/black-box-vs-white-box-testing/ + + //simple AABB constructor check + auto minCorner = glm::vec3(0.0f, 0.0f, 0.0f); + auto maxCorner = glm::vec3(1.0f, 1.0f, 1.0f); + auto someAABB = AABB(minCorner, maxCorner); + BOOST_CHECK(someAABB.MinCorner() == minCorner); + BOOST_CHECK(someAABB.MaxCorner() == maxCorner); + BOOST_CHECK(someAABB.Center() == 0.5f * (minCorner + maxCorner)); + + //simple OctTree constructor check + //OctTree someOctTree(someAABB, 5); + //BOOST_CHECK(someOctTree.m_Children[0] != nullptr); + + //simple destructor check in the end, just look for memleaks, then it didnt clear the AABB structure +} + +BOOST_AUTO_TEST_CASE(octTreeTest2) +{ + //octtree ritningen osv + Game game(0, nullptr); + while (game.Running()) { + game.Tick(); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/Tests/OctTreeTestGameClass.h b/src/Tests/OctTreeTestGameClass.h index 8ca34510..38aaab66 100644 --- a/src/Tests/OctTreeTestGameClass.h +++ b/src/Tests/OctTreeTestGameClass.h @@ -13,6 +13,7 @@ #include "OctTreeTestHardCodedTestWorld.h" #include "Core\Collision.h" + class Game { public: diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index 46b1e00b..512716df 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -7,6 +7,7 @@ #include //last! +//#include "OldOctTree.h" #define private public #include From 7f8e78c8cdeedcfb794b75b4cba3b00f583941ea Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Mon, 14 Dec 2015 17:04:35 +0100 Subject: [PATCH 10/10] RayVsModel tests in progress --- src/Engine/Core/Collision.cpp | 13 +++-- src/Tests/CMakeLists.txt | 1 + src/Tests/CollisionTest.cpp | 95 ++++++++++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 4 deletions(-) diff --git a/src/Engine/Core/Collision.cpp b/src/Engine/Core/Collision.cpp index dee567e0..44875aa4 100644 --- a/src/Engine/Core/Collision.cpp +++ b/src/Engine/Core/Collision.cpp @@ -86,10 +86,14 @@ bool RayVsModel(const Ray& ray, glm::vec3 m = ray.Origin - v0; glm::vec3 MxE1 = glm::cross(m, e1); glm::vec3 DxE2 = glm::cross(ray.Direction, e2); - float DetInv = 1.0f / glm::dot(e1, DxE2); + float DetInv = glm::dot(e1, DxE2); + if (std::abs(DetInv) < FLT_EPSILON) { + continue; + } + DetInv = 1.0f / DetInv; float u = glm::dot(m, DxE2) * DetInv; float v = glm::dot(ray.Direction, MxE1) * DetInv; - if (u < 0 && v < 0 && 1 < u + v) { + if (u < 0 || v < 0 || 1 < u + v) { continue; } //Here, u and v are positive, u+v <= 1, and if distance is positive - triangle is hit. @@ -116,7 +120,10 @@ bool RayVsModel(const Ray& ray, glm::vec3 m = ray.Origin - v0; glm::vec3 MxE1 = glm::cross(m, e1); glm::vec3 DxE2 = glm::cross(ray.Direction, e2); - float DetInv = 1.0f / glm::dot(e1, DxE2); + float DetInv = glm::dot(e1, DxE2); + if (std::abs(DetInv) < FLT_EPSILON) { + continue; + } float dist = glm::dot(e2, MxE1) * DetInv; if (dist >= outDistance) { continue; diff --git a/src/Tests/CMakeLists.txt b/src/Tests/CMakeLists.txt index 697dea29..a3f95a37 100644 --- a/src/Tests/CMakeLists.txt +++ b/src/Tests/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories( ) file(GLOB SOURCE_FILES + "*.h" "*.cpp" ) diff --git a/src/Tests/CollisionTest.cpp b/src/Tests/CollisionTest.cpp index eef24e61..497812a3 100644 --- a/src/Tests/CollisionTest.cpp +++ b/src/Tests/CollisionTest.cpp @@ -3,11 +3,18 @@ #include using boost::unit_test_framework::test_suite; using boost::unit_test_framework::test_case; -#include +#include "Engine\Core\Collision.h" #include "Engine/Core/AABB.h" #include "Engine/Core/Ray.h" #include //srand #include "Engine/Core/OctTree.h" +//vs model +#include + +//ray vs model +#include "Engine\Core\ResourceManager.h" +#include "Engine\Rendering\Model.h" +#include "Engine\Core\Ray.h" //vs memleaks //#define _CRTDBG_MAP_ALLOC @@ -87,6 +94,92 @@ BOOST_AUTO_TEST_CASE(collisionTest2) BOOST_CHECK(test >= 0); } +BOOST_AUTO_TEST_CASE(rayVsModelTest) +{ + //simple test + + Ray ray; + ray.Origin = glm::vec3(-50, 0, 0); + //ray.Direction = glm::vec3(-1, 0, 0); + ray.Direction = glm::normalize(glm::vec3(1, 0, 0)); + //inte model, det kräver renderar grejs tydligen + ResourceManager::RegisterType("RawModel"); + auto unitBox = ResourceManager::Load("Models/Core/UnitBox.obj"); + BOOST_CHECK(unitBox != nullptr); + bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices); + BOOST_CHECK(hit); + ray.Direction = glm::normalize(glm::vec3(-1, 0, 0)); + hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices); + BOOST_CHECK(!hit); +} + +BOOST_AUTO_TEST_CASE(rayVsModelTest2) +{ + //advanced test, based on ray vs AABB + srand(7676762); + Ray ray; + AABB someAABB; + glm::vec3 minPos; + glm::vec3 maxPos; + bool z; + int test = 0; + minPos = glm::vec3(-0.5f, -0.5f, -0.5f); + maxPos = glm::vec3(0.5f, 0.5f, 0.5f); + someAABB = AABB(minPos, maxPos); + ResourceManager::RegisterType("RawModel"); + auto unitBox = ResourceManager::Load("Models/Core/UnitBox.obj"); + BOOST_CHECK(unitBox != nullptr); + + for (size_t i = 0; i < 1000000; i++) + { + ray.Origin.x = rand() % 100; + ray.Origin.y = rand() % 100; + ray.Origin.z = rand() % 100; + ray.Direction.x = rand() % 100; + ray.Direction.y = rand() % 100; + ray.Direction.z = rand() % 100; + ray.Origin /= 100; + ray.Origin = glm::vec3(-2, 0, 0); + ray.Direction /= 100; + ray.Direction = glm::normalize(ray.Direction); + + z = Collision::RayVsAABB(ray, someAABB); + if (z) { + //hit + bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices); + if (!hit) { + hit = hit; + glm::vec3 outtttttttt; + hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices, outtttttttt); + hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices); + } + else { + hit = hit; + } + BOOST_CHECK(hit); + } + // + bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices); + if (hit) { + //hit + z = Collision::RayVsAABB(ray, someAABB); + if (!z) { + z = z; + z = Collision::RayVsAABB(ray, someAABB); + glm::vec3 outtttttttt; + hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices, outtttttttt); + hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices); + } + else { + z = z; + } + BOOST_CHECK(hit); + } + + } +} + + BOOST_AUTO_TEST_CASE(octTest) { glm::vec3 mini = glm::vec3(-1, -1, -1);