Added support for EGMC and a basic EGMC visualizer dialog
This commit is contained in:
parent
b71e1268fa
commit
c0b74c9883
|
@ -182,7 +182,9 @@ HEADERS += \
|
|||
Scene/FShowFlags.h \
|
||||
Scene/CScene.h \
|
||||
Scene/CSceneIterator.h \
|
||||
Resource/CResourceInfo.h
|
||||
Resource/CResourceInfo.h \
|
||||
Resource/CPoiToWorld.h \
|
||||
Resource/Factory/CPoiToWorldLoader.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
|
@ -268,4 +270,6 @@ SOURCES += \
|
|||
Resource/Script/IProperty.cpp \
|
||||
Scene/FShowFlags.cpp \
|
||||
Scene/CScene.cpp \
|
||||
Scene/CSceneIterator.cpp
|
||||
Scene/CSceneIterator.cpp \
|
||||
Resource/CPoiToWorld.cpp \
|
||||
Resource/Factory/CPoiToWorldLoader.cpp
|
||||
|
|
|
@ -179,6 +179,11 @@ CLight* CGameArea::GetLight(u32 layer, u32 light)
|
|||
return mLightLayers[layer][light];
|
||||
}
|
||||
|
||||
CPoiToWorld* CGameArea::GetPoiToWorldMap()
|
||||
{
|
||||
return mpPoiToWorldMap;
|
||||
}
|
||||
|
||||
CAABox CGameArea::AABox()
|
||||
{
|
||||
return mAABox;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "CCollisionMeshGroup.h"
|
||||
#include "CLight.h"
|
||||
#include "CMaterialSet.h"
|
||||
#include "CPoiToWorld.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
#include "Core/Resource/Model/CStaticModel.h"
|
||||
#include <Common/types.h>
|
||||
|
@ -40,6 +41,8 @@ class CGameArea : public CResource
|
|||
CCollisionMeshGroup *mCollision;
|
||||
// Lights
|
||||
std::vector<std::vector<CLight*>> mLightLayers;
|
||||
// Object to Static Geometry Map
|
||||
TResPtr<CPoiToWorld> mpPoiToWorldMap;
|
||||
|
||||
public:
|
||||
CGameArea();
|
||||
|
@ -65,6 +68,7 @@ public:
|
|||
u32 GetLightLayerCount();
|
||||
u32 GetLightCount(u32 layer);
|
||||
CLight* GetLight(u32 layer, u32 light);
|
||||
CPoiToWorld* GetPoiToWorldMap();
|
||||
CAABox AABox();
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#include "CPoiToWorld.h"
|
||||
|
||||
CPoiToWorld::CPoiToWorld()
|
||||
{
|
||||
}
|
||||
|
||||
CPoiToWorld::~CPoiToWorld()
|
||||
{
|
||||
}
|
||||
|
||||
void CPoiToWorld::LinksForMeshID(std::list<u32>& rOutInstanceIDs, u32 MeshID)
|
||||
{
|
||||
for (u32 iLink = 0; iLink < mMeshLinks.size(); iLink++)
|
||||
{
|
||||
if (mMeshLinks[iLink].MeshID == MeshID)
|
||||
rOutInstanceIDs.push_back(mMeshLinks[iLink].PoiInstanceID);
|
||||
}
|
||||
}
|
||||
|
||||
void CPoiToWorld::LinksForInstanceID(std::list<u32>& rOutMeshIDs, u32 InstanceID)
|
||||
{
|
||||
for (u32 iLink = 0; iLink < mMeshLinks.size(); iLink++)
|
||||
{
|
||||
if (mMeshLinks[iLink].PoiInstanceID == InstanceID)
|
||||
rOutMeshIDs.push_back(mMeshLinks[iLink].MeshID);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef CPOITOWORLD_H
|
||||
#define CPOITOWORLD_H
|
||||
|
||||
#include "CResource.h"
|
||||
#include <list>
|
||||
|
||||
class CPoiToWorld : public CResource
|
||||
{
|
||||
DECLARE_RESOURCE_TYPE(ePoiToWorld)
|
||||
friend class CPoiToWorldLoader;
|
||||
|
||||
public:
|
||||
struct SPoiMeshLink
|
||||
{
|
||||
u32 MeshID;
|
||||
u32 PoiInstanceID;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<SPoiMeshLink> mMeshLinks;
|
||||
|
||||
public:
|
||||
CPoiToWorld();
|
||||
~CPoiToWorld();
|
||||
|
||||
void LinksForMeshID(std::list<u32>& rOutInstanceIDs, u32 MeshID);
|
||||
void LinksForInstanceID(std::list<u32>& rOutMeshIDs, u32 InstanceID);
|
||||
|
||||
inline u32 NumMeshLinks()
|
||||
{
|
||||
return mMeshLinks.size();
|
||||
}
|
||||
|
||||
inline const SPoiMeshLink& MeshLinkByIndex(u32 Index)
|
||||
{
|
||||
return mMeshLinks[Index];
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CPOITOWORLD_H
|
|
@ -4,6 +4,7 @@
|
|||
#include "Core/Resource/Factory/CCollisionLoader.h"
|
||||
#include "Core/Resource/Factory/CFontLoader.h"
|
||||
#include "Core/Resource/Factory/CModelLoader.h"
|
||||
#include "Core/Resource/Factory/CPoiToWorldLoader.h"
|
||||
#include "Core/Resource/Factory/CScanLoader.h"
|
||||
#include "Core/Resource/Factory/CStringLoader.h"
|
||||
#include "Core/Resource/Factory/CTextureDecoder.h"
|
||||
|
@ -145,6 +146,7 @@ CResource* CResCache::GetResource(CUniqueID ResID, CFourCC type)
|
|||
else if (type == "FONT") Res = CFontLoader::LoadFONT(mem);
|
||||
else if (type == "SCAN") Res = CScanLoader::LoadSCAN(mem);
|
||||
else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(mem);
|
||||
else if (type == "EGMC") Res = CPoiToWorldLoader::LoadEGMC(mem);
|
||||
else SupportedFormat = false;
|
||||
|
||||
// Log errors
|
||||
|
@ -197,6 +199,7 @@ CResource* CResCache::GetResource(const TString& ResPath)
|
|||
else if (type == "FONT") Res = CFontLoader::LoadFONT(file);
|
||||
else if (type == "SCAN") Res = CScanLoader::LoadSCAN(file);
|
||||
else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(file);
|
||||
else if (type == "EGMC") Res = CPoiToWorldLoader::LoadEGMC(file);
|
||||
else SupportedFormat = false;
|
||||
|
||||
if (!Res) Res = new CResource(); // Default for unsupported formats
|
||||
|
|
|
@ -33,18 +33,19 @@ enum EResType
|
|||
eParticle = 27,
|
||||
eParticleElectric = 28,
|
||||
eParticleSwoosh = 29,
|
||||
eProjectile = 30,
|
||||
eResource = 31,
|
||||
eSaveWorld = 32,
|
||||
eScan = 33,
|
||||
eSkeleton = 34,
|
||||
eSkin = 35,
|
||||
eStateMachine = 36,
|
||||
eStringTable = 37,
|
||||
eTexture = 38,
|
||||
eTweak = 39,
|
||||
eVideo = 40,
|
||||
eWorld = 41
|
||||
ePoiToWorld = 30,
|
||||
eProjectile = 31,
|
||||
eResource = 32,
|
||||
eSaveWorld = 33,
|
||||
eScan = 34,
|
||||
eSkeleton = 35,
|
||||
eSkin = 36,
|
||||
eStateMachine = 37,
|
||||
eStringTable = 38,
|
||||
eTexture = 39,
|
||||
eTweak = 40,
|
||||
eVideo = 41,
|
||||
eWorld = 42
|
||||
};
|
||||
|
||||
#endif // ERESTYPE
|
||||
|
|
|
@ -76,16 +76,25 @@ void CAreaLoader::ReadGeometryPrime()
|
|||
// Geometry
|
||||
std::vector<CModel*> FileModels;
|
||||
|
||||
for (u32 m = 0; m < mNumMeshes; m++) {
|
||||
std::cout << "\rLoading mesh " << std::dec << m + 1 << "/" << mNumMeshes;
|
||||
|
||||
for (u32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
||||
{
|
||||
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, mVersion);
|
||||
FileModels.push_back(pModel);
|
||||
|
||||
if (mVersion <= ePrime)
|
||||
mpArea->AddWorldModel(pModel);
|
||||
|
||||
if (mVersion >= eEchoes) {
|
||||
// For Echoes+, load surface mesh IDs, then skip to the start of the next mesh
|
||||
else
|
||||
{
|
||||
u16 NumSurfaces = mpMREA->ReadShort();
|
||||
|
||||
for (u32 iSurf = 0; iSurf < NumSurfaces; iSurf++)
|
||||
{
|
||||
mpMREA->Seek(0x2, SEEK_CUR);
|
||||
pModel->GetSurface(iSurf)->MeshID = mpMREA->ReadShort();
|
||||
}
|
||||
|
||||
mBlockMgr->ToNextBlock();
|
||||
mBlockMgr->ToNextBlock();
|
||||
}
|
||||
|
@ -102,7 +111,6 @@ void CAreaLoader::ReadGeometryPrime()
|
|||
}
|
||||
|
||||
mpArea->MergeTerrain();
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void CAreaLoader::ReadSCLYPrime()
|
||||
|
@ -341,22 +349,36 @@ void CAreaLoader::ReadGeometryCorruption()
|
|||
mBlockMgr->ToNextBlock();
|
||||
|
||||
// Geometry
|
||||
std::vector<CModel*> FileModels;
|
||||
u32 CurWOBJSection = 1;
|
||||
u32 CurGPUSection = mGPUBlockNum;
|
||||
|
||||
for (u32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
|
||||
{
|
||||
std::cout << "\rLoading mesh " << std::dec << iMesh + 1 << "/" << mNumMeshes;
|
||||
|
||||
CModel *pWorldModel = CModelLoader::LoadCorruptionWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, CurWOBJSection, CurGPUSection, mVersion);
|
||||
mpArea->AddWorldModel(pWorldModel);
|
||||
FileModels.push_back(pWorldModel);
|
||||
|
||||
CurWOBJSection += 4;
|
||||
CurGPUSection = mBlockMgr->CurrentBlock();
|
||||
|
||||
// Load surface mesh IDs
|
||||
mBlockMgr->ToBlock(CurWOBJSection - 2);
|
||||
u16 NumSurfaces = mpMREA->ReadShort();
|
||||
|
||||
for (u32 iSurf = 0; iSurf < NumSurfaces; iSurf++)
|
||||
{
|
||||
mpMREA->Seek(0x2, SEEK_CUR);
|
||||
pWorldModel->GetSurface(iSurf)->MeshID = mpMREA->ReadShort();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CModel*> SplitModels;
|
||||
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
||||
|
||||
for (u32 iMdl = 0; iMdl < SplitModels.size(); iMdl++)
|
||||
mpArea->AddWorldModel(SplitModels[iMdl]);
|
||||
|
||||
mpArea->MergeTerrain();
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void CAreaLoader::ReadLightsCorruption()
|
||||
|
@ -511,6 +533,14 @@ void CAreaLoader::ReadCollision()
|
|||
mpArea->mCollision = CCollisionLoader::LoadAreaCollision(*mpMREA);
|
||||
}
|
||||
|
||||
void CAreaLoader::ReadEGMC()
|
||||
{
|
||||
Log::FileWrite(mpMREA->GetSourceString(), "Reading EGMC");
|
||||
mBlockMgr->ToBlock(mEGMCBlockNum);
|
||||
CUniqueID EGMC(*mpMREA, (mVersion <= eEchoes ? e32Bit : e64Bit));
|
||||
mpArea->mpPoiToWorldMap = gResCache.GetResource(EGMC, "EGMC");
|
||||
}
|
||||
|
||||
void CAreaLoader::SetUpObjects()
|
||||
{
|
||||
// Iterate over all objects
|
||||
|
@ -598,6 +628,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
|||
Loader.ReadSCLYPrime();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsPrime();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eEchoes:
|
||||
Loader.ReadHeaderEchoes();
|
||||
|
@ -605,6 +636,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
|||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsPrime();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eCorruptionProto:
|
||||
Loader.ReadHeaderCorruption();
|
||||
|
@ -612,6 +644,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
|||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsCorruption();
|
||||
Loader.ReadEGMC();
|
||||
break;
|
||||
case eCorruption:
|
||||
case eReturns:
|
||||
|
@ -619,7 +652,11 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
|||
Loader.ReadGeometryCorruption();
|
||||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
if (Loader.mVersion == eCorruption) Loader.ReadLightsCorruption();
|
||||
if (Loader.mVersion == eCorruption)
|
||||
{
|
||||
Loader.ReadLightsCorruption();
|
||||
Loader.ReadEGMC();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log::FileError(MREA.GetSourceString(), "Unsupported MREA version: " + TString::HexString(version));
|
||||
|
|
|
@ -75,6 +75,7 @@ class CAreaLoader
|
|||
void ReadCompressedBlocks();
|
||||
void Decompress();
|
||||
void ReadCollision();
|
||||
void ReadEGMC();
|
||||
void SetUpObjects();
|
||||
|
||||
public:
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#include "CPoiToWorldLoader.h"
|
||||
|
||||
CPoiToWorld* CPoiToWorldLoader::LoadEGMC(IInputStream& rEGMC)
|
||||
{
|
||||
CPoiToWorld *pOut = new CPoiToWorld();
|
||||
u32 NumLinks = rEGMC.ReadLong();
|
||||
|
||||
for (u32 iLink = 0; iLink < NumLinks; iLink++)
|
||||
{
|
||||
CPoiToWorld::SPoiMeshLink Link;
|
||||
Link.MeshID = rEGMC.ReadLong();
|
||||
Link.PoiInstanceID = rEGMC.ReadLong();
|
||||
pOut->mMeshLinks.push_back(Link);
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef CPOITOWORLDLOADER_H
|
||||
#define CPOITOWORLDLOADER_H
|
||||
|
||||
#include "Core/Resource/CPoiToWorld.h"
|
||||
#include "Core/Resource/TResPtr.h"
|
||||
|
||||
class CPoiToWorldLoader
|
||||
{
|
||||
TResPtr<CPoiToWorld> mpPoiToWorld;
|
||||
|
||||
CPoiToWorldLoader() {}
|
||||
|
||||
public:
|
||||
static CPoiToWorld* LoadEGMC(IInputStream& rEGMC);
|
||||
};
|
||||
|
||||
#endif // CPOITOWORLDLOADER_H
|
|
@ -10,6 +10,7 @@ CModelNode::CModelNode(CScene *pScene, CSceneNode *pParent, CModel *pModel) : CS
|
|||
mScale = CVector3f(1.f);
|
||||
mLightingEnabled = true;
|
||||
mForceAlphaOn = false;
|
||||
mTintColor = CColor::skWhite;
|
||||
}
|
||||
|
||||
ENodeType CModelNode::NodeType()
|
||||
|
@ -103,6 +104,11 @@ SRayIntersection CModelNode::RayNodeIntersectTest(const CRay &Ray, u32 AssetID,
|
|||
return out;
|
||||
}
|
||||
|
||||
CColor CModelNode::TintColor(const SViewInfo& /*rkViewInfo*/) const
|
||||
{
|
||||
return mTintColor;
|
||||
}
|
||||
|
||||
void CModelNode::SetModel(CModel *pModel)
|
||||
{
|
||||
mpModel = pModel;
|
||||
|
@ -116,8 +122,3 @@ void CModelNode::SetModel(CModel *pModel)
|
|||
|
||||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
void CModelNode::ForceAlphaEnabled(bool Enable)
|
||||
{
|
||||
mForceAlphaOn = Enable;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ class CModelNode : public CSceneNode
|
|||
u32 mActiveMatSet;
|
||||
bool mLightingEnabled;
|
||||
bool mForceAlphaOn;
|
||||
CColor mTintColor;
|
||||
|
||||
public:
|
||||
explicit CModelNode(CScene *pScene, CSceneNode *pParent = 0, CModel *pModel = 0);
|
||||
|
@ -20,41 +21,20 @@ public:
|
|||
virtual void DrawSelection();
|
||||
virtual void RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo);
|
||||
virtual SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, const SViewInfo& ViewInfo);
|
||||
virtual CColor TintColor(const SViewInfo& rkViewInfo) const;
|
||||
|
||||
// Setters
|
||||
void SetModel(CModel *pModel);
|
||||
void SetMatSet(u32 MatSet);
|
||||
void SetDynamicLighting(bool Enable);
|
||||
void ForceAlphaEnabled(bool Enable);
|
||||
CModel* Model();
|
||||
u32 MatSet();
|
||||
bool IsDynamicLightingEnabled();
|
||||
|
||||
inline void SetMatSet(u32 MatSet) { mActiveMatSet = MatSet; }
|
||||
inline void SetDynamicLighting(bool Enable) { mLightingEnabled = Enable; }
|
||||
inline void ForceAlphaEnabled(bool Enable) { mForceAlphaOn = Enable; }
|
||||
inline void SetTintColor(const CColor& rkTintColor) { mTintColor = rkTintColor; }
|
||||
inline void ClearTintColor() { mTintColor = CColor::skWhite; }
|
||||
inline CModel* Model() const { return mpModel; }
|
||||
inline u32 MatSet() const { return mActiveMatSet; }
|
||||
inline bool IsDynamicLightingEnabled() const { return mLightingEnabled; }
|
||||
inline u32 FindMeshID() const { return mpModel->GetSurface(0)->MeshID; }
|
||||
};
|
||||
|
||||
|
||||
// ************ INLINE FUNCTIONS ************
|
||||
inline void CModelNode::SetMatSet(u32 MatSet)
|
||||
{
|
||||
mActiveMatSet = MatSet;
|
||||
}
|
||||
|
||||
inline void CModelNode::SetDynamicLighting(bool Enable)
|
||||
{
|
||||
mLightingEnabled = Enable;
|
||||
}
|
||||
|
||||
inline CModel* CModelNode::Model()
|
||||
{
|
||||
return mpModel;
|
||||
}
|
||||
|
||||
inline u32 CModelNode::MatSet()
|
||||
{
|
||||
return mActiveMatSet;
|
||||
}
|
||||
|
||||
inline bool CModelNode::IsDynamicLightingEnabled()
|
||||
{
|
||||
return mLightingEnabled;
|
||||
}
|
||||
|
||||
#endif // CMODELNODE_H
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "CScene.h"
|
||||
#include "Core/Render/CGraphics.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
#include "Core/Resource/CPoiToWorld.h"
|
||||
#include "Core/Resource/Script/CScriptLayer.h"
|
||||
#include "Core/CRayCollisionTester.h"
|
||||
|
||||
|
@ -88,23 +89,24 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
|||
mpArea = pArea;
|
||||
mpAreaRootNode = new CRootNode(this, mpSceneRootNode);
|
||||
|
||||
if (mSplitTerrain)
|
||||
{
|
||||
u32 Count = mpArea->GetStaticModelCount();
|
||||
// Create static nodes
|
||||
u32 Count = mpArea->GetStaticModelCount();
|
||||
|
||||
for (u32 iMdl = 0; iMdl < Count; iMdl++)
|
||||
CreateStaticNode(mpArea->GetStaticModel(iMdl));
|
||||
for (u32 iMdl = 0; iMdl < Count; iMdl++)
|
||||
{
|
||||
CStaticNode *pNode = CreateStaticNode(mpArea->GetStaticModel(iMdl));
|
||||
pNode->SetName("Static World Model " + TString::FromInt32(iMdl, 0, 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 Count = mpArea->GetTerrainModelCount();
|
||||
|
||||
for (u32 iMdl = 0; iMdl < Count; iMdl++)
|
||||
{
|
||||
CModel *pModel = mpArea->GetTerrainModel(iMdl);
|
||||
CModelNode *pNode = CreateModelNode(pModel);
|
||||
pNode->SetDynamicLighting(false);
|
||||
}
|
||||
// Create model nodes
|
||||
Count = mpArea->GetTerrainModelCount();
|
||||
|
||||
for (u32 iMdl = 0; iMdl < Count; iMdl++)
|
||||
{
|
||||
CModel *pModel = mpArea->GetTerrainModel(iMdl);
|
||||
CModelNode *pNode = CreateModelNode(pModel);
|
||||
pNode->SetName("World Model " + TString::FromInt32(iMdl, 0, 10));
|
||||
pNode->SetDynamicLighting(false);
|
||||
}
|
||||
|
||||
CreateCollisionNode(mpArea->GetCollision());
|
||||
|
@ -298,7 +300,8 @@ CGameArea* CScene::GetActiveArea()
|
|||
FShowFlags CScene::ShowFlagsForNodeFlags(FNodeFlags NodeFlags)
|
||||
{
|
||||
FShowFlags Out;
|
||||
if (NodeFlags & eStaticNode) Out |= eShowWorld;
|
||||
if (NodeFlags & eModelNode) Out |= eShowSplitWorld;
|
||||
if (NodeFlags & eStaticNode) Out |= eShowMergedWorld;
|
||||
if (NodeFlags & eScriptNode) Out |= eShowObjects;
|
||||
if (NodeFlags & eCollisionNode) Out |= eShowWorldCollision;
|
||||
if (NodeFlags & eLightNode) Out |= eShowLights;
|
||||
|
@ -307,8 +310,9 @@ FShowFlags CScene::ShowFlagsForNodeFlags(FNodeFlags NodeFlags)
|
|||
|
||||
FNodeFlags CScene::NodeFlagsForShowFlags(FShowFlags ShowFlags)
|
||||
{
|
||||
FNodeFlags Out = eRootNode | eModelNode;
|
||||
if (ShowFlags & eShowWorld) Out |= eStaticNode;
|
||||
FNodeFlags Out = eRootNode;
|
||||
if (ShowFlags & eShowSplitWorld) Out |= eModelNode;
|
||||
if (ShowFlags & eShowMergedWorld) Out |= eStaticNode;
|
||||
if (ShowFlags & eShowWorldCollision) Out |= eCollisionNode;
|
||||
if (ShowFlags & eShowObjects) Out |= eScriptNode | eScriptExtraNode;
|
||||
if (ShowFlags & eShowLights) Out |= eLightNode;
|
||||
|
|
|
@ -458,6 +458,11 @@ CScriptTemplate* CScriptNode::Template() const
|
|||
return mpInstance->Template();
|
||||
}
|
||||
|
||||
CScriptExtra* CScriptNode::Extra() const
|
||||
{
|
||||
return mpExtra;
|
||||
}
|
||||
|
||||
CModel* CScriptNode::ActiveModel() const
|
||||
{
|
||||
return mpActiveModel;
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
#include "Core/Resource/Script/CScriptObject.h"
|
||||
#include "Core/CLightParameters.h"
|
||||
|
||||
class CScriptExtra;
|
||||
|
||||
class CScriptNode : public CSceneNode
|
||||
{
|
||||
CScriptObject *mpInstance;
|
||||
class CScriptExtra *mpExtra;
|
||||
CScriptExtra *mpExtra;
|
||||
|
||||
TResPtr<CModel> mpActiveModel;
|
||||
TResPtr<CTexture> mpBillboard;
|
||||
|
@ -39,6 +41,7 @@ public:
|
|||
void GeneratePosition();
|
||||
CScriptObject* Object() const;
|
||||
CScriptTemplate* Template() const;
|
||||
CScriptExtra* Extra() const;
|
||||
CModel* ActiveModel() const;
|
||||
bool UsesModel() const;
|
||||
bool HasPreviewVolume() const;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#include "FShowFlags.h"
|
||||
|
||||
const FShowFlags gkGameModeShowFlags = eShowWorld | eShowObjectGeometry | eShowSky;
|
||||
const FShowFlags gkGameModeShowFlags = eShowMergedWorld | eShowObjectGeometry | eShowSky;
|
||||
|
|
|
@ -6,14 +6,15 @@
|
|||
enum EShowFlag
|
||||
{
|
||||
eShowNone = 0x00,
|
||||
eShowWorld = 0x01,
|
||||
eShowWorldCollision = 0x02,
|
||||
eShowObjectGeometry = 0x04,
|
||||
eShowObjectCollision = 0x08,
|
||||
eShowObjects = 0x0C,
|
||||
eShowLights = 0x10,
|
||||
eShowSky = 0x20,
|
||||
eShowAll = 0x3F
|
||||
eShowSplitWorld = 0x01,
|
||||
eShowMergedWorld = 0x02,
|
||||
eShowWorldCollision = 0x04,
|
||||
eShowObjectGeometry = 0x08,
|
||||
eShowObjectCollision = 0x10,
|
||||
eShowObjects = 0x18,
|
||||
eShowLights = 0x20,
|
||||
eShowSky = 0x40,
|
||||
eShowAll = 0x7F
|
||||
};
|
||||
DECLARE_FLAGS(EShowFlag, FShowFlags)
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ public:
|
|||
explicit CPointOfInterestExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0);
|
||||
void PropertyModified(IProperty* pProperty);
|
||||
void ModifyTintColor(CColor& Color);
|
||||
CScan* GetScan() const { return mpScanData; }
|
||||
|
||||
static const CColor skRegularColor;
|
||||
static const CColor skImportantColor;
|
||||
|
|
|
@ -10,6 +10,7 @@ CSceneViewport::CSceneViewport(QWidget *pParent)
|
|||
: CBasicViewport(pParent),
|
||||
mpEditor(nullptr),
|
||||
mpScene(nullptr),
|
||||
mRenderingMergedWorld(true),
|
||||
mGizmoTransforming(false),
|
||||
mpHoverNode(nullptr),
|
||||
mHoverPoint(CVector3f::skZero),
|
||||
|
@ -22,7 +23,7 @@ CSceneViewport::CSceneViewport(QWidget *pParent)
|
|||
|
||||
mViewInfo.pScene = mpScene;
|
||||
mViewInfo.pRenderer = mpRenderer;
|
||||
mViewInfo.ShowFlags = eShowWorld | eShowObjectGeometry | eShowLights | eShowSky;
|
||||
mViewInfo.ShowFlags = eShowMergedWorld | eShowObjectGeometry | eShowLights | eShowSky;
|
||||
|
||||
CreateContextMenu();
|
||||
}
|
||||
|
@ -46,6 +47,25 @@ void CSceneViewport::SetShowFlag(EShowFlag Flag, bool Visible)
|
|||
mViewInfo.ShowFlags &= ~Flag;
|
||||
}
|
||||
|
||||
void CSceneViewport::SetShowWorld(bool Visible)
|
||||
{
|
||||
if (mRenderingMergedWorld)
|
||||
SetShowFlag(eShowMergedWorld, Visible);
|
||||
else
|
||||
SetShowFlag(eShowSplitWorld, Visible);
|
||||
}
|
||||
|
||||
void CSceneViewport::SetRenderMergedWorld(bool b)
|
||||
{
|
||||
mRenderingMergedWorld = b;
|
||||
|
||||
if (mViewInfo.ShowFlags & (eShowSplitWorld | eShowMergedWorld))
|
||||
{
|
||||
SetShowFlag(eShowSplitWorld, !b);
|
||||
SetShowFlag(eShowMergedWorld, b);
|
||||
}
|
||||
}
|
||||
|
||||
FShowFlags CSceneViewport::ShowFlags() const
|
||||
{
|
||||
return mViewInfo.ShowFlags;
|
||||
|
@ -251,7 +271,7 @@ void CSceneViewport::ContextMenu(QContextMenuEvent* pEvent)
|
|||
|
||||
// Set up actions
|
||||
TString NodeName;
|
||||
bool HasHoverNode = (mpHoverNode && mpHoverNode->NodeType() != eStaticNode);
|
||||
bool HasHoverNode = (mpHoverNode && (mpHoverNode->NodeType() != eStaticNode) && (mpHoverNode->NodeType() != eModelNode));
|
||||
bool HasSelection = mpEditor->HasSelection();
|
||||
bool IsScriptNode = (mpHoverNode && mpHoverNode->NodeType() == eScriptNode);
|
||||
|
||||
|
@ -327,7 +347,7 @@ void CSceneViewport::OnMouseRelease(QMouseEvent *pEvent)
|
|||
// Object selection/deselection
|
||||
else
|
||||
{
|
||||
bool validNode = (mpHoverNode && (mpHoverNode->NodeType() != eStaticNode));
|
||||
bool validNode = (mpHoverNode && (mpHoverNode->NodeType() != eStaticNode) && (mpHoverNode->NodeType() != eModelNode));
|
||||
bool altPressed = ((pEvent->modifiers() & Qt::AltModifier) != 0);
|
||||
bool ctrlPressed = ((pEvent->modifiers() & Qt::ControlModifier) != 0);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ class CSceneViewport : public CBasicViewport
|
|||
INodeEditor *mpEditor;
|
||||
CScene *mpScene;
|
||||
CRenderer *mpRenderer;
|
||||
bool mRenderingMergedWorld;
|
||||
|
||||
// Scene interaction
|
||||
bool mGizmoHovering;
|
||||
|
@ -37,6 +38,8 @@ public:
|
|||
~CSceneViewport();
|
||||
void SetScene(INodeEditor *pEditor, CScene *pScene);
|
||||
void SetShowFlag(EShowFlag Flag, bool Visible);
|
||||
void SetShowWorld(bool Visible);
|
||||
void SetRenderMergedWorld(bool b);
|
||||
FShowFlags ShowFlags() const;
|
||||
CRenderer* Renderer();
|
||||
CSceneNode* HoverNode();
|
||||
|
|
|
@ -127,7 +127,9 @@ HEADERS += \
|
|||
UICommon.h \
|
||||
CErrorLogDialog.h \
|
||||
Undo/CSelectAllCommand.h \
|
||||
Undo/CInvertSelectionCommand.h
|
||||
Undo/CInvertSelectionCommand.h \
|
||||
WorldEditor/CPoiMapEditDialog.h \
|
||||
WorldEditor/CPoiMapModel.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
|
@ -175,7 +177,9 @@ SOURCES += \
|
|||
UICommon.cpp \
|
||||
CErrorLogDialog.cpp \
|
||||
Undo/CSelectAllCommand.cpp \
|
||||
Undo/CInvertSelectionCommand.cpp
|
||||
Undo/CInvertSelectionCommand.cpp \
|
||||
WorldEditor/CPoiMapEditDialog.cpp \
|
||||
WorldEditor/CPoiMapModel.cpp
|
||||
|
||||
# UI Files
|
||||
FORMS += \
|
||||
|
@ -190,4 +194,5 @@ FORMS += \
|
|||
WorldEditor/WCreateTab.ui \
|
||||
WorldEditor/WInstancesTab.ui \
|
||||
WorldEditor/WModifyTab.ui \
|
||||
CErrorLogDialog.ui
|
||||
CErrorLogDialog.ui \
|
||||
WorldEditor/CPoiMapEditDialog.ui
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<RCC>
|
||||
<qresource>
|
||||
<qresource prefix="/">
|
||||
<file>icons/Down.png</file>
|
||||
<file>icons/Free Camera.png</file>
|
||||
<file>icons/Material Highlight.png</file>
|
||||
|
@ -28,5 +28,7 @@
|
|||
<file>icons/Unlink.png</file>
|
||||
<file>icons/World.png</file>
|
||||
<file>icons/SelectMode.png</file>
|
||||
<file>icons/POI Important.png</file>
|
||||
<file>icons/POI Normal.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
#include "CPoiMapEditDialog.h"
|
||||
#include "ui_CPoiMapEditDialog.h"
|
||||
#include "CWorldEditor.h"
|
||||
#include <Core/Resource/CScan.h>
|
||||
#include <Core/ScriptExtra/CPointOfInterestExtra.h>
|
||||
|
||||
CPoiMapEditDialog::CPoiMapEditDialog(CWorldEditor *pEditor, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::CPoiMapEditDialog)
|
||||
, mpEditor(pEditor)
|
||||
, mSourceModel(pEditor, this)
|
||||
, mHighlightMode(eHighlightSelected)
|
||||
{
|
||||
mModel.setSourceModel(&mSourceModel);
|
||||
mModel.sort(0);
|
||||
|
||||
ui->setupUi(this);
|
||||
ui->ListView->setModel(&mModel);
|
||||
|
||||
QActionGroup *pGroup = new QActionGroup(this);
|
||||
pGroup->addAction(ui->ActionHighlightSelected);
|
||||
pGroup->addAction(ui->ActionHighlightAll);
|
||||
pGroup->addAction(ui->ActionHighlightNone);
|
||||
SetHighlightSelected();
|
||||
|
||||
connect(ui->ActionHighlightSelected, SIGNAL(triggered()), this, SLOT(SetHighlightSelected()));
|
||||
connect(ui->ActionHighlightAll, SIGNAL(triggered()), this, SLOT(SetHighlightAll()));
|
||||
connect(ui->ActionHighlightNone, SIGNAL(triggered()), this, SLOT(SetHighlightNone()));
|
||||
connect(ui->ListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SLOT(OnSelectionChanged(QItemSelection,QItemSelection)));
|
||||
connect(ui->ListView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnItemDoubleClick(QModelIndex)));
|
||||
connect(ui->ButtonBox, SIGNAL(accepted()), this, SLOT(close()));
|
||||
connect(ui->ButtonBox, SIGNAL(rejected()), this, SLOT(close()));
|
||||
}
|
||||
|
||||
CPoiMapEditDialog::~CPoiMapEditDialog()
|
||||
{
|
||||
delete ui;
|
||||
|
||||
// Clear model tints
|
||||
if (mHighlightMode != eHighlightNone)
|
||||
SetHighlightNone();
|
||||
}
|
||||
|
||||
void CPoiMapEditDialog::HighlightPoiModels(const QModelIndex& rkIndex)
|
||||
{
|
||||
// Get POI and models
|
||||
QModelIndex SourceIndex = mModel.mapToSource(rkIndex);
|
||||
CScriptNode *pPOI = mSourceModel.PoiNodePointer(SourceIndex);
|
||||
const QList<CModelNode*>& rkModels = mSourceModel.GetPoiMeshList(pPOI);
|
||||
|
||||
// Check whether this is an important scan
|
||||
bool IsImportant = false;
|
||||
TResPtr<CScan> pScan = static_cast<CPointOfInterestExtra*>(pPOI->Extra())->GetScan();
|
||||
|
||||
if (pScan)
|
||||
IsImportant = pScan->IsImportant();
|
||||
|
||||
// Highlight the meshes
|
||||
for (int iMdl = 0; iMdl < rkModels.size(); iMdl++)
|
||||
rkModels[iMdl]->SetTintColor(IsImportant ? CColor::skRed : CColor::skBlue);
|
||||
}
|
||||
|
||||
void CPoiMapEditDialog::UnhighlightPoiModels(const QModelIndex& rkIndex)
|
||||
{
|
||||
QModelIndex SourceIndex = mModel.mapToSource(rkIndex);
|
||||
const QList<CModelNode*>& rkModels = mSourceModel.GetPoiMeshList(SourceIndex);
|
||||
|
||||
for (int iMdl = 0; iMdl < rkModels.size(); iMdl++)
|
||||
rkModels[iMdl]->ClearTintColor();
|
||||
}
|
||||
|
||||
void CPoiMapEditDialog::SetHighlightSelected()
|
||||
{
|
||||
const QItemSelection kSelection = ui->ListView->selectionModel()->selection();
|
||||
|
||||
for (int iRow = 0; iRow < mModel.rowCount(QModelIndex()); iRow++)
|
||||
{
|
||||
QModelIndex Index = mModel.index(iRow, 0);
|
||||
|
||||
if (kSelection.contains(Index))
|
||||
HighlightPoiModels(Index);
|
||||
else
|
||||
UnhighlightPoiModels(Index);
|
||||
}
|
||||
|
||||
mHighlightMode = eHighlightSelected;
|
||||
}
|
||||
|
||||
void CPoiMapEditDialog::SetHighlightAll()
|
||||
{
|
||||
for (int iRow = 0; iRow < mModel.rowCount(QModelIndex()); iRow++)
|
||||
HighlightPoiModels(mModel.index(iRow, 0));
|
||||
|
||||
mHighlightMode = eHighlightAll;
|
||||
}
|
||||
|
||||
void CPoiMapEditDialog::SetHighlightNone()
|
||||
{
|
||||
for (int iRow = 0; iRow < mModel.rowCount(QModelIndex()); iRow++)
|
||||
UnhighlightPoiModels(mModel.index(iRow, 0));
|
||||
|
||||
mHighlightMode = eHighlightNone;
|
||||
}
|
||||
|
||||
void CPoiMapEditDialog::OnSelectionChanged(const QItemSelection& rkSelected, const QItemSelection& rkDeselected)
|
||||
{
|
||||
if (mHighlightMode == eHighlightSelected)
|
||||
{
|
||||
// Clear highlight on deselected models
|
||||
QModelIndexList DeselectedIndices = rkDeselected.indexes();
|
||||
|
||||
for (int iIdx = 0; iIdx < DeselectedIndices.size(); iIdx++)
|
||||
UnhighlightPoiModels(DeselectedIndices[iIdx]);
|
||||
|
||||
// Highlight newly selected models
|
||||
QModelIndexList SelectedIndices = rkSelected.indexes();
|
||||
|
||||
for (int iIdx = 0; iIdx < SelectedIndices.size(); iIdx++)
|
||||
HighlightPoiModels(SelectedIndices[iIdx]);
|
||||
}
|
||||
}
|
||||
|
||||
void CPoiMapEditDialog::OnItemDoubleClick(QModelIndex Index)
|
||||
{
|
||||
QModelIndex SourceIndex = mModel.mapToSource(Index);
|
||||
CScriptNode *pPOI = mSourceModel.PoiNodePointer(SourceIndex);
|
||||
mpEditor->ClearAndSelectNode(pPOI);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef CPOIMAPEDITDIALOG_H
|
||||
#define CPOIMAPEDITDIALOG_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "CPoiMapModel.h"
|
||||
#include <QItemSelection>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
namespace Ui {
|
||||
class CPoiMapEditDialog;
|
||||
}
|
||||
|
||||
class CPoiMapEditDialog : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Ui::CPoiMapEditDialog *ui;
|
||||
|
||||
enum EHighlightMode
|
||||
{
|
||||
eHighlightAll,
|
||||
eHighlightNone,
|
||||
eHighlightSelected
|
||||
};
|
||||
|
||||
CWorldEditor *mpEditor;
|
||||
CPoiMapModel mSourceModel;
|
||||
QSortFilterProxyModel mModel;
|
||||
EHighlightMode mHighlightMode;
|
||||
|
||||
public:
|
||||
explicit CPoiMapEditDialog(CWorldEditor *pEditor, QWidget *parent = 0);
|
||||
~CPoiMapEditDialog();
|
||||
void closeEvent(QCloseEvent *) { emit Closed(); }
|
||||
void HighlightPoiModels(const QModelIndex& rkIndex);
|
||||
void UnhighlightPoiModels(const QModelIndex& rkIndex);
|
||||
|
||||
public slots:
|
||||
void SetHighlightSelected();
|
||||
void SetHighlightAll();
|
||||
void SetHighlightNone();
|
||||
void OnSelectionChanged(const QItemSelection& rkSelected, const QItemSelection& rkDeselected);
|
||||
void OnItemDoubleClick(QModelIndex Index);
|
||||
|
||||
signals:
|
||||
void Closed();
|
||||
};
|
||||
|
||||
#endif // CPOIMAPEDITDIALOG_H
|
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CPoiMapEditDialog</class>
|
||||
<widget class="QMainWindow" name="CPoiMapEditDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>469</width>
|
||||
<height>327</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Edit POI to World Mappings</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="ListView">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="ButtonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="ToolBar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="ActionHighlightSelected"/>
|
||||
<addaction name="ActionHighlightAll"/>
|
||||
<addaction name="ActionHighlightNone"/>
|
||||
</widget>
|
||||
<action name="ActionHighlightAll">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Highlight All</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionHighlightNone">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Highlight None</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Highlight None</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionHighlightSelected">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Highlight Selected</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Highlight Selected</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,112 @@
|
|||
#include "CPoiMapModel.h"
|
||||
#include "CWorldEditor.h"
|
||||
#include "Editor/UICommon.h"
|
||||
#include <Core/Scene/CSceneIterator.h>
|
||||
#include <Core/ScriptExtra/CPointOfInterestExtra.h>
|
||||
|
||||
CPoiMapModel::CPoiMapModel(CWorldEditor *pEditor, QObject *pParent /*= 0*/)
|
||||
: QAbstractListModel(pParent)
|
||||
, mpEditor(pEditor)
|
||||
{
|
||||
mpEditor = pEditor;
|
||||
mpPoiToWorld = mpEditor->ActiveArea()->GetPoiToWorldMap();
|
||||
|
||||
if (mpPoiToWorld)
|
||||
{
|
||||
// Create map of model nodes
|
||||
QMap<u32,CModelNode*> NodeMap;
|
||||
|
||||
for (CSceneIterator It(mpEditor->Scene(), eModelNode, true); !It.DoneIterating(); ++It)
|
||||
{
|
||||
CModelNode *pNode = static_cast<CModelNode*>(*It);
|
||||
NodeMap[pNode->FindMeshID()] = pNode;
|
||||
}
|
||||
|
||||
// Create list of mappings
|
||||
for (u32 iMap = 0; iMap < mpPoiToWorld->NumMeshLinks(); iMap++)
|
||||
{
|
||||
const CPoiToWorld::SPoiMeshLink& rkLink = mpPoiToWorld->MeshLinkByIndex(iMap);
|
||||
CScriptNode *pPOI = mpEditor->Scene()->ScriptNodeByID(rkLink.PoiInstanceID);
|
||||
|
||||
if (!mPoiLookupMap.contains(pPOI))
|
||||
{
|
||||
SEditorPoiMap Map;
|
||||
Map.pPOI = pPOI;
|
||||
mMaps << Map;
|
||||
mPoiLookupMap[pPOI] = &mMaps.last();
|
||||
}
|
||||
|
||||
if (NodeMap.contains(rkLink.MeshID))
|
||||
mPoiLookupMap[pPOI]->Models << NodeMap[rkLink.MeshID];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariant CPoiMapModel::headerData(int Section, Qt::Orientation Orientation, int Role) const
|
||||
{
|
||||
if ( (Section == 0) && (Orientation == Qt::Horizontal) && (Role == Qt::DisplayRole) )
|
||||
return "PointOfInterest";
|
||||
|
||||
return QVariant::Invalid;
|
||||
}
|
||||
|
||||
int CPoiMapModel::rowCount(const QModelIndex& /*rkParent*/) const
|
||||
{
|
||||
return mMaps.size();
|
||||
}
|
||||
|
||||
QVariant CPoiMapModel::data(const QModelIndex& rkIndex, int Role) const
|
||||
{
|
||||
if (rkIndex.row() < mMaps.size())
|
||||
{
|
||||
const SEditorPoiMap& rkMap = mMaps[rkIndex.row()];
|
||||
|
||||
if (Role == Qt::DisplayRole)
|
||||
{
|
||||
if (rkMap.pPOI)
|
||||
return TO_QSTRING(rkMap.pPOI->Object()->InstanceName());
|
||||
else
|
||||
return "[INVALID POI]";
|
||||
}
|
||||
|
||||
else if (Role == Qt::DecorationRole)
|
||||
{
|
||||
bool IsImportant = false;
|
||||
|
||||
if (rkMap.pPOI)
|
||||
{
|
||||
// Get scan
|
||||
CScan *pScan = static_cast<CPointOfInterestExtra*>(rkMap.pPOI->Extra())->GetScan();
|
||||
|
||||
if (pScan)
|
||||
IsImportant = pScan->IsImportant();
|
||||
}
|
||||
|
||||
if (IsImportant)
|
||||
return QIcon(":/icons/POI Important.png");
|
||||
else
|
||||
return QIcon(":/icons/POI Normal.png");
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant::Invalid;
|
||||
}
|
||||
|
||||
CScriptNode* CPoiMapModel::PoiNodePointer(const QModelIndex& rkIndex) const
|
||||
{
|
||||
if (rkIndex.row() < mMaps.size())
|
||||
return mMaps[rkIndex.row()].pPOI;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const QList<CModelNode*>& CPoiMapModel::GetPoiMeshList(const QModelIndex& rkIndex) const
|
||||
{
|
||||
CScriptNode *pPOI = PoiNodePointer(rkIndex);
|
||||
return GetPoiMeshList(pPOI);
|
||||
}
|
||||
|
||||
const QList<CModelNode*>& CPoiMapModel::GetPoiMeshList(CScriptNode *pPOI) const
|
||||
{
|
||||
return mPoiLookupMap[pPOI]->Models;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef CPOIMAPMODEL_H
|
||||
#define CPOIMAPMODEL_H
|
||||
|
||||
#include <Core/Resource/CPoiToWorld.h>
|
||||
#include <Core/Resource/TResPtr.h>
|
||||
#include <Core/Scene/CModelNode.h>
|
||||
#include <Core/Scene/CScriptNode.h>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QVector>
|
||||
|
||||
class CWorldEditor;
|
||||
|
||||
class CPoiMapModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
private:
|
||||
CWorldEditor *mpEditor;
|
||||
TResPtr<CPoiToWorld> mpPoiToWorld;
|
||||
|
||||
struct SEditorPoiMap
|
||||
{
|
||||
CScriptNode *pPOI;
|
||||
QList<CModelNode*> Models;
|
||||
};
|
||||
QList<SEditorPoiMap> mMaps;
|
||||
QMap<CScriptNode*,SEditorPoiMap*> mPoiLookupMap;
|
||||
|
||||
public:
|
||||
explicit CPoiMapModel(CWorldEditor *pEditor, QObject *pParent = 0);
|
||||
QVariant headerData(int Section, Qt::Orientation Orientation, int Role) const;
|
||||
int rowCount(const QModelIndex& rkParent) const;
|
||||
QVariant data(const QModelIndex& rkIndex, int Role) const;
|
||||
|
||||
CScriptNode* PoiNodePointer(const QModelIndex& rkIndex) const;
|
||||
const QList<CModelNode*>& GetPoiMeshList(const QModelIndex& rkIndex) const;
|
||||
const QList<CModelNode*>& GetPoiMeshList(CScriptNode *pPOI) const;
|
||||
};
|
||||
|
||||
#endif // CPOIMAPMODEL_H
|
|
@ -28,6 +28,7 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
|
|||
|
||||
mpArea = nullptr;
|
||||
mpWorld = nullptr;
|
||||
mpPoiDialog = nullptr;
|
||||
mGizmoHovering = false;
|
||||
mGizmoTransforming = false;
|
||||
|
||||
|
@ -80,6 +81,12 @@ CWorldEditor::~CWorldEditor()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void CWorldEditor::closeEvent(QCloseEvent *)
|
||||
{
|
||||
if (mpPoiDialog)
|
||||
mpPoiDialog->close();
|
||||
}
|
||||
|
||||
bool CWorldEditor::eventFilter(QObject *pObj, QEvent *pEvent)
|
||||
{
|
||||
if (pObj == ui->MainDock)
|
||||
|
@ -103,6 +110,12 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
|||
ui->InstancesTabContents->SetArea(pArea);
|
||||
mUndoStack.clear();
|
||||
|
||||
if (mpPoiDialog)
|
||||
{
|
||||
delete mpPoiDialog;
|
||||
mpPoiDialog = nullptr;
|
||||
}
|
||||
|
||||
// Clear old area - hack until better world/area loader is implemented
|
||||
if ((mpArea) && (pArea != mpArea))
|
||||
mpArea->ClearScriptLayers();
|
||||
|
@ -160,7 +173,7 @@ void CWorldEditor::UpdateStatusBar()
|
|||
{
|
||||
CSceneNode *pHoverNode = ui->MainViewport->HoverNode();
|
||||
|
||||
if (pHoverNode && (pHoverNode->NodeType() != eStaticNode))
|
||||
if (pHoverNode && (pHoverNode->NodeType() != eStaticNode) && (pHoverNode->NodeType() != eModelNode))
|
||||
StatusText = TO_QSTRING(pHoverNode->Name());
|
||||
}
|
||||
}
|
||||
|
@ -259,7 +272,7 @@ void CWorldEditor::UpdateCursor()
|
|||
|
||||
if (ui->MainViewport->IsHoveringGizmo())
|
||||
ui->MainViewport->SetCursorState(Qt::SizeAllCursor);
|
||||
else if ((pHoverNode) && (pHoverNode->NodeType() != eStaticNode))
|
||||
else if ((pHoverNode) && (pHoverNode->NodeType() != eStaticNode) && (pHoverNode->NodeType() != eModelNode))
|
||||
ui->MainViewport->SetCursorState(Qt::PointingHandCursor);
|
||||
else
|
||||
ui->MainViewport->SetCursorState(Qt::ArrowCursor);
|
||||
|
@ -350,10 +363,17 @@ void CWorldEditor::OnTransformSpinBoxEdited(CVector3f)
|
|||
UpdateGizmoUI();
|
||||
}
|
||||
|
||||
void CWorldEditor::OnClosePoiEditDialog()
|
||||
{
|
||||
delete mpPoiDialog;
|
||||
mpPoiDialog = nullptr;
|
||||
ui->MainViewport->SetRenderMergedWorld(true);
|
||||
}
|
||||
|
||||
// These functions are from "Go to slot" in the designer
|
||||
void CWorldEditor::on_ActionDrawWorld_triggered()
|
||||
{
|
||||
ui->MainViewport->SetShowFlag(eShowWorld, ui->ActionDrawWorld->isChecked());
|
||||
ui->MainViewport->SetShowWorld(ui->ActionDrawWorld->isChecked());
|
||||
}
|
||||
|
||||
void CWorldEditor::on_ActionDrawCollision_triggered()
|
||||
|
@ -477,13 +497,28 @@ void CWorldEditor::on_ActionGameMode_triggered()
|
|||
void CWorldEditor::on_ActionSelectAll_triggered()
|
||||
{
|
||||
FNodeFlags NodeFlags = CScene::NodeFlagsForShowFlags(ui->MainViewport->ShowFlags());
|
||||
NodeFlags &= ~(eStaticNode | eCollisionNode);
|
||||
NodeFlags &= ~(eModelNode | eStaticNode | eCollisionNode);
|
||||
SelectAll(NodeFlags);
|
||||
}
|
||||
|
||||
void CWorldEditor::on_ActionInvertSelection_triggered()
|
||||
{
|
||||
FNodeFlags NodeFlags = CScene::NodeFlagsForShowFlags(ui->MainViewport->ShowFlags());
|
||||
NodeFlags &= ~(eStaticNode | eCollisionNode);
|
||||
NodeFlags &= ~(eModelNode | eStaticNode | eCollisionNode);
|
||||
InvertSelection(NodeFlags);
|
||||
}
|
||||
|
||||
void CWorldEditor::on_ActionEditPoiToWorldMap_triggered()
|
||||
{
|
||||
if (!mpPoiDialog)
|
||||
{
|
||||
mpPoiDialog = new CPoiMapEditDialog(this, this);
|
||||
mpPoiDialog->show();
|
||||
ui->MainViewport->SetRenderMergedWorld(false);
|
||||
connect(mpPoiDialog, SIGNAL(Closed()), this, SLOT(OnClosePoiEditDialog()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mpPoiDialog->show();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CWORLDEDITOR_H
|
||||
#define CWORLDEDITOR_H
|
||||
|
||||
#include "CPoiMapEditDialog.h"
|
||||
#include "Editor/INodeEditor.h"
|
||||
#include "Editor/CGizmo.h"
|
||||
|
||||
|
@ -34,9 +35,12 @@ class CWorldEditor : public INodeEditor
|
|||
TResPtr<CGameArea> mpArea;
|
||||
QTimer mRefreshTimer;
|
||||
|
||||
CPoiMapEditDialog *mpPoiDialog;
|
||||
|
||||
public:
|
||||
explicit CWorldEditor(QWidget *parent = 0);
|
||||
~CWorldEditor();
|
||||
void closeEvent(QCloseEvent *);
|
||||
bool eventFilter(QObject *pObj, QEvent *pEvent);
|
||||
void SetArea(CWorld *pWorld, CGameArea *pArea);
|
||||
CGameArea* ActiveArea();
|
||||
|
@ -58,6 +62,7 @@ private slots:
|
|||
void OnCameraSpeedChange(double speed);
|
||||
void OnTransformSpinBoxModified(CVector3f value);
|
||||
void OnTransformSpinBoxEdited(CVector3f value);
|
||||
void OnClosePoiEditDialog();
|
||||
void on_ActionDrawWorld_triggered();
|
||||
void on_ActionDrawCollision_triggered();
|
||||
void on_ActionDrawObjects_triggered();
|
||||
|
@ -79,6 +84,7 @@ private slots:
|
|||
void on_ActionGameMode_triggered();
|
||||
void on_ActionSelectAll_triggered();
|
||||
void on_ActionInvertSelection_triggered();
|
||||
void on_ActionEditPoiToWorldMap_triggered();
|
||||
};
|
||||
|
||||
#endif // CWORLDEDITOR_H
|
||||
|
|
|
@ -289,6 +289,7 @@
|
|||
<string>Tools</string>
|
||||
</property>
|
||||
<addaction name="ActionEditLayers"/>
|
||||
<addaction name="ActionEditPoiToWorldMap"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuEdit"/>
|
||||
|
@ -758,6 +759,11 @@
|
|||
<string>Ctrl+I</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionEditPoiToWorldMap">
|
||||
<property name="text">
|
||||
<string>Edit POI to World Map</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -173,6 +173,9 @@
|
|||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderDefaultSectionSize">
|
||||
<number>21</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -195,6 +198,9 @@
|
|||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>75</number>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderDefaultSectionSize">
|
||||
<number>21</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
|
@ -7,13 +7,16 @@
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Create application
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
||||
QApplication app(argc, argv);
|
||||
CStartWindow w;
|
||||
w.show();
|
||||
|
||||
// Load templates
|
||||
CTemplateLoader::LoadGameList();
|
||||
|
||||
// Set up dark style
|
||||
app.setStyle(new CDarkStyle);
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
|
||||
|
@ -35,5 +38,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
qApp->setPalette(darkPalette);
|
||||
|
||||
// Execute application
|
||||
return app.exec();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue