mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-17 00:47:05 +00:00
Added CSceneIterator and implemented support for Select All/Invert Selection
This commit is contained in:
@@ -31,7 +31,7 @@ CModelNode* CScene::CreateModelNode(CModel *pModel)
|
||||
if (pModel == nullptr) return nullptr;
|
||||
|
||||
CModelNode *pNode = new CModelNode(this, mpSceneRootNode, pModel);
|
||||
mNodes[eShowObjects].push_back(pNode);
|
||||
mNodes[eModelNode].push_back(pNode);
|
||||
mNumNodes++;
|
||||
return pNode;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ CStaticNode* CScene::CreateStaticNode(CStaticModel *pModel)
|
||||
if (pModel == nullptr) return nullptr;
|
||||
|
||||
CStaticNode *pNode = new CStaticNode(this, mpAreaRootNode, pModel);
|
||||
mNodes[eShowWorld].push_back(pNode);
|
||||
mNodes[eStaticNode].push_back(pNode);
|
||||
mNumNodes++;
|
||||
return pNode;
|
||||
}
|
||||
@@ -51,7 +51,7 @@ CCollisionNode* CScene::CreateCollisionNode(CCollisionMeshGroup *pMesh)
|
||||
if (pMesh == nullptr) return nullptr;
|
||||
|
||||
CCollisionNode *pNode = new CCollisionNode(this, mpAreaRootNode, pMesh);
|
||||
mNodes[eShowWorldCollision].push_back(pNode);
|
||||
mNodes[eCollisionNode].push_back(pNode);
|
||||
mNumNodes++;
|
||||
return pNode;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ CScriptNode* CScene::CreateScriptNode(CScriptObject *pObj)
|
||||
if (pObj == nullptr) return nullptr;
|
||||
|
||||
CScriptNode *pNode = new CScriptNode(this, mpAreaRootNode, pObj);
|
||||
mNodes[eShowObjects].push_back(pNode);
|
||||
mNodes[eScriptNode].push_back(pNode);
|
||||
mNumNodes++;
|
||||
return pNode;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ CLightNode* CScene::CreateLightNode(CLight *pLight)
|
||||
if (pLight == nullptr) return nullptr;
|
||||
|
||||
CLightNode *pNode = new CLightNode(this, mpAreaRootNode, pLight);
|
||||
mNodes[eShowLights].push_back(pNode);
|
||||
mNodes[eLightNode].push_back(pNode);
|
||||
mNumNodes++;
|
||||
return pNode;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||
{
|
||||
CScriptLayer *pLayer = mpArea->GetScriptLayer(iLyr);
|
||||
u32 NumObjects = pLayer->GetNumObjects();
|
||||
mNodes[eShowObjects].reserve(mNodes[eShowObjects].size() + NumObjects);
|
||||
mNodes[eScriptNode].reserve(mNodes[eScriptNode].size() + NumObjects);
|
||||
|
||||
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
||||
{
|
||||
@@ -202,10 +202,11 @@ void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
{
|
||||
// Override show flags in game mode
|
||||
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
||||
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
||||
|
||||
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
|
||||
{
|
||||
if (ShowFlags & it->first)
|
||||
if (NodeFlags & it->first)
|
||||
{
|
||||
std::vector<CSceneNode*>& rNodeVec = it->second;
|
||||
|
||||
@@ -219,11 +220,12 @@ void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
SRayIntersection CScene::SceneRayCast(const CRay& Ray, const SViewInfo& ViewInfo)
|
||||
{
|
||||
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
||||
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
||||
CRayCollisionTester Tester(Ray);
|
||||
|
||||
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
|
||||
{
|
||||
if (ShowFlags & it->first)
|
||||
if (NodeFlags & it->first)
|
||||
{
|
||||
std::vector<CSceneNode*>& rNodeVec = it->second;
|
||||
|
||||
@@ -252,7 +254,7 @@ CScriptNode* CScene::NodeForObject(CScriptObject *pObj)
|
||||
CLightNode* CScene::NodeForLight(CLight *pLight)
|
||||
{
|
||||
// Slow. Is there a better way to do this?
|
||||
std::vector<CSceneNode*>& rLights = mNodes[eShowLights];
|
||||
std::vector<CSceneNode*>& rLights = mNodes[eLightNode];
|
||||
|
||||
for (auto it = rLights.begin(); it != rLights.end(); it++)
|
||||
{
|
||||
@@ -291,3 +293,24 @@ CGameArea* CScene::GetActiveArea()
|
||||
{
|
||||
return mpArea;
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
FShowFlags CScene::ShowFlagsForNodeFlags(FNodeFlags NodeFlags)
|
||||
{
|
||||
FShowFlags Out;
|
||||
if (NodeFlags & eStaticNode) Out |= eShowWorld;
|
||||
if (NodeFlags & eScriptNode) Out |= eShowObjects;
|
||||
if (NodeFlags & eCollisionNode) Out |= eShowWorldCollision;
|
||||
if (NodeFlags & eLightNode) Out |= eShowLights;
|
||||
return Out;
|
||||
}
|
||||
|
||||
FNodeFlags CScene::NodeFlagsForShowFlags(FShowFlags ShowFlags)
|
||||
{
|
||||
FNodeFlags Out = eRootNode | eModelNode;
|
||||
if (ShowFlags & eShowWorld) Out |= eStaticNode;
|
||||
if (ShowFlags & eShowWorldCollision) Out |= eCollisionNode;
|
||||
if (ShowFlags & eShowObjects) Out |= eScriptNode | eScriptExtraNode;
|
||||
if (ShowFlags & eShowLights) Out |= eLightNode;
|
||||
return Out;
|
||||
}
|
||||
|
||||
@@ -22,11 +22,13 @@
|
||||
|
||||
class CScene
|
||||
{
|
||||
friend class CSceneIterator;
|
||||
|
||||
bool mSplitTerrain;
|
||||
|
||||
u32 mNumNodes;
|
||||
CRootNode *mpSceneRootNode;
|
||||
std::unordered_map<EShowFlag, std::vector<CSceneNode*>> mNodes;
|
||||
std::unordered_map<ENodeType, std::vector<CSceneNode*>> mNodes;
|
||||
|
||||
TResPtr<CGameArea> mpArea;
|
||||
TResPtr<CWorld> mpWorld;
|
||||
@@ -60,6 +62,10 @@ public:
|
||||
// Setters/Getters
|
||||
CModel* GetActiveSkybox();
|
||||
CGameArea* GetActiveArea();
|
||||
|
||||
// Static
|
||||
static FShowFlags ShowFlagsForNodeFlags(FNodeFlags NodeFlags);
|
||||
static FNodeFlags NodeFlagsForShowFlags(FShowFlags ShowFlags);
|
||||
};
|
||||
|
||||
#endif // CSCENE_H
|
||||
|
||||
72
src/Core/Scene/CSceneIterator.cpp
Normal file
72
src/Core/Scene/CSceneIterator.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "CSceneIterator.h"
|
||||
#include "CScene.h"
|
||||
|
||||
CSceneIterator::CSceneIterator(CScene *pScene, FNodeFlags AllowedNodeTypes /*= eAllNodeTypes*/, bool AllowHiddenNodes /*= false*/)
|
||||
: mpScene(pScene)
|
||||
, mAllowHiddenNodes(AllowHiddenNodes)
|
||||
, mNodeFlags(AllowedNodeTypes)
|
||||
, mpCurNode(nullptr)
|
||||
{
|
||||
mMapIterator = mpScene->mNodes.begin();
|
||||
|
||||
while (mMapIterator != mpScene->mNodes.end())
|
||||
{
|
||||
if (mMapIterator->first & AllowedNodeTypes)
|
||||
break;
|
||||
|
||||
mMapIterator++;
|
||||
}
|
||||
|
||||
if (mMapIterator != mpScene->mNodes.end())
|
||||
{
|
||||
mVectorIterator = (mMapIterator->second).begin();
|
||||
Next(); // Find first node
|
||||
}
|
||||
}
|
||||
|
||||
// ************ PROTECTED ************
|
||||
void CSceneIterator::InternalFindNext()
|
||||
{
|
||||
// This function does most of the heavy lifting. We continue from where we left off last time this function was called.
|
||||
while (mMapIterator != mpScene->mNodes.end())
|
||||
{
|
||||
// Iterate over each node in the vector.
|
||||
std::vector<CSceneNode*>& rVector = mMapIterator->second;
|
||||
bool FoundNext = false;
|
||||
|
||||
while (mVectorIterator != rVector.end())
|
||||
{
|
||||
CSceneNode *pNode = *mVectorIterator;
|
||||
|
||||
// Check node visibility
|
||||
if (mAllowHiddenNodes || pNode->IsVisible())
|
||||
{
|
||||
mpCurNode = pNode;
|
||||
FoundNext = true;
|
||||
}
|
||||
|
||||
mVectorIterator++;
|
||||
if (FoundNext) return;
|
||||
}
|
||||
|
||||
// We've reached the end of this node vector, so advance the map iterator
|
||||
while (true)
|
||||
{
|
||||
mMapIterator++;
|
||||
|
||||
if (mMapIterator == mpScene->mNodes.end())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (mNodeFlags & mMapIterator->first)
|
||||
{
|
||||
mVectorIterator = mMapIterator->second.begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're down here, then it seems we're done iterating the scene.
|
||||
mpCurNode = nullptr;
|
||||
}
|
||||
66
src/Core/Scene/CSceneIterator.h
Normal file
66
src/Core/Scene/CSceneIterator.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef CSCENEITERATOR_H
|
||||
#define CSCENEITERATOR_H
|
||||
|
||||
#include "ENodeType.h"
|
||||
#include <unordered_map>
|
||||
|
||||
class CScene;
|
||||
class CSceneNode;
|
||||
|
||||
class CSceneIterator
|
||||
{
|
||||
CScene *mpScene;
|
||||
bool mAllowHiddenNodes;
|
||||
FNodeFlags mNodeFlags;
|
||||
|
||||
CSceneNode *mpCurNode;
|
||||
std::unordered_map<ENodeType, std::vector<CSceneNode*>>::iterator mMapIterator;
|
||||
std::vector<CSceneNode*>::iterator mVectorIterator;
|
||||
|
||||
public:
|
||||
CSceneIterator(CScene *pScene, FNodeFlags AllowedNodeTypes = eAllNodeTypes, bool AllowHiddenNodes = false);
|
||||
|
||||
inline CSceneNode* Next()
|
||||
{
|
||||
InternalFindNext();
|
||||
return mpCurNode;
|
||||
}
|
||||
|
||||
inline bool DoneIterating() const
|
||||
{
|
||||
return (mpCurNode == nullptr);
|
||||
}
|
||||
|
||||
inline CSceneNode* GetNode() const
|
||||
{
|
||||
return mpCurNode;
|
||||
}
|
||||
|
||||
inline CSceneNode* operator*() const
|
||||
{
|
||||
return mpCurNode;
|
||||
}
|
||||
|
||||
inline CSceneNode* operator->() const
|
||||
{
|
||||
return mpCurNode;
|
||||
}
|
||||
|
||||
inline CSceneIterator& operator++()
|
||||
{
|
||||
Next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CSceneIterator operator++(int)
|
||||
{
|
||||
CSceneIterator Copy = *this;
|
||||
Next();
|
||||
return Copy;
|
||||
}
|
||||
|
||||
protected:
|
||||
void InternalFindNext();
|
||||
};
|
||||
|
||||
#endif // CSCENEITERATOR_H
|
||||
@@ -1,16 +1,21 @@
|
||||
#ifndef ENODETYPE_H
|
||||
#define ENODETYPE_H
|
||||
|
||||
#include <Common/Flags.h>
|
||||
|
||||
enum ENodeType
|
||||
{
|
||||
eRootNode,
|
||||
eModelNode,
|
||||
eStaticNode,
|
||||
eCollisionNode,
|
||||
eScriptNode,
|
||||
eScriptExtraNode,
|
||||
eLightNode
|
||||
eRootNode = 0x0,
|
||||
eModelNode = 0x1,
|
||||
eStaticNode = 0x2,
|
||||
eCollisionNode = 0x4,
|
||||
eScriptNode = 0x8,
|
||||
eScriptExtraNode = 0x10,
|
||||
eLightNode = 0x20,
|
||||
eAllNodeTypes = 0x3F
|
||||
};
|
||||
|
||||
DECLARE_FLAGS(ENodeType, FNodeFlags)
|
||||
|
||||
#endif // ENODETYPE_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user