Added support for EGMC and a basic EGMC visualizer dialog

This commit is contained in:
parax0 2016-01-15 16:36:58 -07:00
parent b71e1268fa
commit c0b74c9883
35 changed files with 763 additions and 101 deletions

View File

@ -182,7 +182,9 @@ HEADERS += \
Scene/FShowFlags.h \ Scene/FShowFlags.h \
Scene/CScene.h \ Scene/CScene.h \
Scene/CSceneIterator.h \ Scene/CSceneIterator.h \
Resource/CResourceInfo.h Resource/CResourceInfo.h \
Resource/CPoiToWorld.h \
Resource/Factory/CPoiToWorldLoader.h
# Source Files # Source Files
SOURCES += \ SOURCES += \
@ -268,4 +270,6 @@ SOURCES += \
Resource/Script/IProperty.cpp \ Resource/Script/IProperty.cpp \
Scene/FShowFlags.cpp \ Scene/FShowFlags.cpp \
Scene/CScene.cpp \ Scene/CScene.cpp \
Scene/CSceneIterator.cpp Scene/CSceneIterator.cpp \
Resource/CPoiToWorld.cpp \
Resource/Factory/CPoiToWorldLoader.cpp

View File

@ -179,6 +179,11 @@ CLight* CGameArea::GetLight(u32 layer, u32 light)
return mLightLayers[layer][light]; return mLightLayers[layer][light];
} }
CPoiToWorld* CGameArea::GetPoiToWorldMap()
{
return mpPoiToWorldMap;
}
CAABox CGameArea::AABox() CAABox CGameArea::AABox()
{ {
return mAABox; return mAABox;

View File

@ -5,6 +5,7 @@
#include "CCollisionMeshGroup.h" #include "CCollisionMeshGroup.h"
#include "CLight.h" #include "CLight.h"
#include "CMaterialSet.h" #include "CMaterialSet.h"
#include "CPoiToWorld.h"
#include "Core/Resource/Model/CModel.h" #include "Core/Resource/Model/CModel.h"
#include "Core/Resource/Model/CStaticModel.h" #include "Core/Resource/Model/CStaticModel.h"
#include <Common/types.h> #include <Common/types.h>
@ -40,6 +41,8 @@ class CGameArea : public CResource
CCollisionMeshGroup *mCollision; CCollisionMeshGroup *mCollision;
// Lights // Lights
std::vector<std::vector<CLight*>> mLightLayers; std::vector<std::vector<CLight*>> mLightLayers;
// Object to Static Geometry Map
TResPtr<CPoiToWorld> mpPoiToWorldMap;
public: public:
CGameArea(); CGameArea();
@ -65,6 +68,7 @@ public:
u32 GetLightLayerCount(); u32 GetLightLayerCount();
u32 GetLightCount(u32 layer); u32 GetLightCount(u32 layer);
CLight* GetLight(u32 layer, u32 light); CLight* GetLight(u32 layer, u32 light);
CPoiToWorld* GetPoiToWorldMap();
CAABox AABox(); CAABox AABox();
}; };

View File

@ -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);
}
}

View File

@ -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

View File

@ -4,6 +4,7 @@
#include "Core/Resource/Factory/CCollisionLoader.h" #include "Core/Resource/Factory/CCollisionLoader.h"
#include "Core/Resource/Factory/CFontLoader.h" #include "Core/Resource/Factory/CFontLoader.h"
#include "Core/Resource/Factory/CModelLoader.h" #include "Core/Resource/Factory/CModelLoader.h"
#include "Core/Resource/Factory/CPoiToWorldLoader.h"
#include "Core/Resource/Factory/CScanLoader.h" #include "Core/Resource/Factory/CScanLoader.h"
#include "Core/Resource/Factory/CStringLoader.h" #include "Core/Resource/Factory/CStringLoader.h"
#include "Core/Resource/Factory/CTextureDecoder.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 == "FONT") Res = CFontLoader::LoadFONT(mem);
else if (type == "SCAN") Res = CScanLoader::LoadSCAN(mem); else if (type == "SCAN") Res = CScanLoader::LoadSCAN(mem);
else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(mem); else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(mem);
else if (type == "EGMC") Res = CPoiToWorldLoader::LoadEGMC(mem);
else SupportedFormat = false; else SupportedFormat = false;
// Log errors // Log errors
@ -197,6 +199,7 @@ CResource* CResCache::GetResource(const TString& ResPath)
else if (type == "FONT") Res = CFontLoader::LoadFONT(file); else if (type == "FONT") Res = CFontLoader::LoadFONT(file);
else if (type == "SCAN") Res = CScanLoader::LoadSCAN(file); else if (type == "SCAN") Res = CScanLoader::LoadSCAN(file);
else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(file); else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(file);
else if (type == "EGMC") Res = CPoiToWorldLoader::LoadEGMC(file);
else SupportedFormat = false; else SupportedFormat = false;
if (!Res) Res = new CResource(); // Default for unsupported formats if (!Res) Res = new CResource(); // Default for unsupported formats

