Moved selection handling code to CNodeSelection, implemented instance spawning, half-implemented instance deleting (this build is buggy/crash prone)

This commit is contained in:
parax0
2016-03-13 22:30:04 -06:00
parent b2699eb96f
commit f02f7ada0f
64 changed files with 1259 additions and 754 deletions

View File

@@ -15,6 +15,8 @@ public:
bool IsLayerEnabled() const;
bool IsSkyEnabled() const;
CModel* SkyModel() const;
inline CScriptObject* Instance() const { return mpObj; }
};
#endif // CAREAATTRIBUTES_H

View File

@@ -2,23 +2,25 @@
#include "Core/Resource/Script/CScriptLayer.h"
#include "Core/Render/CRenderer.h"
CGameArea::CGameArea() : CResource()
CGameArea::CGameArea()
: CResource()
, mWorldIndex(-1)
, mVertexCount(0)
, mTriangleCount(0)
, mTerrainMerged(false)
, mOriginalWorldMeshCount(0)
, mUsesCompression(false)
, mMaterialSet(nullptr)
, mpGeneratorLayer(nullptr)
, mpCollision(nullptr)
{
mVertexCount = 0;
mTriangleCount = 0;
mTerrainMerged = false;
mOriginalWorldMeshCount = 0;
mUsesCompression = false;
mMaterialSet = nullptr;
mpGeneratorLayer = nullptr;
mCollision = nullptr;
}
CGameArea::~CGameArea()
{
ClearTerrain();
delete mCollision;
delete mpCollision;
delete mpGeneratorLayer;
for (u32 iSCLY = 0; iSCLY < mScriptLayers.size(); iSCLY++)
@@ -108,85 +110,109 @@ void CGameArea::ClearScriptLayers()
mpGeneratorLayer = nullptr;
}
EGame CGameArea::Version()
u32 CGameArea::TotalInstanceCount() const
{
return mVersion;
u32 Num = 0;
for (u32 iLyr = 0; iLyr < mScriptLayers.size(); iLyr++)
Num += mScriptLayers[iLyr]->NumInstances();
return Num;
}
CTransform4f CGameArea::GetTransform()
{
return mTransform;
}
u32 CGameArea::GetTerrainModelCount()
{
return mTerrainModels.size();
}
u32 CGameArea::GetStaticModelCount()
{
return mStaticTerrainModels.size();
}
CModel* CGameArea::GetTerrainModel(u32 mdl)
{
return mTerrainModels[mdl];
}
CStaticModel* CGameArea::GetStaticModel(u32 mdl)
{
return mStaticTerrainModels[mdl];
}
CCollisionMeshGroup* CGameArea::GetCollision()
{
return mCollision;
}
u32 CGameArea::GetScriptLayerCount()
{
return mScriptLayers.size();
}
CScriptLayer* CGameArea::GetScriptLayer(u32 index)
{
return mScriptLayers[index];
}
CScriptLayer* CGameArea::GetGeneratorLayer()
{
return mpGeneratorLayer;
}
CScriptObject* CGameArea::GetInstanceByID(u32 InstanceID)
CScriptObject* CGameArea::InstanceByID(u32 InstanceID)
{
auto it = mObjectMap.find(InstanceID);
if (it != mObjectMap.end()) return it->second;
else return nullptr;
}
u32 CGameArea::GetLightLayerCount()
CScriptObject* CGameArea::SpawnInstance(CScriptTemplate *pTemplate,
CScriptLayer *pLayer,
const CVector3f& rkPosition /*= CVector3f::skZero*/,
const CQuaternion& rkRotation /*= CQuaternion::skIdentity*/,
const CVector3f& rkScale /*= CVector3f::skOne*/,
u32 SuggestedID /*= -1*/,
u32 SuggestedLayerIndex /*= -1*/ )
{
return mLightLayers.size();
// Verify we can fit another instance in this area.
u32 NumInstances = TotalInstanceCount();
if (NumInstances >= 0xFFFF)
{
Log::Error("Unable to spawn a new script instance; too many instances in area (" + TString::FromInt32(NumInstances, 0, 10) + ")");
return nullptr;
}
// Check whether the suggested instance ID is valid
u32 InstanceID = SuggestedID;
if (InstanceID != -1)
{
if (mObjectMap.find(InstanceID) == mObjectMap.end())
InstanceID = -1;
}
// If not valid (or if there's no suggested ID) then determine a new instance ID
if (InstanceID == -1)
{
// Determine layer index
u32 LayerIndex = -1;
for (u32 iLyr = 0; iLyr < mScriptLayers.size(); iLyr++)
{
if (mScriptLayers[iLyr] == pLayer)
{
LayerIndex = iLyr;
break;
}
}
if (LayerIndex == -1)
{
Log::Error("Unable to spawn a new script instance; invalid script layer passed in");
return nullptr;
}
// Look for a valid instance ID
InstanceID = (LayerIndex << 26) | (mWorldIndex << 16) | 1;
while (true)
{
auto it = mObjectMap.find(InstanceID);
if (it == mObjectMap.end())
break;
else
InstanceID++;
}
}
// Spawn instance
CScriptObject *pInstance = new CScriptObject(InstanceID, this, pLayer, pTemplate);
pInstance->EvaluateProperties();
pInstance->SetPosition(rkPosition);
pInstance->SetRotation(rkRotation.ToEuler());
pInstance->SetScale(rkScale);
pInstance->SetName(pTemplate->Name());
if (pTemplate->Game() < eEchoesDemo) pInstance->SetActive(true);
pLayer->AddInstance(pInstance, SuggestedLayerIndex);
mObjectMap[InstanceID] = pInstance;
return pInstance;
}
u32 CGameArea::GetLightCount(u32 layer)
void CGameArea::DeleteInstance(CScriptObject *pInstance)
{
if (mLightLayers.empty()) return 0;
return mLightLayers[layer].size();
}
pInstance->Layer()->RemoveInstance(pInstance);
pInstance->Template()->RemoveObject(pInstance);
CLight* CGameArea::GetLight(u32 layer, u32 light)
{
return mLightLayers[layer][light];
}
auto it = mObjectMap.find(pInstance->InstanceID());
if (it != mObjectMap.end()) mObjectMap.erase(it);
CPoiToWorld* CGameArea::GetPoiToWorldMap()
{
return mpPoiToWorldMap;
}
if (mpPoiToWorldMap && mpPoiToWorldMap->HasPoiMappings(pInstance->InstanceID()))
mpPoiToWorldMap->RemovePoi(pInstance->InstanceID());
CAABox CGameArea::AABox()
{
return mAABox;
pInstance->BreakAllLinks();
delete pInstance;
}

