#include "OgreOctreeHierarchyInterface.h" #include "OgreVisibilityOctreeSceneManager.h" #include #include #include namespace Ogre { //----------------------------------------------------------------------- OctreeHierarchyInterface::OctreeHierarchyInterface(OctreeSceneManager *sm, RenderSystem *rsys): SceneNodeHierarchyInterface(sm, rsys) { } //----------------------------------------------------------------------- void OctreeHierarchyInterface::TraverseNode(GtpVisibility::HierarchyNode *node) { ++ mNumTraversedNodes; Octree *octree = static_cast(node); // if we come across some renderable geometry => render it if (octree->mNodes.size() > 0) { RenderNode(node); } // if not all subtrees are empty //if (octree->numNodes() > (int)octree->mNodes.size()) if (!IsLeaf(node)) { for(int i=0; i<8; ++i) { Octree *nextChild = octree->mChildren[(i & 4) >> 2][(i & 2) >> 1][i & 1]; if (nextChild) { mDistanceQueue->push(nextChild); } } } } //----------------------------------------------------------------------- bool OctreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const { Octree *octree = static_cast(node); // HACK: if there are subtrees, they are empty => we are not interested in them return octree->numNodes() == (int)octree->mNodes.size(); } //----------------------------------------------------------------------- bool OctreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const { return static_cast(node)->mNodes.size() > 0; } //----------------------------------------------------------------------- void OctreeHierarchyInterface::SetNumOctreeNodes(unsigned int num) { mNumOctreeNodes = num; } //----------------------------------------------------------------------- float OctreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const { AxisAlignedBox *box = &static_cast(node)->mBox; Vector3 mid = ((box->getMaximum() - box->getMinimum()) * 0.5) + box->getMinimum(); return (mCullCamera->getDerivedPosition() - mid).squaredLength(); } //----------------------------------------------------------------------- void OctreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node, const bool visible) { #ifdef GTP_VISIBILITY_MODIFIED_OGRE static_cast(node)->setOctreeVisible(visible); #endif } //----------------------------------------------------------------------- void OctreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node, const unsigned int frameId) { #ifdef GTP_VISIBILITY_MODIFIED_OGRE static_cast(node)->setLastVisited(frameId); #endif } //----------------------------------------------------------------------- void OctreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) { #ifdef GTP_VISIBILITY_MODIFIED_OGRE Octree *octant = static_cast(node); while(octant && !octant->isOctreeVisible()) { octant->setOctreeVisible(true); octant = octant->getParent(); } #endif } //----------------------------------------------------------------------- void OctreeHierarchyInterface::RenderNode(GtpVisibility::HierarchyNode *node) { #ifdef GTP_VISIBILITY_MODIFIED_OGRE Octree *octant = static_cast(node); if (octant->lastRendered() != mFrameId) { octant->setLastRendered(mFrameId); dynamic_cast(mSceneManager)->_renderOctant(mCamera, octant, mOnlyShadowCasters, mLeavePassesInQueue); mRenderedNodes.push_back(node); } #endif } //----------------------------------------------------------------------- bool OctreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const { #ifdef GTP_VISIBILITY_MODIFIED_OGRE return static_cast(node)->isOctreeVisible(); #else return true; #endif } //----------------------------------------------------------------------- unsigned int OctreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const { #ifdef GTP_VISIBILITY_MODIFIED_OGRE return static_cast(node)->lastVisited(); #else return 0; #endif } //----------------------------------------------------------------------- AxisAlignedBox *OctreeHierarchyInterface::GetBoundingBox(GtpVisibility::HierarchyNode *node) { if (node != mPreviousNode) { mPreviousNode = node; //static_cast(node)->_getCullBounds(&mBox); mBox = static_cast(node)->_getWorldAABB(); //std::stringstream d; d << mBox;LogManager::getSingleton().logMessage(d.str()); } return &mBox; } //----------------------------------------------------------------------- void OctreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node, GtpVisibility::CullingType type) { WireBoundingBox *box = static_cast(node)->getWireBoundingBox(); if (type == GtpVisibility::FRUSTUM_CULLED) { box->setMaterial("FrustumCulledNodesMaterial"); } else // type == GtpVisibility::QUERY_CULLED { box->setMaterial("QueryCulledNodesMaterial"); } dynamic_cast(mSceneManager)->getBoxes()->push_back(box); } //----------------------------------------------------------------------- void OctreeHierarchyInterface::GetGeometry(GtpVisibility::HierarchyNode *node, GtpVisibility::GeometryList *geometryList, bool includeChildren) { NodeList::const_iterator nodeIt, nodeIt_end; nodeIt_end = static_cast(node)->mNodes.end(); for (nodeIt = static_cast(node)->mNodes.begin(); nodeIt != nodeIt_end; ++nodeIt) { SceneNodeHierarchyInterface::GetGeometry(*nodeIt, geometryList, includeChildren); } } //----------------------------------------------------------------------- /*bool OctreeHierarchyInterface::FindVisibleObjects(GtpVisibility::HierarchyNode *node, InfoContainer *visibleGeometry, bool includeChildren) { bool foundVisible = false; PlatformOcclusionQuery query(mRenderSystem); NodeList *nodes = &static_cast(node)->mNodes; NodeList::const_iterator nodeIt = nodes->begin(), nodeIt_end; nodeIt_end = nodes->end(); while (nodeIt != nodeIt_end) { OctreeNode *octreeNode = (*nodeIt); if (SceneNodeHierarchyInterface::FindVisibleObjects(octreeNode, visibleGeometry, includeChildren)) { foundVisible = true; } ++nodeIt; } return foundVisible; }*/ } // namespace Ogre