/* ----------------------------------------------------------------------------- This source file is part of the GameTools Project http://www.gametools.org Author: Martin Szydlowski ----------------------------------------------------------------------------- */ #include "OgreKdRenderable.h" #include "OgreKdTreeSceneManager.h" #include "OgreKdTreeHierarchyInterface.h" namespace Ogre { KdTreeHierarchyInterface::KdTreeHierarchyInterface(KdTreeSceneManager *sm, RenderSystem *rsys): PlatformHierarchyInterface(sm, rsys) { } bool KdTreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const { return KDNODEPTR_CAST(node)->isLeaf(); } void KdTreeHierarchyInterface::TraverseNode(GtpVisibility::HierarchyNode *node) { ++ mNumTraversedNodes; KdTree::Node * kdnode = KDNODEPTR_CAST(node); // if the node is a leaf and has geometry => render it if (kdnode->isLeaf()) { if (!kdnode->isEmpty()) { RenderNode(node); } } else { if (kdnode->getLeftChild()) mDistanceQueue->push(kdnode->getLeftChild()); if (kdnode->getRightChild()) mDistanceQueue->push(kdnode->getRightChild()); } } void KdTreeHierarchyInterface::RenderNode(GtpVisibility::HierarchyNode *node) { KdTree::Node * kdnode = KDNODEPTR_CAST(node); if (kdnode->lastRendered() != mFrameId) { kdnode->setLastRendered(mFrameId); KdTreeSceneManager * ksm = static_cast(mSceneManager); ksm->_renderNode(kdnode, mCamera, mOnlyShadowCasters, mLeavePassesInQueue); mVisibleNodes.push_back(node); } } void KdTreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const { KdTree::Node * kdnode = KDNODEPTR_CAST(node); while (kdnode && !kdnode->isNodeVisible()) { kdnode->setNodeVisible(true); kdnode = kdnode->getParent(); } } float KdTreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const { const Vector3 pos = KDNODEPTR_CAST(node)->mAABB.getCenter(); return (mCameraPosition - pos).squaredLength(); } AxisAlignedBox * KdTreeHierarchyInterface::GetBoundingBox(GtpVisibility::HierarchyNode *node) { // reuse box if node is the same // only create renderable bounding box for new node if (node != mSavedNode) { mSavedNode = node; mBox = KDNODEPTR_CAST(node)->_getWorldAABB(); } return &mBox; } bool KdTreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const { return KDNODEPTR_CAST(node)->hasGeometry(); } void KdTreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node, const bool visible) const { KDNODEPTR_CAST(node)->setNodeVisible(visible); } bool KdTreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const { return KDNODEPTR_CAST(node)->isNodeVisible(); } void KdTreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node, const unsigned int frameId) const { KDNODEPTR_CAST(node)->setLastVisited(frameId); } unsigned int KdTreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const { return KDNODEPTR_CAST(node)->lastVisited(); } void KdTreeHierarchyInterface::VisualizeCulledNode(GtpVisibility::HierarchyNode *node, GtpVisibility::CullingType type) const { WireBoundingBox *box = KDNODEPTR_CAST(node)->getWireBoundingBox(); if (type == GtpVisibility::FRUSTUM_CULLED) { box->setMaterial("FrustumCulledNodesMaterial"); } else // type == GtpVisibility::QUERY_CULLED { box->setMaterial("QueryCulledNodesMaterial"); } static_cast(mSceneManager)->getRenderQueue()->addRenderable(box); } void KdTreeHierarchyInterface::GetNodeGeometryList(GtpVisibility::HierarchyNode *node, GtpVisibility::GeometryVector *geometryList, bool includeChildren) { KDNODEPTR_CAST(node)->getGeometryList(geometryList); } } // namespace Ogre