View File

@@ -9,12 +9,14 @@
#include "Core/Resource/Model/CModel.h"
#include "Core/Resource/Model/CStaticModel.h"
#include <Common/types.h>
#include <Math/CQuaternion.h>
#include <Math/CTransform4f.h>
#include <unordered_map>
class CScriptLayer;
class CScriptObject;
class CScriptTemplate;
class CGameArea : public CResource
{
@@ -23,6 +25,7 @@ class CGameArea : public CResource
friend class CAreaCooker;
EGame mVersion;
u32 mWorldIndex;
u32 mVertexCount;
u32 mTriangleCount;
bool mTerrainMerged;
@@ -50,7 +53,7 @@ class CGameArea : public CResource
CScriptLayer *mpGeneratorLayer;
std::unordered_map<u32, CScriptObject*> mObjectMap;
// Collision
CCollisionMeshGroup *mCollision;
CCollisionMeshGroup *mpCollision;
// Lights
std::vector<std::vector<CLight*>> mLightLayers;
// Object to Static Geometry Map
@@ -64,24 +67,34 @@ public:
void MergeTerrain();
void ClearTerrain();
void ClearScriptLayers();
u32 TotalInstanceCount() const;
CScriptObject* InstanceByID(u32 InstanceID);
CScriptObject* SpawnInstance(CScriptTemplate *pTemplate, CScriptLayer *pLayer,
const CVector3f& rkPosition = CVector3f::skZero,
const CQuaternion& rkRotation = CQuaternion::skIdentity,
const CVector3f& rkScale = CVector3f::skOne,
u32 SuggestedID = -1, u32 SuggestedLayerIndex = -1);
void DeleteInstance(CScriptObject *pInstance);
// Getters
EGame Version();
CTransform4f GetTransform();
u32 GetTerrainModelCount();
u32 GetStaticModelCount();
CModel* GetTerrainModel(u32 mdl);
CStaticModel* GetStaticModel(u32 mdl);
CCollisionMeshGroup* GetCollision();
u32 GetScriptLayerCount();
CScriptLayer* GetScriptLayer(u32 index);
CScriptLayer* GetGeneratorLayer();
CScriptObject* GetInstanceByID(u32 InstanceID);
u32 GetLightLayerCount();
u32 GetLightCount(u32 layer);
CLight* GetLight(u32 layer, u32 light);
CPoiToWorld* GetPoiToWorldMap();
CAABox AABox();
// Inline Accessors
inline EGame Version() const { return mVersion; }
inline u32 WorldIndex() const { return mWorldIndex; }
inline CTransform4f GetTransform() const { return mTransform; }
inline u32 GetTerrainModelCount() const { return mTerrainModels.size(); }
inline u32 GetStaticModelCount() const { return mStaticTerrainModels.size(); }
inline CModel* GetTerrainModel(u32 iMdl) const { return mTerrainModels[iMdl]; }
inline CStaticModel* GetStaticModel(u32 iMdl) const { return mStaticTerrainModels[iMdl]; }
inline CCollisionMeshGroup* GetCollision() const { return mpCollision; }
inline u32 GetScriptLayerCount() const { return mScriptLayers.size(); }
inline CScriptLayer* GetScriptLayer(u32 Index) const { return mScriptLayers[Index]; }
inline CScriptLayer* GetGeneratorLayer() const { return mpGeneratorLayer; }
inline u32 GetLightLayerCount() const { return mLightLayers.size(); }
inline u32 GetLightCount(u32 LayerIndex) const { return (LayerIndex < mLightLayers.size() ? mLightLayers[LayerIndex].size() : 0); }
inline CLight* GetLight(u32 LayerIndex, u32 LightIndex) const { return mLightLayers[LayerIndex][LightIndex]; }
inline CPoiToWorld* GetPoiToWorldMap() const { return mpPoiToWorldMap; }
inline CAABox AABox() const { return mAABox; }
inline void SetWorldIndex(u32 NewWorldIndex) { mWorldIndex = NewWorldIndex; }
};
#endif // CGAMEAREA_H