View File

@ -33,18 +33,19 @@ enum EResType
eParticle = 27, eParticle = 27,
eParticleElectric = 28, eParticleElectric = 28,
eParticleSwoosh = 29, eParticleSwoosh = 29,
eProjectile = 30, ePoiToWorld = 30,
eResource = 31, eProjectile = 31,
eSaveWorld = 32, eResource = 32,
eScan = 33, eSaveWorld = 33,
eSkeleton = 34, eScan = 34,
eSkin = 35, eSkeleton = 35,
eStateMachine = 36, eSkin = 36,
eStringTable = 37, eStateMachine = 37,
eTexture = 38, eStringTable = 38,
eTweak = 39, eTexture = 39,
eVideo = 40, eTweak = 40,
eWorld = 41 eVideo = 41,
eWorld = 42
}; };
#endif // ERESTYPE #endif // ERESTYPE

View File

@ -76,16 +76,25 @@ void CAreaLoader::ReadGeometryPrime()
// Geometry // Geometry
std::vector<CModel*> FileModels; std::vector<CModel*> FileModels;
for (u32 m = 0; m < mNumMeshes; m++) { for (u32 iMesh = 0; iMesh < mNumMeshes; iMesh++)
std::cout << "\rLoading mesh " << std::dec << m + 1 << "/" << mNumMeshes; {
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, mVersion); CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, mVersion);
FileModels.push_back(pModel); FileModels.push_back(pModel);
if (mVersion <= ePrime) if (mVersion <= ePrime)
mpArea->AddWorldModel(pModel); 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();
mBlockMgr->ToNextBlock(); mBlockMgr->ToNextBlock();
} }
@ -102,7 +111,6 @@ void CAreaLoader::ReadGeometryPrime()
} }
mpArea->MergeTerrain(); mpArea->MergeTerrain();
std::cout << "\n";
} }
void CAreaLoader::ReadSCLYPrime() void CAreaLoader::ReadSCLYPrime()
@ -341,22 +349,36 @@ void CAreaLoader::ReadGeometryCorruption()
mBlockMgr->ToNextBlock(); mBlockMgr->ToNextBlock();
// Geometry // Geometry
std::vector<CModel*> FileModels;
u32 CurWOBJSection = 1; u32 CurWOBJSection = 1;
u32 CurGPUSection = mGPUBlockNum; u32 CurGPUSection = mGPUBlockNum;
for (u32 iMesh = 0; iMesh < mNumMeshes; iMesh++) 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); CModel *pWorldModel = CModelLoader::LoadCorruptionWorldModel(*mpMREA, *mBlockMgr, *mpArea->mMaterialSet, CurWOBJSection, CurGPUSection, mVersion);
mpArea->AddWorldModel(pWorldModel); FileModels.push_back(pWorldModel);
CurWOBJSection += 4; CurWOBJSection += 4;
CurGPUSection = mBlockMgr->CurrentBlock(); 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(); mpArea->MergeTerrain();
std::cout << "\n";
} }
void CAreaLoader::ReadLightsCorruption() void CAreaLoader::ReadLightsCorruption()
@ -511,6 +533,14 @@ void CAreaLoader::ReadCollision()
mpArea->mCollision = CCollisionLoader::LoadAreaCollision(*mpMREA); 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() void CAreaLoader::SetUpObjects()
{ {
// Iterate over all objects // Iterate over all objects
@ -598,6 +628,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
Loader.ReadSCLYPrime(); Loader.ReadSCLYPrime();
Loader.ReadCollision(); Loader.ReadCollision();
Loader.ReadLightsPrime(); Loader.ReadLightsPrime();
Loader.ReadEGMC();
break; break;
case eEchoes: case eEchoes:
Loader.ReadHeaderEchoes(); Loader.ReadHeaderEchoes();
@ -605,6 +636,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
Loader.ReadSCLYEchoes(); Loader.ReadSCLYEchoes();
Loader.ReadCollision(); Loader.ReadCollision();
Loader.ReadLightsPrime(); Loader.ReadLightsPrime();
Loader.ReadEGMC();
break; break;
case eCorruptionProto: case eCorruptionProto:
Loader.ReadHeaderCorruption(); Loader.ReadHeaderCorruption();
@ -612,6 +644,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
Loader.ReadSCLYEchoes(); Loader.ReadSCLYEchoes();
Loader.ReadCollision(); Loader.ReadCollision();
Loader.ReadLightsCorruption(); Loader.ReadLightsCorruption();
Loader.ReadEGMC();
break; break;
case eCorruption: case eCorruption:
case eReturns: case eReturns:
@ -619,7 +652,11 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
Loader.ReadGeometryCorruption(); Loader.ReadGeometryCorruption();
Loader.ReadSCLYEchoes(); Loader.ReadSCLYEchoes();
Loader.ReadCollision(); Loader.ReadCollision();
if (Loader.mVersion == eCorruption) Loader.ReadLightsCorruption(); if (Loader.mVersion == eCorruption)
{
Loader.ReadLightsCorruption();
Loader.ReadEGMC();
}
break; break;
default: default:
Log::FileError(MREA.GetSourceString(), "Unsupported MREA version: " + TString::HexString(version)); Log::FileError(MREA.GetSourceString(), "Unsupported MREA version: " + TString::HexString(version));

View File

@ -75,6 +75,7 @@ class CAreaLoader
void ReadCompressedBlocks(); void ReadCompressedBlocks();
void Decompress(); void Decompress();
void ReadCollision(); void ReadCollision();
void ReadEGMC();
void SetUpObjects(); void SetUpObjects();
public: public:

View File

@ -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;
}

View File

@ -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

View File

@ -10,6 +10,7 @@ CModelNode::CModelNode(CScene *pScene, CSceneNode *pParent, CModel *pModel) : CS
mScale = CVector3f(1.f); mScale = CVector3f(1.f);
mLightingEnabled = true; mLightingEnabled = true;
mForceAlphaOn = false; mForceAlphaOn = false;
mTintColor = CColor::skWhite;
} }
ENodeType CModelNode::NodeType() ENodeType CModelNode::NodeType()
@ -103,6 +104,11 @@ SRayIntersection CModelNode::RayNodeIntersectTest(const CRay &Ray, u32 AssetID,
return out; return out;
} }
CColor CModelNode::TintColor(const SViewInfo& /*rkViewInfo*/) const
{
return mTintColor;
}
void CModelNode::SetModel(CModel *pModel) void CModelNode::SetModel(CModel *pModel)
{ {
mpModel = pModel; mpModel = pModel;
@ -116,8 +122,3 @@ void CModelNode::SetModel(CModel *pModel)
MarkTransformChanged(); MarkTransformChanged();
} }
void CModelNode::ForceAlphaEnabled(bool Enable)
{
mForceAlphaOn = Enable;
}

View File

@ -10,6 +10,7 @@ class CModelNode : public CSceneNode
u32 mActiveMatSet; u32 mActiveMatSet;
bool mLightingEnabled; bool mLightingEnabled;
bool mForceAlphaOn; bool mForceAlphaOn;
CColor mTintColor;
public: public:
explicit CModelNode(CScene *pScene, CSceneNode *pParent = 0, CModel *pModel = 0); explicit CModelNode(CScene *pScene, CSceneNode *pParent = 0, CModel *pModel = 0);
@ -20,41 +21,20 @@ public:
virtual void DrawSelection(); virtual void DrawSelection();
virtual void RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo); virtual void RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo);
virtual SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, 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 SetModel(CModel *pModel);
void SetMatSet(u32 MatSet);
void SetDynamicLighting(bool Enable); inline void SetMatSet(u32 MatSet) { mActiveMatSet = MatSet; }
void ForceAlphaEnabled(bool Enable); inline void SetDynamicLighting(bool Enable) { mLightingEnabled = Enable; }
CModel* Model(); inline void ForceAlphaEnabled(bool Enable) { mForceAlphaOn = Enable; }
u32 MatSet(); inline void SetTintColor(const CColor& rkTintColor) { mTintColor = rkTintColor; }
bool IsDynamicLightingEnabled(); 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 #endif // CMODELNODE_H

View File

