From 14bcb7ea0db5d54a76653d907692af1e8749aa67 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Wed, 9 Dec 2015 13:52:17 +0100 Subject: [PATCH] Added Update call in Game to test OctTree by using collision. --- include/Engine/Core/OctTree.h | 10 +++++++ include/Game/Game.h | 3 +++ include/Game/HardcodedTestWorld.h | 36 ++++++++++++++++++++++++++ src/Engine/Core/OctTree.cpp | 43 +++++++++++++++++++++++++++++++ src/Game/Game.cpp | 9 +++++++ 5 files changed, 101 insertions(+) diff --git a/include/Engine/Core/OctTree.h b/include/Engine/Core/OctTree.h index 911375d5..e5d5a83a 100644 --- a/include/Engine/Core/OctTree.h +++ b/include/Engine/Core/OctTree.h @@ -4,6 +4,8 @@ #include "Core/AABB.h" struct Ray; +class World; +class Camera; class OctTree { @@ -23,6 +25,9 @@ public: OctTree(const OctTree&& other) = delete; OctTree& operator= (const OctTree& other) = delete; + //Collision test function. WTODO: Probably remove or relocate elsewhere, Collision system? + void Update(float dt, World* world, Camera* cam); + void AddDynamicObject(const AABB& box); void AddStaticObject(const AABB& box); @@ -47,6 +52,11 @@ private: std::vector m_DynamicObjects; AABB m_Box; + bool m_UpdatedOnce; + unsigned int m_BoxID; + glm::vec3 m_PrevPos; + glm::quat m_PrevOri; + inline bool hasChildren() const; int childIndexContainingPoint(const glm::vec3& point) const; std::vector childIndicesContainingBox(const AABB& box) const; diff --git a/include/Game/Game.h b/include/Game/Game.h index cd16a3dd..8667b8c8 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -10,6 +10,8 @@ #include "Core/World.h" #include "Rendering/RenderQueueFactory.h" +class OctTree; + class Game { public: @@ -28,6 +30,7 @@ private: GUI::Frame* m_FrameStack; World* m_World; RenderQueueFactory* m_RenderQueueFactory; + OctTree* m_OctTree; }; #endif diff --git a/include/Game/HardcodedTestWorld.h b/include/Game/HardcodedTestWorld.h index f183330f..5f7cc5f6 100644 --- a/include/Game/HardcodedTestWorld.h +++ b/include/Game/HardcodedTestWorld.h @@ -42,6 +42,11 @@ private: f.AddProperty("Color", glm::vec4(1.f, 1.f, 1.f, 1.f)); f.AddProperty("Visible", true); RegisterComponent(f); + + f = ComponentWrapperFactory("Collision"); + f.AddProperty("BoxCenter", glm::vec3(0.f, 0.f, 0.f)); + f.AddProperty("BoxSize", glm::vec3(1.f, 1.f, 1.f)); + RegisterComponent(f); } void createTestEntities() @@ -103,6 +108,37 @@ private: ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); model["Resource"] = "Models/DummyScene.obj"; } + { + 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"; + + ComponentWrapper collision = world.AttachComponent(entityCollisionBox, "Collision"); + glm::vec3 pos = transform["Position"]; + glm::vec3 scale = transform["Scale"]; + glm::quat ori = transform["Orientation"]; + Model* modelRes = ResourceManager::Load(model["Resource"]); + + //WTODO: This only works for objects that never moves/scales/rotates since modelMatrix don't change. + //For dynamic objects, should save a collision box in modelspace and transform box with modelMatrix per collision check. + glm::mat4 modelMatrix = modelRes->m_Matrix * glm::translate(glm::mat4(), pos) * glm::toMat4(ori) * glm::scale(scale); + + glm::vec3 mini = glm::vec3(INFINITY, INFINITY, INFINITY); + glm::vec3 maxi = glm::vec3(-INFINITY, -INFINITY, -INFINITY); + for (const auto& v : modelRes->m_Vertices) { + const auto& wPos = modelMatrix * glm::vec4(v.Position.x, v.Position.y, v.Position.z, 1); + maxi.x = std::max(wPos.x, maxi.x); + maxi.y = std::max(wPos.y, maxi.y); + maxi.z = std::max(wPos.z, maxi.z); + mini.x = std::min(wPos.x, mini.x); + mini.y = std::min(wPos.y, mini.y); + mini.z = std::min(wPos.z, mini.z); + } + collision["BoxCenter"] = 0.5f * (maxi + mini); + collision["BoxSize"] = maxi - mini; + } diff --git a/src/Engine/Core/OctTree.cpp b/src/Engine/Core/OctTree.cpp index 66355580..82c1b554 100644 --- a/src/Engine/Core/OctTree.cpp +++ b/src/Engine/Core/OctTree.cpp @@ -4,6 +4,8 @@ #include "Core/OctTree.h" #include "Core/Collision.h" +#include "Core/World.h" +#include "Rendering/Camera.h" namespace { @@ -27,6 +29,7 @@ OctTree::OctTree() OctTree::OctTree(const AABB& octTreeBounds, int subDivisions) : m_Box(octTreeBounds) + , m_UpdatedOnce(false) { if (subDivisions == 0) { for (OctTree*& c : m_Children) { @@ -80,6 +83,46 @@ OctTree::~OctTree() } } +void OctTree::Update(float dt, World* world, Camera* cam) +{ + AABB aabb; + for (ComponentWrapper& c : world->GetComponents("Collision")) { + aabb.CreateFromCenter(c["BoxCenter"], c["BoxSize"]); + AddStaticObject(aabb); + } + 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) { + m_BoxID = world->CreateEntity(); + ComponentWrapper transform = world->AttachComponent(m_BoxID, "Transform"); + transform["Scale"] = boxSize; + ComponentWrapper model = world->AttachComponent(m_BoxID, "Model"); + model["Resource"] = "Models/Core/UnitBox.obj"; + m_UpdatedOnce = true; + } + + AABB box; + auto boxPos = cam->Position() + 1.2f*cam->Forward(); + box.CreateFromCenter(boxPos, boxSize); + 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)) { + cam->SetPosition(m_PrevPos); + cam->SetOrientation(m_PrevOri); + model["Color"] = greenCol; + } else { + model["Color"] = redCol; + } + + m_PrevPos = cam->Position(); + m_PrevOri = cam->Orientation(); + ClearObjects(); +} + bool OctTree::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const { if (hasChildren()) { diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 416b054e..03e71dce 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -1,5 +1,6 @@ #include "Game.h" #include "HardcodedTestWorld.h" +#include "Core/OctTree.h" Game::Game(int argc, char* argv[]) { @@ -38,6 +39,10 @@ Game::Game(int argc, char* argv[]) // Create a TEST WORLD m_World = new HardcodedTestWorld(); + //WTODO: Current worldsize is temp. + glm::vec3 worldSize = glm::vec3(50, 50, 50); + m_OctTree = new OctTree(AABB(-0.5f*worldSize, 0.5f*worldSize), 2); + m_LastTime = glfwGetTime(); } @@ -45,6 +50,7 @@ Game::~Game() { delete m_FrameStack; delete m_EventBroker; + delete m_OctTree; } void Game::Tick() @@ -56,6 +62,9 @@ void Game::Tick() m_EventBroker->Swap(); m_InputManager->Update(dt); m_Renderer->Update(dt); + + m_OctTree->Update(dt, m_World, m_Renderer->Camera()); + m_EventBroker->Swap(); m_RenderQueueFactory->Update(m_World);