View File

@@ -39,6 +39,22 @@ public:
{
return mMaps[Index];
}
inline const SPoiMap* MapByID(u32 InstanceID) const
{
auto it = mPoiLookupMap.find(InstanceID);
if (it != mPoiLookupMap.end())
return it->second;
else
return nullptr;
}
bool HasPoiMappings(u32 InstanceID) const
{
auto it = mPoiLookupMap.find(InstanceID);
return (it != mPoiLookupMap.end());
}
};
#endif // CPOITOWORLD_H

View File

@@ -31,7 +31,7 @@ public:
inline CUniqueID ID() const
{
TString FileName = mPath.GetFileName();
TString FileName = mPath.GetFileName(false);
if (!mIsPath)
return CUniqueID::FromString(FileName);

View File

@@ -16,12 +16,12 @@ CWorld::~CWorld()
{
}
void CWorld::SetAreaLayerInfo(CGameArea *pArea, u32 AreaIndex)
void CWorld::SetAreaLayerInfo(CGameArea *pArea)
{
// The AreaIndex parameter is a placeholder until an improved world loader is implemented.
// For now it's the easiest/fastest way to do this because this function is called from
// the start window and the start window already knows the area index.
SArea& AreaInfo = mAreas[AreaIndex];
SArea& AreaInfo = mAreas[pArea->WorldIndex()];
for (u32 iLyr = 0; iLyr < pArea->GetScriptLayerCount(); iLyr++)
{

View File

@@ -84,7 +84,7 @@ public:
CWorld();
~CWorld();
void SetAreaLayerInfo(CGameArea *pArea, u32 AreaIndex);
void SetAreaLayerInfo(CGameArea *pArea);
// Setters
EGame Version();

View File

@@ -595,7 +595,7 @@ void CAreaLoader::ReadCollision()
{
Log::FileWrite(mpMREA->GetSourceString(), "Reading collision (MP1/MP2/MP3)");
mpSectionMgr->ToSection(mCollisionBlockNum);
mpArea->mCollision = CCollisionLoader::LoadAreaCollision(*mpMREA);
mpArea->mpCollision = CCollisionLoader::LoadAreaCollision(*mpMREA);
}
void CAreaLoader::ReadEGMC()
@@ -643,7 +643,7 @@ void CAreaLoader::SetUpObjects()
if (iConMap != mConnectionMap.end())
{
CScriptObject *pObj = mpArea->GetInstanceByID(InstanceID);
CScriptObject *pObj = mpArea->InstanceByID(InstanceID);
pObj->mInLinks = iConMap->second;
}
}

View File

@@ -214,8 +214,8 @@ CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& SCLY)
return nullptr;
}
mpObj = new CScriptObject(mpArea, mpLayer, pTemp);
mpObj->mInstanceID = SCLY.ReadLong();
u32 InstanceID = SCLY.ReadLong();
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemp);
// Load connections
u32 NumLinks = SCLY.ReadLong();
@@ -249,7 +249,7 @@ CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream &SCLY)
SCLY.Seek(0x1, SEEK_CUR); // One unknown byte at the start of each layer
u32 NumObjects = SCLY.ReadLong();
mpLayer = new CScriptLayer();
mpLayer = new CScriptLayer(mpArea);
mpLayer->Reserve(NumObjects);
for (u32 iObj = 0; iObj < NumObjects; iObj++)
@@ -327,8 +327,8 @@ CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& SCLY)
return nullptr;
}
mpObj = new CScriptObject(mpArea, mpLayer, pTemplate);
mpObj->mInstanceID = SCLY.ReadLong();
u32 InstanceID = SCLY.ReadLong();
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemplate);
// Load connections
u32 NumConnections = SCLY.ReadShort();
@@ -359,7 +359,7 @@ CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
SCLY.Seek(0x1, SEEK_CUR); // Skipping version. todo: verify this?
u32 NumObjects = SCLY.ReadLong();
mpLayer = new CScriptLayer();
mpLayer = new CScriptLayer(mpArea);
mpLayer->Reserve(NumObjects);
for (u32 iObj = 0; iObj < NumObjects; iObj++)
@@ -372,9 +372,10 @@ CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
return mpLayer;
}
CScriptLayer* CScriptLoader::LoadLayer(IInputStream &SCLY, CGameArea *pArea, EGame Version)
// ************ STATIC ************
CScriptLayer* CScriptLoader::LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EGame Version)
{
if (!SCLY.IsValid()) return nullptr;
if (!rSCLY.IsValid()) return nullptr;
CScriptLoader Loader;
Loader.mVersion = Version;
@@ -391,7 +392,7 @@ CScriptLayer* CScriptLoader::LoadLayer(IInputStream &SCLY, CGameArea *pArea, EGa
CTemplateLoader::LoadGameTemplates(Version);
if (Version <= ePrime)
return Loader.LoadLayerMP1(SCLY);
return Loader.LoadLayerMP1(rSCLY);
else
return Loader.LoadLayerMP2(SCLY);
return Loader.LoadLayerMP2(rSCLY);
}

View File

@@ -52,8 +52,8 @@ public:
void SetSender(u32 NewSenderID, u32 Index = -1)
{
u32 OldSenderID = mSenderID;
CScriptObject *pOldSender = mpArea->GetInstanceByID(OldSenderID);
CScriptObject *pNewSender = mpArea->GetInstanceByID(NewSenderID);
CScriptObject *pOldSender = mpArea->InstanceByID(OldSenderID);
CScriptObject *pNewSender = mpArea->InstanceByID(NewSenderID);
mSenderID = NewSenderID;
pOldSender->RemoveLink(eOutgoing, this);
@@ -63,8 +63,8 @@ public:
void SetReceiver(u32 NewReceiverID, u32 Index = -1)
{
u32 OldReceiverID = mSenderID;
CScriptObject *pOldReceiver = mpArea->GetInstanceByID(OldReceiverID);
CScriptObject *pNewReceiver = mpArea->GetInstanceByID(NewReceiverID);
CScriptObject *pOldReceiver = mpArea->InstanceByID(OldReceiverID);
CScriptObject *pNewReceiver = mpArea->InstanceByID(NewReceiverID);
mReceiverID = NewReceiverID;
pOldReceiver->RemoveLink(eIncoming, this);
@@ -73,7 +73,7 @@ public:
u32 SenderIndex() const
{
CScriptObject *pSender = mpArea->GetInstanceByID(mSenderID);
CScriptObject *pSender = mpArea->InstanceByID(mSenderID);
for (u32 iLink = 0; iLink < pSender->NumLinks(eOutgoing); iLink++)
{
@@ -86,7 +86,7 @@ public:
u32 ReceiverIndex() const
{
CScriptObject *pReceiver = mpArea->GetInstanceByID(mReceiverID);
CScriptObject *pReceiver = mpArea->InstanceByID(mReceiverID);
for (u32 iLink = 0; iLink < pReceiver->NumLinks(eIncoming); iLink++)
{
@@ -117,8 +117,8 @@ public:
u32 Message() const { return mMessageID; }
u32 SenderID() const { return mSenderID; }
u32 ReceiverID() const { return mReceiverID; }
CScriptObject* Sender() const { return mpArea->GetInstanceByID(mSenderID); }
CScriptObject* Receiver() const { return mpArea->GetInstanceByID(mReceiverID); }
CScriptObject* Sender() const { return mpArea->InstanceByID(mSenderID); }
CScriptObject* Receiver() const { return mpArea->InstanceByID(mReceiverID); }
void SetState(u32 StateID) { mStateID = StateID; }
void SetMessage(u32 MessageID) { mMessageID = MessageID; }

View File

@@ -8,13 +8,15 @@
class CScriptLayer
{
CGameArea *mpArea;
TString mLayerName;
bool mActive;
bool mVisible;
std::vector<CScriptObject*> mInstances;
public:
CScriptLayer()
: mLayerName("New Layer")
CScriptLayer(CGameArea *pArea)
: mpArea(pArea)
, mLayerName("New Layer")
, mActive(true)
, mVisible(true)
{
@@ -27,9 +29,17 @@ public:
}
// Data Manipulation
void AddInstance(CScriptObject *pObject)
void AddInstance(CScriptObject *pObject, u32 Index = -1)
{
mInstances.push_back(pObject);
if (Index != -1 && Index < mInstances.size())
{
auto it = mInstances.begin();
std::advance(it, Index);
mInstances.insert(it, pObject);
}
else
mInstances.push_back(pObject);
}
void RemoveInstance(CScriptObject *pInstance)
@@ -67,6 +77,7 @@ public:
}
// Accessors
inline CGameArea* Area() const { return mpArea; }
inline TString Name() const { return mLayerName; }
inline bool IsActive() const { return mActive; }
inline bool IsVisible() const { return mVisible; }
@@ -88,6 +99,17 @@ public:
inline void SetActive(bool Active) { mActive = Active; }
inline void SetVisible(bool Visible) { mVisible = Visible; }
inline u32 AreaIndex() const
{
for (u32 iLyr = 0; iLyr < mpArea->GetScriptLayerCount(); iLyr++)
{
if (mpArea->GetScriptLayer(iLyr) == this)
return iLyr;
}
return -1;
}
// Operators
CScriptObject* operator[](u32 Index) { return InstanceByIndex(Index); }
};

View File

@@ -3,11 +3,12 @@
#include "CMasterTemplate.h"
#include "Core/Resource/CAnimSet.h"
CScriptObject::CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate)
CScriptObject::CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate)
: mpTemplate(pTemplate)
, mpArea(pArea)
, mpLayer(pLayer)
, mVersion(0)
, mInstanceID(InstanceID)
, mpDisplayModel(nullptr)
, mpCollision(nullptr)
, mHasInGameModel(false)
@@ -75,16 +76,27 @@ bool CScriptObject::IsEditorProperty(IProperty *pProp)
);
}
void CScriptObject::SetLayer(CScriptLayer *pLayer)
void CScriptObject::SetLayer(CScriptLayer *pLayer, u32 NewLayerIndex)
{
if (pLayer != mpLayer)
{
mpLayer->RemoveInstance(this);
mpLayer = pLayer;
mpLayer->AddInstance(this);
mpLayer->AddInstance(this, NewLayerIndex);
}
}
u32 CScriptObject::LayerIndex() const
{
for (u32 iInst = 0; iInst < mpLayer->NumInstances(); iInst++)
{
if (mpLayer->InstanceByIndex(iInst) == this)
return iInst;
}
return -1;
}
bool CScriptObject::HasNearVisibleActivation() const
{
/* This function is used to check whether an inactive DKCR object should render in game mode. DKCR deactivates a lot of
@@ -240,6 +252,26 @@ void CScriptObject::RemoveLink(ELinkType Type, CLink *pLink)
}
}
void CScriptObject::BreakAllLinks()
{
for (auto it = mInLinks.begin(); it != mInLinks.end(); it++)
{
CLink *pLink = *it;
pLink->Sender()->RemoveLink(eOutgoing, pLink);
delete pLink;
}
for (auto it = mOutLinks.begin(); it != mOutLinks.end(); it++)
{
CLink *pLink = *it;
pLink->Receiver()->RemoveLink(eIncoming, pLink);
delete pLink;
}
mInLinks.clear();
mOutLinks.clear();
}
TString CScriptObject::InstanceName() const
{
if (mpInstanceName)

View File

@@ -50,7 +50,7 @@ class CScriptObject
mutable bool mIsCheckingNearVisibleActivation;
public:
CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate);
CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate);
~CScriptObject();
void EvaluateProperties();
@@ -59,7 +59,8 @@ public:
void EvaluateCollisionModel();
void EvaluateVolume();
bool IsEditorProperty(IProperty *pProp);
void SetLayer(CScriptLayer *pLayer);
void SetLayer(CScriptLayer *pLayer, u32 NewLayerIndex = -1);
u32 LayerIndex() const;
bool HasNearVisibleActivation() const;
CScriptTemplate* Template() const;
@@ -78,6 +79,7 @@ public:
CLink* Link(ELinkType Type, u32 Index) const;
void AddLink(ELinkType Type, CLink *pLink, u32 Index = -1);
void RemoveLink(ELinkType Type, CLink *pLink);
void BreakAllLinks();
CVector3f Position() const;
CVector3f Rotation() const;

View File

@@ -65,6 +65,18 @@ CScriptNode* CScene::CreateScriptNode(CScriptObject *pObj)
CScriptNode *pNode = new CScriptNode(this, mpAreaRootNode, pObj);
mNodes[eScriptNode].push_back(pNode);
mScriptNodeMap[pObj->InstanceID()] = pNode;
pNode->BuildLightList(mpArea);
// AreaAttributes check
switch (pObj->ObjectTypeID())
{
case 0x4E: // MP1 AreaAttributes ID
case 0x52454141: // MP2/MP3/DKCR AreaAttributes ID ("REAA")
mAreaAttributesObjects.emplace_back( CAreaAttributes(pObj) );
break;
}
mNumNodes++;
return pNode;
}
@@ -79,6 +91,48 @@ CLightNode* CScene::CreateLightNode(CLight *pLight)
return pNode;
}
void CScene::DeleteNode(CSceneNode *pNode)
{
ENodeType Type = pNode->NodeType();
for (auto it = mNodes[Type].begin(); it != mNodes[Type].end(); it++)
{
if (*it == pNode)
{
mNodes[Type].erase(it);
break;
}
}
if (Type == eScriptNode)
{
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
auto ScriptMapIt = mScriptNodeMap.find(pScript->Object()->InstanceID());
if (ScriptMapIt != mScriptNodeMap.end())
mScriptNodeMap.erase(ScriptMapIt);
switch (pScript->Object()->ObjectTypeID())
{
case 0x4E:
case 0x52454141:
for (auto it = mAreaAttributesObjects.begin(); it != mAreaAttributesObjects.end(); it++)
{
if ((*it).Instance() == pScript->Object())
{
mAreaAttributesObjects.erase(it);
break;
}
}
break;
}
}
pNode->Unparent();
delete pNode;
mNumNodes--;
}
void CScene::SetActiveArea(CGameArea *pArea)
{
// Clear existing area
@@ -121,20 +175,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
for (u32 iObj = 0; iObj < NumObjects; iObj++)
{
CScriptObject *pObj = pLayer->InstanceByIndex(iObj);
CScriptNode *pNode = CreateScriptNode(pObj);
pNode->BuildLightList(mpArea);
// Add to map
mScriptNodeMap[pObj->InstanceID()] = pNode;
// AreaAttributes check
switch (pObj->ObjectTypeID())
{
case 0x4E: // MP1 AreaAttributes ID
case 0x52454141: // MP2/MP3/DKCR AreaAttributes ID ("REAA")
mAreaAttributesObjects.emplace_back( CAreaAttributes(pObj) );
break;
}
CreateScriptNode(pObj);
}
}
@@ -144,10 +185,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
for (u32 iObj = 0; iObj < pGenLayer->NumInstances(); iObj++)
{
CScriptObject *pObj = pGenLayer->InstanceByIndex(iObj);
CScriptNode *pNode = CreateScriptNode(pObj);
// Add to map
mScriptNodeMap[pObj->InstanceID()] = pNode;
CreateScriptNode(pObj);
}
}
@@ -217,16 +255,10 @@ void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
for (CSceneIterator It(this, NodeFlags, false); It; ++It)
{
if (NodeFlags & it->first)
{
std::vector<CSceneNode*>& rNodeVec = it->second;
for (u32 iNode = 0; iNode < rNodeVec.size(); iNode++)
if (ViewInfo.GameMode || rNodeVec[iNode]->IsVisible())
rNodeVec[iNode]->AddToRenderer(pRenderer, ViewInfo);
}
if (ViewInfo.GameMode || It->IsVisible())
It->AddToRenderer(pRenderer, ViewInfo);
}
}
@@ -236,16 +268,10 @@ SRayIntersection CScene::SceneRayCast(const CRay& Ray, const SViewInfo& ViewInfo
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
CRayCollisionTester Tester(Ray);
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
for (CSceneIterator It(this, NodeFlags, false); It; ++It)
{
if (NodeFlags & it->first)
{
std::vector<CSceneNode*>& rNodeVec = it->second;
for (u32 iNode = 0; iNode < rNodeVec.size(); iNode++)
if (rNodeVec[iNode]->IsVisible())
rNodeVec[iNode]->RayAABoxIntersectTest(Tester, ViewInfo);
}
if (It->IsVisible())
It->RayAABoxIntersectTest(Tester, ViewInfo);
}
return Tester.TestNodes(ViewInfo);

View File

@@ -51,6 +51,7 @@ public:
CCollisionNode* CreateCollisionNode(CCollisionMeshGroup *pMesh);
CScriptNode* CreateScriptNode(CScriptObject *pObj);
CLightNode* CreateLightNode(CLight *pLight);
void DeleteNode(CSceneNode *pNode);
void SetActiveArea(CGameArea *pArea);
void SetActiveWorld(CWorld *pWorld);
void PostLoad();

View File

@@ -38,7 +38,7 @@ public:
inline operator bool() const
{
return DoneIterating();
return !DoneIterating();
}
inline CSceneNode* operator*() const