#ifndef OctTree_h__ #define OctTree_h__ #include "Core/AABB.h" class Ray; class OctTree { public: struct Output { float CollideDistance; }; OctTree(); ~OctTree(); //For the root OctTree, [octTreeBounds] should be a box containing the entire level. OctTree(const AABB& octTreeBounds, int subDivisions); //We cannot copy the OctTree as of now, because of the recursive dynamic allocation. //Define these if the OctTree suddenly needs to be copied, think of the children OctChild* ptrs. OctTree(const OctTree& other) = delete; OctTree(const OctTree&& other) = delete; OctTree& operator= (const OctTree& other) = delete; //Add a dynamic object (one that moves around) into the tree. void AddDynamicObject(const AABB& box); //Add a static object (that does not move) into the tree. void AddStaticObject(const AABB& box); //Get the boxes that are in the same area as the input [box], the boxes are put in [outBoxes]. void BoxesInSameRegion(const AABB& box, std::vector& outBoxes); //Empty the tree of all objects, static and dynamic. void ClearObjects(); //Empty the tree of all dynamic objects. Static objects remain in the tree. void ClearDynamicObjects(); //Returns true if the ray collides with something in the tree. Result is written to [data]. bool RayCollides(const Ray& ray, Output& data); //Returns true if the box collides with something in the tree. //On collision with a box, that box is written to [outBoxIntersected]. //Note: More efficient than calling BoxesInSameRegion from outside and testing there. bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected); private: struct OctChild; //Fwd declaration; struct ContainedObject { ContainedObject() : Box(AABB()) , Checked(false) {} ContainedObject(AABB box) : Box(box) , Checked(false) {} AABB Box; bool Checked; }; OctChild* m_Root; std::vector m_StaticObjects; std::vector m_DynamicObjects; bool m_UpdatedOnce; unsigned int m_BoxID; glm::vec3 m_PrevPos; glm::quat m_PrevOri; void falsifyObjectChecks(); struct OctChild { ~OctChild(); OctChild(const AABB& octTreeBounds, int subDivisions, std::vector& staticObjects, std::vector& dynamicObjects); OctChild(const OctChild& other) = delete; OctChild(const OctChild&& other) = delete; OctChild& operator= (const OctChild& other) = delete; void AddDynamicObject(const AABB& box); void AddStaticObject(const AABB& box); void BoxesInSameRegion(const AABB& box, std::vector& outBoxes) const; void ClearObjects(); void ClearDynamicObjects(); bool RayCollides(const Ray& ray, Output& data) const; bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const; OctChild* m_Children[8]; //Indices into the lists in OctTree. std::vector m_StaticObjIndices; std::vector m_DynamicObjIndices; AABB m_Box; //Reference to the lists in OctTree. std::vector& m_StaticObjectsRef; std::vector& m_DynamicObjectsRef; inline bool hasChildren() const; int childIndexContainingPoint(const glm::vec3& point) const; std::vector childIndicesContainingBox(const AABB& box) const; }; }; #endif