@ -1,6 +1,7 @@
#include "CScene.h" #include "CScene.h"
#include "Core/Render/CGraphics.h" #include "Core/Render/CGraphics.h"
#include "Core/Resource/CResCache.h" #include "Core/Resource/CResCache.h"
#include "Core/Resource/CPoiToWorld.h"
#include "Core/Resource/Script/CScriptLayer.h" #include "Core/Resource/Script/CScriptLayer.h"
#include "Core/CRayCollisionTester.h" #include "Core/CRayCollisionTester.h"
@ -88,23 +89,24 @@ void CScene::SetActiveArea(CGameArea *pArea)
mpArea = pArea; mpArea = pArea;
mpAreaRootNode = new CRootNode(this, mpSceneRootNode); mpAreaRootNode = new CRootNode(this, mpSceneRootNode);
if (mSplitTerrain) // Create static nodes
{ u32 Count = mpArea->GetStaticModelCount();
u32 Count = mpArea->GetStaticModelCount();
for (u32 iMdl = 0; iMdl < Count; iMdl++) for (u32 iMdl = 0; iMdl < Count; iMdl++)
CreateStaticNode(mpArea->GetStaticModel(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++) // Create model nodes
{ Count = mpArea->GetTerrainModelCount();
CModel *pModel = mpArea->GetTerrainModel(iMdl);
CModelNode *pNode = CreateModelNode(pModel); for (u32 iMdl = 0; iMdl < Count; iMdl++)
pNode->SetDynamicLighting(false); {
} CModel *pModel = mpArea->GetTerrainModel(iMdl);
CModelNode *pNode = CreateModelNode(pModel);
pNode->SetName("World Model " + TString::FromInt32(iMdl, 0, 10));
pNode->SetDynamicLighting(false);
} }
CreateCollisionNode(mpArea->GetCollision()); CreateCollisionNode(mpArea->GetCollision());
@ -298,7 +300,8 @@ CGameArea* CScene::GetActiveArea()
FShowFlags CScene::ShowFlagsForNodeFlags(FNodeFlags NodeFlags) FShowFlags CScene::ShowFlagsForNodeFlags(FNodeFlags NodeFlags)
{ {
FShowFlags Out; FShowFlags Out;
if (NodeFlags & eStaticNode) Out |= eShowWorld; if (NodeFlags & eModelNode) Out |= eShowSplitWorld;
if (NodeFlags & eStaticNode) Out |= eShowMergedWorld;
if (NodeFlags & eScriptNode) Out |= eShowObjects; if (NodeFlags & eScriptNode) Out |= eShowObjects;
if (NodeFlags & eCollisionNode) Out |= eShowWorldCollision; if (NodeFlags & eCollisionNode) Out |= eShowWorldCollision;
if (NodeFlags & eLightNode) Out |= eShowLights; if (NodeFlags & eLightNode) Out |= eShowLights;
@ -307,8 +310,9 @@ FShowFlags CScene::ShowFlagsForNodeFlags(FNodeFlags NodeFlags)
FNodeFlags CScene::NodeFlagsForShowFlags(FShowFlags ShowFlags) FNodeFlags CScene::NodeFlagsForShowFlags(FShowFlags ShowFlags)
{ {
FNodeFlags Out = eRootNode | eModelNode; FNodeFlags Out = eRootNode;
if (ShowFlags & eShowWorld) Out |= eStaticNode; if (ShowFlags & eShowSplitWorld) Out |= eModelNode;
if (ShowFlags & eShowMergedWorld) Out |= eStaticNode;
if (ShowFlags & eShowWorldCollision) Out |= eCollisionNode; if (ShowFlags & eShowWorldCollision) Out |= eCollisionNode;
if (ShowFlags & eShowObjects) Out |= eScriptNode | eScriptExtraNode; if (ShowFlags & eShowObjects) Out |= eScriptNode | eScriptExtraNode;
if (ShowFlags & eShowLights) Out |= eLightNode; if (ShowFlags & eShowLights) Out |= eLightNode;

View File

@ -458,6 +458,11 @@ CScriptTemplate* CScriptNode::Template() const
return mpInstance->Template(); return mpInstance->Template();
} }
CScriptExtra* CScriptNode::Extra() const
{
return mpExtra;
}
CModel* CScriptNode::ActiveModel() const CModel* CScriptNode::ActiveModel() const
{ {
return mpActiveModel; return mpActiveModel;

View File

@ -7,10 +7,12 @@
#include "Core/Resource/Script/CScriptObject.h" #include "Core/Resource/Script/CScriptObject.h"
#include "Core/CLightParameters.h" #include "Core/CLightParameters.h"
class CScriptExtra;
class CScriptNode : public CSceneNode class CScriptNode : public CSceneNode
{ {
CScriptObject *mpInstance; CScriptObject *mpInstance;
class CScriptExtra *mpExtra; CScriptExtra *mpExtra;
TResPtr<CModel> mpActiveModel; TResPtr<CModel> mpActiveModel;
TResPtr<CTexture> mpBillboard; TResPtr<CTexture> mpBillboard;
@ -39,6 +41,7 @@ public:
void GeneratePosition(); void GeneratePosition();
CScriptObject* Object() const; CScriptObject* Object() const;
CScriptTemplate* Template() const; CScriptTemplate* Template() const;
CScriptExtra* Extra() const;
CModel* ActiveModel() const; CModel* ActiveModel() const;
bool UsesModel() const; bool UsesModel() const;
bool HasPreviewVolume() const; bool HasPreviewVolume() const;

View File

@ -1,3 +1,3 @@
#include "FShowFlags.h" #include "FShowFlags.h"
const FShowFlags gkGameModeShowFlags = eShowWorld | eShowObjectGeometry | eShowSky; const FShowFlags gkGameModeShowFlags = eShowMergedWorld | eShowObjectGeometry | eShowSky;

View File

@ -6,14 +6,15 @@
enum EShowFlag enum EShowFlag
{ {
eShowNone = 0x00, eShowNone = 0x00,
eShowWorld = 0x01, eShowSplitWorld = 0x01,
eShowWorldCollision = 0x02, eShowMergedWorld = 0x02,
eShowObjectGeometry = 0x04, eShowWorldCollision = 0x04,
eShowObjectCollision = 0x08, eShowObjectGeometry = 0x08,
eShowObjects = 0x0C, eShowObjectCollision = 0x10,
eShowLights = 0x10, eShowObjects = 0x18,
eShowSky = 0x20, eShowLights = 0x20,
eShowAll = 0x3F eShowSky = 0x40,
eShowAll = 0x7F
}; };
DECLARE_FLAGS(EShowFlag, FShowFlags) DECLARE_FLAGS(EShowFlag, FShowFlags)

View File

@ -15,6 +15,7 @@ public:
explicit CPointOfInterestExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0); explicit CPointOfInterestExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0);
void PropertyModified(IProperty* pProperty); void PropertyModified(IProperty* pProperty);
void ModifyTintColor(CColor& Color); void ModifyTintColor(CColor& Color);
CScan* GetScan() const { return mpScanData; }
static const CColor skRegularColor; static const CColor skRegularColor;
static const CColor skImportantColor; static const CColor skImportantColor;

View File

@ -10,6 +10,7 @@ CSceneViewport::CSceneViewport(QWidget *pParent)
: CBasicViewport(pParent), : CBasicViewport(pParent),
mpEditor(nullptr), mpEditor(nullptr),
mpScene(nullptr), mpScene(nullptr),
mRenderingMergedWorld(true),
mGizmoTransforming(false), mGizmoTransforming(false),
mpHoverNode(nullptr), mpHoverNode(nullptr),
mHoverPoint(CVector3f::skZero), mHoverPoint(CVector3f::skZero),
@ -22,7 +23,7 @@ CSceneViewport::CSceneViewport(QWidget *pParent)
mViewInfo.pScene = mpScene; mViewInfo.pScene = mpScene;
mViewInfo.pRenderer = mpRenderer; mViewInfo.pRenderer = mpRenderer;
mViewInfo.ShowFlags = eShowWorld | eShowObjectGeometry | eShowLights | eShowSky; mViewInfo.ShowFlags = eShowMergedWorld | eShowObjectGeometry | eShowLights | eShowSky;
CreateContextMenu(); CreateContextMenu();
} }
@ -46,6 +47,25 @@ void CSceneViewport::SetShowFlag(EShowFlag Flag, bool Visible)
mViewInfo.ShowFlags &= ~Flag; 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 FShowFlags CSceneViewport::ShowFlags() const
{ {
return mViewInfo.ShowFlags; return mViewInfo.ShowFlags;
@ -251,7 +271,7 @@ void CSceneViewport::ContextMenu(QContextMenuEvent* pEvent)
// Set up actions // Set up actions
TString NodeName; TString NodeName;
bool HasHoverNode = (mpHoverNode && mpHoverNode->NodeType() != eStaticNode); bool HasHoverNode = (mpHoverNode && (mpHoverNode->NodeType() != eStaticNode) && (mpHoverNode->NodeType() != eModelNode));
bool HasSelection = mpEditor->HasSelection(); bool HasSelection = mpEditor->HasSelection();
bool IsScriptNode = (mpHoverNode && mpHoverNode->NodeType() == eScriptNode); bool IsScriptNode = (mpHoverNode && mpHoverNode->NodeType() == eScriptNode);
@ -327,7 +347,7 @@ void CSceneViewport::OnMouseRelease(QMouseEvent *pEvent)
// Object selection/deselection // Object selection/deselection
else else
{ {
bool validNode = (mpHoverNode && (mpHoverNode->NodeType() != eStaticNode)); bool validNode = (mpHoverNode && (mpHoverNode->NodeType() != eStaticNode) && (mpHoverNode->NodeType() != eModelNode));
bool altPressed = ((pEvent->modifiers() & Qt::AltModifier) != 0); bool altPressed = ((pEvent->modifiers() & Qt::AltModifier) != 0);
bool ctrlPressed = ((pEvent->modifiers() & Qt::ControlModifier) != 0); bool ctrlPressed = ((pEvent->modifiers() & Qt::ControlModifier) != 0);

View File

@ -11,6 +11,7 @@ class CSceneViewport : public CBasicViewport
INodeEditor *mpEditor; INodeEditor *mpEditor;
CScene *mpScene; CScene *mpScene;
CRenderer *mpRenderer; CRenderer *mpRenderer;
bool mRenderingMergedWorld;
// Scene interaction // Scene interaction
bool mGizmoHovering; bool mGizmoHovering;
@ -37,6 +38,8 @@ public:
~CSceneViewport(); ~CSceneViewport();
void SetScene(INodeEditor *pEditor, CScene *pScene); void SetScene(INodeEditor *pEditor, CScene *pScene);
void SetShowFlag(EShowFlag Flag, bool Visible); void SetShowFlag(EShowFlag Flag, bool Visible);
void SetShowWorld(bool Visible);
void SetRenderMergedWorld(bool b);
FShowFlags ShowFlags() const; FShowFlags ShowFlags() const;
CRenderer* Renderer(); CRenderer* Renderer();
CSceneNode* HoverNode(); CSceneNode* HoverNode();

View File

@ -127,7 +127,9 @@ HEADERS += \
UICommon.h \ UICommon.h \
CErrorLogDialog.h \ CErrorLogDialog.h \
Undo/CSelectAllCommand.h \ Undo/CSelectAllCommand.h \
Undo/CInvertSelectionCommand.h Undo/CInvertSelectionCommand.h \
WorldEditor/CPoiMapEditDialog.h \
WorldEditor/CPoiMapModel.h
# Source Files # Source Files
SOURCES += \ SOURCES += \
@ -175,7 +177,9 @@ SOURCES += \
UICommon.cpp \ UICommon.cpp \
CErrorLogDialog.cpp \ CErrorLogDialog.cpp \
Undo/CSelectAllCommand.cpp \ Undo/CSelectAllCommand.cpp \
Undo/CInvertSelectionCommand.cpp Undo/CInvertSelectionCommand.cpp \
WorldEditor/CPoiMapEditDialog.cpp \
WorldEditor/CPoiMapModel.cpp
# UI Files # UI Files
FORMS += \ FORMS += \
@ -190,4 +194,5 @@ FORMS += \
WorldEditor/WCreateTab.ui \ WorldEditor/WCreateTab.ui \
WorldEditor/WInstancesTab.ui \ WorldEditor/WInstancesTab.ui \
WorldEditor/WModifyTab.ui \ WorldEditor/WModifyTab.ui \
CErrorLogDialog.ui CErrorLogDialog.ui \
WorldEditor/CPoiMapEditDialog.ui

View File

@ -1,5 +1,5 @@
<RCC> <RCC>
<qresource> <qresource prefix="/">
<file>icons/Down.png</file> <file>icons/Down.png</file>
<file>icons/Free Camera.png</file> <file>icons/Free Camera.png</file>
<file>icons/Material Highlight.png</file> <file>icons/Material Highlight.png</file>
@ -28,5 +28,7 @@
<file>icons/Unlink.png</file> <file>icons/Unlink.png</file>
<file>icons/World.png</file> <file>icons/World.png</file>
<file>icons/SelectMode.png</file> <file>icons/SelectMode.png</file>
<file>icons/POI Important.png</file>
<file>icons/POI Normal.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -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);
}

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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

View File

@ -28,6 +28,7 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
mpArea = nullptr; mpArea = nullptr;
mpWorld = nullptr; mpWorld = nullptr;
mpPoiDialog = nullptr;
mGizmoHovering = false; mGizmoHovering = false;
mGizmoTransforming = false; mGizmoTransforming = false;
@ -80,6 +81,12 @@ CWorldEditor::~CWorldEditor()
delete ui; delete ui;
} }
void CWorldEditor::closeEvent(QCloseEvent *)
{
if (mpPoiDialog)
mpPoiDialog->close();
}
bool CWorldEditor::eventFilter(QObject *pObj, QEvent *pEvent) bool CWorldEditor::eventFilter(QObject *pObj, QEvent *pEvent)
{ {
if (pObj == ui->MainDock) if (pObj == ui->MainDock)
@ -103,6 +110,12 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
ui->InstancesTabContents->SetArea(pArea); ui->InstancesTabContents->SetArea(pArea);
mUndoStack.clear(); mUndoStack.clear();
if (mpPoiDialog)
{
delete mpPoiDialog;
mpPoiDialog = nullptr;
}
// Clear old area - hack until better world/area loader is implemented // Clear old area - hack until better world/area loader is implemented
if ((mpArea) && (pArea != mpArea)) if ((mpArea) && (pArea != mpArea))
mpArea->ClearScriptLayers(); mpArea->ClearScriptLayers();
@ -160,7 +173,7 @@ void CWorldEditor::UpdateStatusBar()
{ {
CSceneNode *pHoverNode = ui->MainViewport->HoverNode(); CSceneNode *pHoverNode = ui->MainViewport->HoverNode();
if (pHoverNode && (pHoverNode->NodeType() != eStaticNode)) if (pHoverNode && (pHoverNode->NodeType() != eStaticNode) && (pHoverNode->NodeType() != eModelNode))
StatusText = TO_QSTRING(pHoverNode->Name()); StatusText = TO_QSTRING(pHoverNode->Name());
} }
} }
@ -259,7 +272,7 @@ void CWorldEditor::UpdateCursor()
if (ui->MainViewport->IsHoveringGizmo()) if (ui->MainViewport->IsHoveringGizmo())
ui->MainViewport->SetCursorState(Qt::SizeAllCursor); 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); ui->MainViewport->SetCursorState(Qt::PointingHandCursor);
else else
ui->MainViewport->SetCursorState(Qt::ArrowCursor); ui->MainViewport->SetCursorState(Qt::ArrowCursor);
@ -350,10 +363,17 @@ void CWorldEditor::OnTransformSpinBoxEdited(CVector3f)
UpdateGizmoUI(); UpdateGizmoUI();
} }
void CWorldEditor::OnClosePoiEditDialog()
{
delete mpPoiDialog;
mpPoiDialog = nullptr;
ui->MainViewport->SetRenderMergedWorld(true);
}
// These functions are from "Go to slot" in the designer // These functions are from "Go to slot" in the designer
void CWorldEditor::on_ActionDrawWorld_triggered() void CWorldEditor::on_ActionDrawWorld_triggered()
{ {
ui->MainViewport->SetShowFlag(eShowWorld, ui->ActionDrawWorld->isChecked()); ui->MainViewport->SetShowWorld(ui->ActionDrawWorld->isChecked());
} }
void CWorldEditor::on_ActionDrawCollision_triggered() void CWorldEditor::on_ActionDrawCollision_triggered()
@ -477,13 +497,28 @@ void CWorldEditor::on_ActionGameMode_triggered()
void CWorldEditor::on_ActionSelectAll_triggered() void CWorldEditor::on_ActionSelectAll_triggered()
{ {
FNodeFlags NodeFlags = CScene::NodeFlagsForShowFlags(ui->MainViewport->ShowFlags()); FNodeFlags NodeFlags = CScene::NodeFlagsForShowFlags(ui->MainViewport->ShowFlags());
NodeFlags &= ~(eStaticNode | eCollisionNode); NodeFlags &= ~(eModelNode | eStaticNode | eCollisionNode);
SelectAll(NodeFlags); SelectAll(NodeFlags);
} }
void CWorldEditor::on_ActionInvertSelection_triggered() void CWorldEditor::on_ActionInvertSelection_triggered()
{ {
FNodeFlags NodeFlags = CScene::NodeFlagsForShowFlags(ui->MainViewport->ShowFlags()); FNodeFlags NodeFlags = CScene::NodeFlagsForShowFlags(ui->MainViewport->ShowFlags());
NodeFlags &= ~(eStaticNode | eCollisionNode); NodeFlags &= ~(eModelNode | eStaticNode | eCollisionNode);
InvertSelection(NodeFlags); 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();
}
}

