diff --git a/KREngine/kraken/KRHitInfo.h b/KREngine/kraken/KRHitInfo.h index e63c5a6..ecadc52 100644 --- a/KREngine/kraken/KRHitInfo.h +++ b/KREngine/kraken/KRHitInfo.h @@ -33,7 +33,8 @@ #define KRHITINFO_H #include "KRVector3.h" -#include "KRNode.h" + +class KRNode; class KRHitInfo { public: diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index 3bd5546..d118a41 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -409,3 +409,26 @@ void KRNode::SetAttribute(node_attribute_type attrib, float v) } } +void KRNode::removeFromOctreeNodes() +{ + for(std::set::iterator itr=m_octree_nodes.begin(); itr != m_octree_nodes.end(); itr++) { + KROctreeNode *octree_node = *itr; + octree_node->remove(this); + + // FINDME, TODO - This should be moved to the KROctree class + while(octree_node) { + octree_node->trim(); + if(octree_node->isEmpty()) { + octree_node = octree_node->getParent(); + } else { + octree_node = NULL; + } + } + } + m_octree_nodes.clear(); +} + +void KRNode::addToOctreeNode(KROctreeNode *octree_node) +{ + m_octree_nodes.insert(octree_node); +} diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index cff71f4..4992d38 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -13,6 +13,7 @@ #include "KRVector3.h" #include "KRViewport.h" #include "tinyxml2.h" +#include "KROctreeNode.h" class KRCamera; class KRShaderManager; @@ -131,8 +132,13 @@ private: KRScene *m_pScene; + std::set m_octree_nodes; + public: + void removeFromOctreeNodes(); + void addToOctreeNode(KROctreeNode *octree_node); + template T *find() { T *match = dynamic_cast(this); diff --git a/KREngine/kraken/KROctree.cpp b/KREngine/kraken/KROctree.cpp index 18b1045..ffc22f4 100644 --- a/KREngine/kraken/KROctree.cpp +++ b/KREngine/kraken/KROctree.cpp @@ -32,8 +32,7 @@ void KROctree::add(KRNode *pNode) } else { if(m_pRootNode == NULL) { // First item inserted, create a node large enough to fit it - m_pRootNode = new KROctreeNode(nodeBounds); - //m_pRootNode = new KROctreeNode(KRAABB(nodeBounds.min - nodeBounds.size() * 0.25f, nodeBounds.max + nodeBounds.size() * 0.25f)); + m_pRootNode = new KROctreeNode(NULL, nodeBounds); m_pRootNode->add(pNode); } else { // Keep encapsulating the root node until the new root contains the inserted node @@ -42,9 +41,9 @@ void KROctree::add(KRNode *pNode) KRAABB rootBounds = m_pRootNode->getBounds(); KRVector3 rootSize = rootBounds.size(); if(nodeBounds.min.x < rootBounds.min.x || nodeBounds.min.y < rootBounds.min.y || nodeBounds.min.z < rootBounds.min.z) { - m_pRootNode = new KROctreeNode(KRAABB(rootBounds.min - rootSize, rootBounds.max), 7, m_pRootNode); + m_pRootNode = new KROctreeNode(NULL, KRAABB(rootBounds.min - rootSize, rootBounds.max), 7, m_pRootNode); } else if(nodeBounds.max.x > rootBounds.max.x || nodeBounds.max.y > rootBounds.max.y || nodeBounds.max.z > rootBounds.max.z) { - m_pRootNode = new KROctreeNode(KRAABB(rootBounds.min, rootBounds.max + rootSize), 0, m_pRootNode); + m_pRootNode = new KROctreeNode(NULL, KRAABB(rootBounds.min, rootBounds.max + rootSize), 0, m_pRootNode); } else { bInsideRoot = true; } @@ -58,7 +57,7 @@ void KROctree::remove(KRNode *pNode) { if(!m_outerSceneNodes.erase(pNode)) { if(m_pRootNode) { - m_pRootNode->remove(pNode); + pNode->removeFromOctreeNodes(); } } diff --git a/KREngine/kraken/KROctree.h b/KREngine/kraken/KROctree.h index 5a97c5e..7f0cd12 100644 --- a/KREngine/kraken/KROctree.h +++ b/KREngine/kraken/KROctree.h @@ -34,7 +34,6 @@ public: private: KROctreeNode *m_pRootNode; std::set m_outerSceneNodes; - //std::set visibleMVPs; void shrink(); }; diff --git a/KREngine/kraken/KROctreeNode.cpp b/KREngine/kraken/KROctreeNode.cpp index e71c6c0..490b7f7 100644 --- a/KREngine/kraken/KROctreeNode.cpp +++ b/KREngine/kraken/KROctreeNode.cpp @@ -10,8 +10,10 @@ #include "KRNode.h" #include "KRCollider.h" -KROctreeNode::KROctreeNode(const KRAABB &bounds) : m_bounds(bounds) +KROctreeNode::KROctreeNode(KROctreeNode *parent, const KRAABB &bounds) : m_bounds(bounds) { + m_parent = parent; + for(int i=0; i<8; i++) m_children[i] = NULL; m_occlusionQuery = 0; @@ -19,11 +21,14 @@ KROctreeNode::KROctreeNode(const KRAABB &bounds) : m_bounds(bounds) m_activeQuery = false; } -KROctreeNode::KROctreeNode(const KRAABB &bounds, int iChild, KROctreeNode *pChild) : m_bounds(bounds) +KROctreeNode::KROctreeNode(KROctreeNode *parent, const KRAABB &bounds, int iChild, KROctreeNode *pChild) : m_bounds(bounds) { // This constructor is used when expanding the octree and replacing the root node with a new root that encapsulates it + m_parent = parent; + for(int i=0; i<8; i++) m_children[i] = NULL; m_children[iChild] = pChild; + pChild->m_parent = this; m_occlusionQuery = 0; m_occlusionTested = false; @@ -81,9 +86,10 @@ void KROctreeNode::add(KRNode *pNode) int iChild = getChildIndex(pNode); if(iChild == -1) { m_sceneNodes.insert(pNode); + pNode->addToOctreeNode(this); } else { if(m_children[iChild] == NULL) { - m_children[iChild] = new KROctreeNode(getChildBounds(iChild)); + m_children[iChild] = new KROctreeNode(this, getChildBounds(iChild)); } m_children[iChild]->add(pNode); } @@ -115,12 +121,10 @@ int KROctreeNode::getChildIndex(KRNode *pNode) return -1; } -void KROctreeNode::remove(KRNode *pNode) +void KROctreeNode::trim() { - if(!m_sceneNodes.erase(pNode)) { - int iChild = getChildIndex(pNode); + for(int iChild = 0; iChild < 8; iChild++) { if(m_children[iChild]) { - m_children[iChild]->remove(pNode); if(m_children[iChild]->isEmpty()) { delete m_children[iChild]; m_children[iChild] = NULL; @@ -129,6 +133,11 @@ void KROctreeNode::remove(KRNode *pNode) } } +void KROctreeNode::remove(KRNode *pNode) +{ + m_sceneNodes.erase(pNode); +} + void KROctreeNode::update(KRNode *pNode) { @@ -162,6 +171,7 @@ KROctreeNode *KROctreeNode::stripChild() for(int i=0; i<8; i++) { if(m_children[i]) { KROctreeNode *child = m_children[i]; + child->m_parent = NULL; m_children[i] = NULL; return child; } @@ -170,6 +180,11 @@ KROctreeNode *KROctreeNode::stripChild() } +KROctreeNode *KROctreeNode::getParent() +{ + return m_parent; +} + KROctreeNode **KROctreeNode::getChildren() { return m_children; diff --git a/KREngine/kraken/KROctreeNode.h b/KREngine/kraken/KROctreeNode.h index b33ab65..c1bb7cf 100644 --- a/KREngine/kraken/KROctreeNode.h +++ b/KREngine/kraken/KROctreeNode.h @@ -18,8 +18,8 @@ class KRNode; class KROctreeNode { public: - KROctreeNode(const KRAABB &bounds); - KROctreeNode(const KRAABB &bounds, int iChild, KROctreeNode *pChild); + KROctreeNode(KROctreeNode *parent, const KRAABB &bounds); + KROctreeNode(KROctreeNode *parent, const KRAABB &bounds, int iChild, KROctreeNode *pChild); ~KROctreeNode(); KROctreeNode **getChildren(); @@ -31,9 +31,11 @@ public: KRAABB getBounds(); + KROctreeNode *getParent(); void setChildNode(int iChild, KROctreeNode *pChild); int getChildIndex(KRNode *pNode); KRAABB getChildBounds(int iChild); + void trim(); bool isEmpty() const; bool canShrinkRoot() const; @@ -53,6 +55,7 @@ private: KRAABB m_bounds; + KROctreeNode *m_parent; KROctreeNode *m_children[8]; std::setm_sceneNodes; diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index c4d0ea9..acd8b51 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -73,7 +73,7 @@ void KRScene::renderFrame(float deltaTime, int width, int height) { } void KRScene::render(KRCamera *pCamera, std::map &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) { - + updateOctree(); if(new_frame) { @@ -97,7 +97,6 @@ void KRScene::render(KRCamera *pCamera, std::map &visibleBounds, co std::vector lights; - updateOctree(); pCamera->settings.setSkyBox(m_skyBoxName); // This is temporary until the camera is moved into the scene graph @@ -383,40 +382,47 @@ KRLight *KRScene::getFirstLight() void KRScene::notify_sceneGraphCreate(KRNode *pNode) { - m_nodeTree.add(pNode); - if(pNode->hasPhysics()) { - m_physicsNodes.insert(pNode); - } -// m_newNodes.insert(pNode); +// m_nodeTree.add(pNode); +// if(pNode->hasPhysics()) { +// m_physicsNodes.insert(pNode); +// } + m_newNodes.insert(pNode); +} + +void KRScene::notify_sceneGraphModify(KRNode *pNode) +{ + // m_nodeTree.update(pNode); + m_modifiedNodes.insert(pNode); } void KRScene::notify_sceneGraphDelete(KRNode *pNode) { m_nodeTree.remove(pNode); m_physicsNodes.erase(pNode); -// -// m_modifiedNodes.erase(pNode); -// if(!m_newNodes.erase(pNode)) { -// m_nodeTree.remove(pNode); -// } -} - -void KRScene::notify_sceneGraphModify(KRNode *pNode) -{ - m_nodeTree.update(pNode); -// m_modifiedNodes.insert(pNode); + m_modifiedNodes.erase(pNode); + if(!m_newNodes.erase(pNode)) { + m_nodeTree.remove(pNode); + } } void KRScene::updateOctree() { -// for(std::set::iterator itr=m_newNodes.begin(); itr != m_newNodes.end(); itr++) { -// m_nodeTree.add(*itr); -// } -// for(std::set::iterator itr=m_modifiedNodes.begin(); itr != m_modifiedNodes.end(); itr++) { -// m_nodeTree.update(*itr); -// } -// m_newNodes.clear(); -// m_modifiedNodes.clear(); + std::set newNodes = m_newNodes; + std::set modifiedNodes = m_modifiedNodes; + m_newNodes.clear(); + m_modifiedNodes.clear(); + + for(std::set::iterator itr=newNodes.begin(); itr != newNodes.end(); itr++) { + KRNode *node = *itr; + m_nodeTree.add(node); + if(node->hasPhysics()) { + m_physicsNodes.insert(node); + } + } + for(std::set::iterator itr=modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) { + KRNode *node = *itr; + m_nodeTree.update(node); + } } void KRScene::physicsUpdate(float deltaTime)