diff --git a/source/anim/DynamicModelProvider.cpp b/source/anim/DynamicModelProvider.cpp index 98c6715f262f65fe0468807e7d3b54d154622fea..cc06aaed5d550f1b81c80d82e8cdb5accb95aacd 100644 --- a/source/anim/DynamicModelProvider.cpp +++ b/source/anim/DynamicModelProvider.cpp @@ -539,16 +539,16 @@ void CDynamicModelProvider::renderEmissive(CRenderableVisibility *pVisibility) render(pVisibility->getSelfillumList(), MF_SELFILLUM); } -void CDynamicModelProvider::computeVisibility(const IXFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference) +void CDynamicModelProvider::computeVisibility(const IXFrustum *pFrustum, const float3 &vHintDir, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference) { void **ppData; - UINT uCount = m_pOpaqueQuery->execute(pFrustum, &ppData); + UINT uCount = m_pOpaqueQuery->execute(pFrustum, vHintDir, &ppData); pVisibility->setRenderList(ppData, uCount); - uCount = m_pSelfillumQuery->execute(pFrustum, &ppData); + uCount = m_pSelfillumQuery->execute(pFrustum, vHintDir, &ppData); pVisibility->setSelfillumList(ppData, uCount); - uCount = m_pTransparentQuery->execute(pFrustum, &ppData); + uCount = m_pTransparentQuery->execute(pFrustum, vHintDir, &ppData); pVisibility->setTransparentList(ppData, uCount); { diff --git a/source/anim/DynamicModelProvider.h b/source/anim/DynamicModelProvider.h index 957cfb47d596f4218b835c1e3f9c3c2c1529c17d..97488fa5291039a49e31ab51db0f740e66a69e8d 100644 --- a/source/anim/DynamicModelProvider.h +++ b/source/anim/DynamicModelProvider.h @@ -45,7 +45,7 @@ public: void render(bool isTransparent, CRenderableVisibility *pVisibility = NULL); void renderEmissive(CRenderableVisibility *pVisibility); - void computeVisibility(const IXFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference=NULL); + void computeVisibility(const IXFrustum *pFrustum, const float3 &vHintDir, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference=NULL); void render(Array<CDynamicModel*> &aRenderList, XMODEL_FEATURE bmWhat); diff --git a/source/anim/RenderableVisibility.cpp b/source/anim/RenderableVisibility.cpp index 6f9b472157f3a0047cfa26f670ce91ed95a5ced2..90f1d2caa1207747b8d42c3e1888d37ee5a3e265 100644 --- a/source/anim/RenderableVisibility.cpp +++ b/source/anim/RenderableVisibility.cpp @@ -22,8 +22,16 @@ void CRenderableVisibility::setOcclusionCuller(IXOcclusionCuller *pOcclusionCull void CRenderableVisibility::updateForCamera(ICamera *pCamera, const IXRenderableVisibility *pReference) { + CRenderableVisibility *pRef = NULL; + if(pReference) + { + assert(((IXRenderableVisibility*)pReference)->getPluginId() == getPluginId()); + pRef = (CRenderableVisibility*)pReference; + } + IXFrustum *pFrustum = pCamera->getFrustum(); - updateForFrustum(pFrustum, pReference); + m_pProviderAnimated->computeVisibility(pFrustum, this, pRef); + m_pProviderDynamic->computeVisibility(pFrustum, pCamera->getLook(), this, pRef); mem_release(pFrustum); } @@ -37,7 +45,7 @@ void CRenderableVisibility::updateForFrustum(const IXFrustum *pFrustum, const IX } m_pProviderAnimated->computeVisibility(pFrustum, this, pRef); - m_pProviderDynamic->computeVisibility(pFrustum, this, pRef); + m_pProviderDynamic->computeVisibility(pFrustum, float3(), this, pRef); } static void SortRenderList(Array<CDynamicModel*> &aList) diff --git a/source/render/Scene.cpp b/source/render/Scene.cpp index eda1ea18254017749d4e0193c8802307cd6d607d..667f057cd01690f3806b2ad9a3ce4b3fc2bb920a 100644 --- a/source/render/Scene.cpp +++ b/source/render/Scene.cpp @@ -86,6 +86,25 @@ void XMETHODCALLTYPE CSceneObject::setFeatures(IXSceneFeature **ppFeatures) //########################################################################## +static const UINT gcs_puOrders[][BVH_CHILD_COUNT] = { + // +x +y +z + {13, 4, 10, 12, 1, 3, 9, 14, 16, 22, 0, 5, 7, 11, 15, 19, 21, 2, 6, 17, 18, 23, 25, 8, 20, 24, 26}, + // +x +y -z + {22, 4, 19, 21, 1, 3, 13, 18, 23, 25, 0, 5, 7, 10, 12, 20, 24, 2, 6, 9, 14, 16, 26, 8, 11, 15, 17}, + // +x -y +z + {16, 7, 10, 15, 1, 6, 9, 13, 17, 25, 0, 4, 8, 11, 12, 19, 24, 2, 3, 14, 18, 22, 26, 5, 20, 21, 23}, + // +x -y -z + {25, 7, 19, 24, 1, 6, 16, 18, 22, 26, 0, 4, 8, 10, 15, 20, 21, 2, 3, 9, 13, 17, 23, 5, 11, 12, 14}, + // -x +y +z + {14, 5, 11, 12, 2, 3, 9, 13, 17, 23, 0, 4, 8, 10, 15, 20, 21, 1, 6, 16, 18, 22, 26, 7, 19, 24, 25}, + // -x +y -z + {23, 5, 20, 21, 2, 3, 14, 18, 22, 26, 0, 4, 8, 11 ,12, 19, 24, 1, 6, 9, 13, 17, 25, 7, 10, 15, 16}, + // -x -y +z + {17, 8, 11, 15, 2, 6, 9, 14, 16, 26, 0, 5, 7, 10, 12, 20, 24, 1, 3, 13, 18, 23, 25, 4, 19, 21, 22}, + // -x -y -z + {26, 8, 20, 24, 2, 6, 17, 18, 23, 25, 0, 5, 7, 11, 15, 19, 21, 1, 3, 9, 14, 16, 22, 4, 10, 12, 13} +}; + CSceneQuery::CSceneQuery(CScene *pScene, CSceneObjectType *pObjectType): m_pScene(pScene), m_bmType(pObjectType->getType()) @@ -95,8 +114,19 @@ CSceneQuery::~CSceneQuery() { } +UINT XMETHODCALLTYPE CSceneQuery::execute(const IXFrustum *pFrustum, const float3 &vDir, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller) +{ + pOrder = gcs_puOrders[(vDir.x < 0.0f ? 4 : 0) + (vDir.y < 0.0f ? 2 : 0) + (vDir.z < 0.0f ? 1 : 0)]; + + return(execute(pFrustum, pppObjects, pOcclusionCuller)); +} + UINT XMETHODCALLTYPE CSceneQuery::execute(const IXFrustum *pFrustum, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller) { + if(!pOrder) + { + pOrder = gcs_puOrders[0]; + } m_aQueryResponse.clearFast(); queryObjectsInternal(m_pScene->m_pRootNode, pFrustum); @@ -140,7 +170,7 @@ void CSceneQuery::queryObjectsInternal(CSceneNode *pNode, const IXFrustum *pFrus for(UINT i = 0; i < BVH_CHILD_COUNT; ++i) { - queryObjectsInternal(pNode->getChild(i, false), pFrustum, isFullyVisible); + queryObjectsInternal(pNode->getChild(pOrder[i], false), pFrustum, isFullyVisible); } auto &aObjects = pNode->getObjects(); diff --git a/source/render/Scene.h b/source/render/Scene.h index 1e3ac2249065a23ba13cf72149f44b2a485d9d00..abd4d5848f3f75d132a7e2406367f8a3f42e3d8f 100644 --- a/source/render/Scene.h +++ b/source/render/Scene.h @@ -88,6 +88,7 @@ public: ~CSceneQuery(); UINT XMETHODCALLTYPE execute(const IXFrustum *pFrustum, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller = NULL) override; + UINT XMETHODCALLTYPE execute(const IXFrustum *pFrustum, const float3 &vDir, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller = NULL) override; void XMETHODCALLTYPE setOP(XSCENE_QUERY_OP op) override; @@ -102,6 +103,8 @@ private: NodeFeature m_bmSet = 0; NodeFeature m_bmUnset = 0; + const UINT *pOrder = NULL; + void queryObjectsInternal(CSceneNode *pNode, const IXFrustum *pFrustum, bool isFullyVisible = false, IXOcclusionCuller *pOcclusionCuller = NULL); bool testFeatures(NodeFeature bmFeatures, bool isStrict = true); }; diff --git a/source/xcommon/IXScene.h b/source/xcommon/IXScene.h index 14e50abf1199a6902176db222a95bb267d3c198d..a424ebe7879c5bdae23c2e1ff90c56d63b9c1a80 100644 --- a/source/xcommon/IXScene.h +++ b/source/xcommon/IXScene.h @@ -66,6 +66,14 @@ public: */ virtual UINT XMETHODCALLTYPE execute(const IXFrustum *pFrustum, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller = NULL) = 0; + /*! + Выполняет запрос, возвращает количество найденных объектов, + в pppObjects записывается указатель на массив пользовательских указателей найденных объектов + в vDir задается предпочтительное направление обхода (данное направление лишь подсказка, но не руководство к действию) + @threadsafe sync + */ + virtual UINT XMETHODCALLTYPE execute(const IXFrustum *pFrustum, const float3 &vDir, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller = NULL) = 0; + /*! Устанавливает операцию выборки @threadsafe none