View File

@ -1,6 +1,7 @@
#ifndef CWORLDEDITOR_H #ifndef CWORLDEDITOR_H
#define CWORLDEDITOR_H #define CWORLDEDITOR_H
#include "CPoiMapEditDialog.h"
#include "Editor/INodeEditor.h" #include "Editor/INodeEditor.h"
#include "Editor/CGizmo.h" #include "Editor/CGizmo.h"
@ -34,9 +35,12 @@ class CWorldEditor : public INodeEditor
TResPtr<CGameArea> mpArea; TResPtr<CGameArea> mpArea;
QTimer mRefreshTimer; QTimer mRefreshTimer;
CPoiMapEditDialog *mpPoiDialog;
public: public:
explicit CWorldEditor(QWidget *parent = 0); explicit CWorldEditor(QWidget *parent = 0);
~CWorldEditor(); ~CWorldEditor();
void closeEvent(QCloseEvent *);
bool eventFilter(QObject *pObj, QEvent *pEvent); bool eventFilter(QObject *pObj, QEvent *pEvent);
void SetArea(CWorld *pWorld, CGameArea *pArea); void SetArea(CWorld *pWorld, CGameArea *pArea);
CGameArea* ActiveArea(); CGameArea* ActiveArea();
@ -58,6 +62,7 @@ private slots:
void OnCameraSpeedChange(double speed); void OnCameraSpeedChange(double speed);
void OnTransformSpinBoxModified(CVector3f value); void OnTransformSpinBoxModified(CVector3f value);
void OnTransformSpinBoxEdited(CVector3f value); void OnTransformSpinBoxEdited(CVector3f value);
void OnClosePoiEditDialog();
void on_ActionDrawWorld_triggered(); void on_ActionDrawWorld_triggered();
void on_ActionDrawCollision_triggered(); void on_ActionDrawCollision_triggered();
void on_ActionDrawObjects_triggered(); void on_ActionDrawObjects_triggered();
@ -79,6 +84,7 @@ private slots:
void on_ActionGameMode_triggered(); void on_ActionGameMode_triggered();
void on_ActionSelectAll_triggered(); void on_ActionSelectAll_triggered();
void on_ActionInvertSelection_triggered(); void on_ActionInvertSelection_triggered();
void on_ActionEditPoiToWorldMap_triggered();
}; };
#endif // CWORLDEDITOR_H #endif // CWORLDEDITOR_H

View File

@ -289,6 +289,7 @@
<string>Tools</string> <string>Tools</string>
</property> </property>
<addaction name="ActionEditLayers"/> <addaction name="ActionEditLayers"/>
<addaction name="ActionEditPoiToWorldMap"/>
</widget> </widget>
<addaction name="menuFile"/> <addaction name="menuFile"/>
<addaction name="menuEdit"/> <addaction name="menuEdit"/>
@ -758,6 +759,11 @@
<string>Ctrl+I</string> <string>Ctrl+I</string>
</property> </property>
</action> </action>
<action name="ActionEditPoiToWorldMap">
<property name="text">
<string>Edit POI to World Map</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -173,6 +173,9 @@
<attribute name="horizontalHeaderStretchLastSection"> <attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>21</number>
</attribute>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -195,6 +198,9 @@
<attribute name="horizontalHeaderDefaultSectionSize"> <attribute name="horizontalHeaderDefaultSectionSize">
<number>75</number> <number>75</number>
</attribute> </attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>21</number>
</attribute>
</widget> </widget>
</item> </item>
</layout> </layout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -7,13 +7,16 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Create application
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QApplication app(argc, argv); QApplication app(argc, argv);
CStartWindow w; CStartWindow w;
w.show(); w.show();
// Load templates
CTemplateLoader::LoadGameList(); CTemplateLoader::LoadGameList();
// Set up dark style
app.setStyle(new CDarkStyle); app.setStyle(new CDarkStyle);
qApp->setStyle(QStyleFactory::create("Fusion")); qApp->setStyle(QStyleFactory::create("Fusion"));
@ -35,5 +38,6 @@ int main(int argc, char *argv[])
qApp->setPalette(darkPalette); qApp->setPalette(darkPalette);
// Execute application
return app.exec(); return app.exec();
} }