Fixed various bugs and crashes and moved more functionality into the world editor

This commit is contained in:
Aruki 2017-02-13 13:44:02 -07:00
parent 00a48e69f8
commit c5de322ac7
13 changed files with 105 additions and 148 deletions

View File

@ -22,7 +22,7 @@ void main()
const float kMaxDepth = 75.0; // Controls the max depth range that kDepthTintNear and kDepthTintFar are interpolated between
const float kDepthTintNear = 0.0; // Sets the pixel color offset for pixels close to the screen
const float kDepthTintFar = -0.2; // Sets the pixel color offset for pixels far from the screen
const float kDepthCurveFactor = 2; // Controls the strength of the interpolation curve (higher = color chabges faster from up close and slower from further away)
const float kDepthCurveFactor = 2; // Controls the strength of the interpolation curve (higher = color changes faster from up close and slower from further away)
// Apply some fake fog so pixels closer to the camera appear slightly brighter
float Depth = ( (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near) ) / gl_FragCoord.w;

View File

@ -356,6 +356,7 @@ CResource* CResourceEntry::LoadCooked(IInputStream& rInput)
bool CResourceEntry::Unload()
{
ASSERT(mpResource != nullptr);
ASSERT(!mpResource->IsReferenced());
delete mpResource;
mpResource = nullptr;
return true;

View File

@ -277,6 +277,21 @@ void CResourceStore::CloseProject()
// various TResPtrs are destroyed. There might be a cleaner solution than this.)
DestroyUnreferencedResources();
// There should be no loaded resources!!!
// If there are, that means something didn't clean up resource references properly on project close!!!
if (!mLoadedResources.empty())
{
Log::Error(TString::FromInt32(mLoadedResources.size(), 0, 10) + " resources still loaded on project close:");
for (auto Iter = mLoadedResources.begin(); Iter != mLoadedResources.end(); Iter++)
{
CResourceEntry *pEntry = Iter->second;
Log::Write("\t" + pEntry->Name().ToUTF8() + "." + pEntry->CookedExtension().ToString());
}
ASSERT(false);
}
// Delete all entries from old project
auto It = mResourceEntries.begin();
@ -286,16 +301,6 @@ void CResourceStore::CloseProject()
if (!pEntry->IsTransient())
{
if (pEntry->IsLoaded())
{
bool UnloadSuccess = pEntry->Unload();
ASSERT(UnloadSuccess);
auto LoadIt = mLoadedResources.find(pEntry->ID());
ASSERT(LoadIt != mLoadedResources.end());
mLoadedResources.erase(LoadIt);
}
delete pEntry;
It = mResourceEntries.erase(It);
}

View File

@ -172,12 +172,13 @@ void CScene::DeleteNode(CSceneNode *pNode)
mNumNodes--;
}
void CScene::SetActiveArea(CGameArea *pArea)
void CScene::SetActiveArea(CWorld *pWorld, CGameArea *pArea)
{
// Clear existing area
ClearScene();
// Create nodes for new area
mpWorld = pWorld;
mpArea = pArea;
mpAreaRootNode = new CRootNode(this, -1, mpSceneRootNode);
@ -248,11 +249,6 @@ void CScene::SetActiveArea(CGameArea *pArea)
Log::Write( TString::FromInt32(CSceneNode::NumNodes(), 0, 10) + " nodes" );
}
void CScene::SetActiveWorld(CWorld* pWorld)
{
mpWorld = pWorld;
}
void CScene::PostLoad()
{
mpSceneRootNode->OnLoadFinished();
@ -265,6 +261,7 @@ void CScene::ClearScene()
{
mpAreaRootNode->Unparent();
delete mpAreaRootNode;
mpAreaRootNode = nullptr;
}
mNodes.clear();
@ -274,6 +271,7 @@ void CScene::ClearScene()
mNumNodes = 0;
mpArea = nullptr;
mpWorld = nullptr;
}
void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo)

View File

@ -56,8 +56,7 @@ public:
CScriptNode* CreateScriptNode(CScriptObject *pObj, u32 NodeID = -1);
CLightNode* CreateLightNode(CLight *pLight, u32 NodeID = -1);
void DeleteNode(CSceneNode *pNode);
void SetActiveArea(CGameArea *pArea);
void SetActiveWorld(CWorld *pWorld);
void SetActiveArea(CWorld *pWorld, CGameArea *pArea);
void PostLoad();
void ClearScene();
void AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo);

View File

@ -16,11 +16,6 @@ CProjectOverviewDialog::CProjectOverviewDialog(QWidget *pParent)
{
mpUI->setupUi(this);
connect(mpUI->OpenProjectButton, SIGNAL(clicked()), this, SLOT(OpenProject()));
connect(mpUI->ExportGameButton, SIGNAL(clicked()), this, SLOT(ExportGame()));
connect(mpUI->LoadWorldButton, SIGNAL(clicked()), this, SLOT(LoadWorld()));
connect(mpUI->LaunchEditorButton, SIGNAL(clicked()), this, SLOT(LaunchEditor()));
connect(mpUI->ViewResourcesButton, SIGNAL(clicked()), this, SLOT(LaunchResourceBrowser()));
connect(mpUI->CookPackageButton, SIGNAL(clicked()), this, SLOT(CookPackage()));
connect(mpUI->CookAllDirtyPackagesButton, SIGNAL(clicked(bool)), this, SLOT(CookAllDirtyPackages()));
@ -36,59 +31,13 @@ CProjectOverviewDialog::~CProjectOverviewDialog()
void CProjectOverviewDialog::ActiveProjectChanged(CGameProject *pProj)
{
mpProject = pProj;
SetupWorldsList();
SetupPackagesList();
}
void CProjectOverviewDialog::ExportGame()
{
QString IsoPath = UICommon::OpenFileDialog(this, "Select ISO", "*.iso *.gcm *.tgc *.wbfs");
if (IsoPath.isEmpty()) return;
QString ExportDir = UICommon::OpenDirDialog(this, "Select output export directory");
if (ExportDir.isEmpty()) return;
CExportGameDialog ExportDialog(IsoPath, ExportDir, this);
if (ExportDialog.HasValidDisc()) ExportDialog.exec();
if (ExportDialog.ExportSucceeded())
{
int OpenChoice = QMessageBox::information(this, "Export complete", "Export finished successfully! Open new project?", QMessageBox::Yes, QMessageBox::No);
if (OpenChoice == QMessageBox::Yes)
gpEdApp->OpenProject(ExportDialog.ProjectPath());
}
}
void CProjectOverviewDialog::SetupWorldsList()
{
std::list<CAssetID> WorldIDs;
mpProject->GetWorldList(WorldIDs);
mWorldEntries.clear();
mpUI->WorldsList->clear();
for (auto It = WorldIDs.begin(); It != WorldIDs.end(); It++)
{
CAssetID ID = *It;
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
if (!pEntry)
{
Log::Error("Couldn't find entry for world: " + ID.ToString());
continue;
}
mWorldEntries << pEntry;
mpUI->WorldsList->addItem(TO_QSTRING(pEntry->Name()));
}
mpUI->AreasGroupBox->setEnabled(false);
mpUI->LoadWorldButton->setEnabled(!mWorldEntries.isEmpty());
}
void CProjectOverviewDialog::SetupPackagesList()
{
mpUI->PackagesList->clear();
if (!mpProject) return;
for (u32 iPkg = 0; iPkg < mpProject->NumPackages(); iPkg++)
{
@ -101,63 +50,6 @@ void CProjectOverviewDialog::SetupPackagesList()
}
}
void CProjectOverviewDialog::LoadWorld()
{
// Find world
u32 WorldIdx = mpUI->WorldsList->currentRow();
CResourceEntry *pWorldEntry = mWorldEntries[WorldIdx];
mpWorld = pWorldEntry->Load();
mAreaEntries.clear();
mpUI->AreaComboBox->clear();
if (mpWorld)
{
for (u32 iArea = 0; iArea < mpWorld->NumAreas(); iArea++)
{
CResourceEntry *pAreaEntry = gpResourceStore->FindEntry( mpWorld->AreaResourceID(iArea) );
if (pAreaEntry)
{
mAreaEntries << pAreaEntry;
mpUI->AreaComboBox->addItem(TO_QSTRING(pAreaEntry->Name()));
}
}
}
mpUI->AreasGroupBox->setEnabled(true);
mpUI->AreaComboBox->setEnabled(!mAreaEntries.isEmpty());
mpUI->LaunchEditorButton->setEnabled(!mAreaEntries.isEmpty());
gpResourceStore->DestroyUnreferencedResources();
}
void CProjectOverviewDialog::LaunchEditor()
{
// Load area
u32 AreaIdx = mpUI->AreaComboBox->currentIndex();
CResourceEntry *pAreaEntry = mAreaEntries[AreaIdx];
CGameArea *pArea = (CGameArea*) pAreaEntry->Load();
if (pArea)
{
pArea->SetWorldIndex(AreaIdx);
mpWorld->SetAreaLayerInfo(pArea);
gpEdApp->WorldEditor()->SetArea(mpWorld, AreaIdx);
gpEdApp->WorldEditor()->showMaximized();
}
else
Log::Error("Failed to load area");
gpResourceStore->DestroyUnreferencedResources();
}
void CProjectOverviewDialog::LaunchResourceBrowser()
{
gpEdApp->ResourceBrowser()->show();
gpEdApp->ResourceBrowser()->raise();
}
void CProjectOverviewDialog::CookPackage()
{
u32 PackageIdx = mpUI->PackagesList->currentRow();

View File

@ -26,15 +26,9 @@ public:
public slots:
void ActiveProjectChanged(CGameProject *pProj);
void ExportGame();
void LoadWorld();
void LaunchEditor();
void LaunchResourceBrowser();
void SetupPackagesList();
void CookPackage();
void CookAllDirtyPackages();
void SetupWorldsList();
void SetupPackagesList();
};
#endif // CPROJECTOVERVIEWDIALOG_H

View File

@ -12,7 +12,7 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
: QDialog(pParent)
, mpUI(new Ui::CResourceBrowser)
, mpSelectedEntry(nullptr)
, mpStore(gpResourceStore)
, mpStore(nullptr)
, mpSelectedDir(nullptr)
, mAssetListMode(true)
, mSearching(false)
@ -232,7 +232,10 @@ void CResourceBrowser::UpdateDescriptionLabel()
void CResourceBrowser::UpdateStore()
{
int StoreIndex = mpUI->StoreComboBox->currentIndex();
CResourceStore *pNewStore = (StoreIndex == 0 ? gpResourceStore : gpEditorStore);
CGameProject *pProj = gpEdApp->ActiveProject();
CResourceStore *pProjStore = (pProj ? pProj->ResourceStore() : nullptr);
CResourceStore *pNewStore = (StoreIndex == 0 ? pProjStore : gpEditorStore);
if (mpStore != pNewStore)
{

View File

@ -53,6 +53,11 @@ CResourceSelector::CResourceSelector(QWidget *pParent /*= 0*/)
mpLayout->setContentsMargins(0, 0, 0, 0);
setLayout(mpLayout);
// Font
QFont Font = font();
Font.setPointSize(10);
setFont(Font);
// UI Connections
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CreateContextMenu(QPoint)));
connect(mpSetButton, SIGNAL(clicked()), this, SLOT(Set()));

View File

@ -9,6 +9,7 @@
#include "WInstancesTab.h"
#include "Editor/CBasicViewport.h"
#include "Editor/CExportGameDialog.h"
#include "Editor/CNodeCopyMimeData.h"
#include "Editor/CPakToolDialog.h"
#include "Editor/CSelectionIterator.h"
@ -53,7 +54,7 @@ CWorldEditor::CWorldEditor(QWidget *parent)
ui->splitter->setSizes(SplitterSizes);
// Initialize UI stuff
ui->MainViewport->Camera().Snap(CVector3f(0.f, 5.f, 1.f));
ResetCamera();
ui->MainViewport->SetScene(this, &mScene);
ui->MainViewport->setAcceptDrops(true);
ui->TransformSpinBox->SetOrientation(Qt::Horizontal);
@ -110,6 +111,26 @@ CWorldEditor::CWorldEditor(QWidget *parent)
mpCollisionDialog = new CCollisionRenderSettingsDialog(this, this);
// Resource Browser button
QPushButton *pBrowserButton = new QPushButton(this);
pBrowserButton->setText("Resource Browser");
connect(pBrowserButton, SIGNAL(pressed()), this, SLOT(OpenResourceBrowser()));
QPalette Palette = pBrowserButton->palette();
QBrush ButtonBrush = Palette.button();
ButtonBrush.setColor( QColor(36, 100, 100) );
Palette.setBrush(QPalette::Button, ButtonBrush);
pBrowserButton->setPalette(Palette);
QFont BrowserButtonFont = pBrowserButton->font();
BrowserButtonFont.setPointSize( BrowserButtonFont.pointSize() + 3 );
pBrowserButton->setFont(BrowserButtonFont);
QWidget *pSpacerWidget = new QWidget(this);
pSpacerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
ui->MainToolBar->addWidget(pSpacerWidget);
ui->MainToolBar->addWidget(pBrowserButton);
// "Open Recent" menu
mpOpenRecentMenu = new QMenu(this);
ui->ActionOpenRecent->setMenu(mpOpenRecentMenu);
@ -149,6 +170,10 @@ CWorldEditor::CWorldEditor(QWidget *parent)
connect(ui->ActionOpenProject, SIGNAL(triggered()), this, SLOT(OpenProject()));
connect(ui->ActionSave, SIGNAL(triggered()) , this, SLOT(Save()));
connect(ui->ActionSaveAndRepack, SIGNAL(triggered()), this, SLOT(SaveAndRepack()));
connect(ui->ActionExportGame, SIGNAL(triggered()), this, SLOT(ExportGame()));
connect(ui->ActionCloseProject, SIGNAL(triggered()), this, SLOT(CloseProject()));
connect(ui->ActionExit, SIGNAL(triggered()), this, SLOT(close()));
connect(ui->ActionCut, SIGNAL(triggered()), this, SLOT(Cut()));
connect(ui->ActionCopy, SIGNAL(triggered()), this, SLOT(Copy()));
connect(ui->ActionPaste, SIGNAL(triggered()), this, SLOT(Paste()));
@ -216,6 +241,7 @@ bool CWorldEditor::CloseWorld()
ExitPickMode();
ClearSelection();
ui->MainViewport->ResetHover();
mScene.ClearScene();
mUndoStack.clear();
mpCollisionDialog->close();
@ -262,9 +288,7 @@ bool CWorldEditor::SetArea(CWorld *pWorld, int AreaIndex)
mpArea = pAreaEntry->Load();
ASSERT(mpArea);
mpWorld->SetAreaLayerInfo(mpArea);
mScene.SetActiveWorld(mpWorld);
mScene.SetActiveArea(mpArea);
mScene.SetActiveArea(mpWorld, mpArea);
// Snap camera to new area
CCamera *pCamera = &ui->MainViewport->Camera();
@ -353,6 +377,11 @@ bool CWorldEditor::CheckUnsavedChanges()
return OkToClear;
}
void CWorldEditor::ResetCamera()
{
ui->MainViewport->Camera().Snap(CVector3f(0.f, 5.f, 1.f));
}
bool CWorldEditor::HasAnyScriptNodesSelected() const
{
for (CSelectionIterator It(mpSelection); It; ++It)
@ -446,11 +475,6 @@ void CWorldEditor::OpenRecentProject()
}
}
void CWorldEditor::CloseProject()
{
gpEdApp->CloseProject();
}
bool CWorldEditor::Save()
{
if (!mpArea)
@ -483,6 +507,31 @@ bool CWorldEditor::SaveAndRepack()
return true;
}
void CWorldEditor::ExportGame()
{
QString IsoPath = UICommon::OpenFileDialog(this, "Select ISO", "*.iso *.gcm *.tgc *.wbfs");
if (IsoPath.isEmpty()) return;
QString ExportDir = UICommon::OpenDirDialog(this, "Select output export directory");
if (ExportDir.isEmpty()) return;
CExportGameDialog ExportDialog(IsoPath, ExportDir, this);
if (ExportDialog.HasValidDisc()) ExportDialog.exec();
if (ExportDialog.ExportSucceeded())
{
int OpenChoice = QMessageBox::information(this, "Export complete", "Export finished successfully! Open new project?", QMessageBox::Yes, QMessageBox::No);
if (OpenChoice == QMessageBox::Yes)
gpEdApp->OpenProject(ExportDialog.ProjectPath());
}
}
void CWorldEditor:: CloseProject()
{
gpEdApp->CloseProject();
}
void CWorldEditor::ChangeEditMode(int Mode)
{
// This function is connected to the edit mode QButtonGroup.
@ -521,6 +570,7 @@ void CWorldEditor::OpenResourceBrowser()
void CWorldEditor::OnActiveProjectChanged(CGameProject *pProj)
{
ui->ActionCloseProject->setEnabled( pProj != nullptr );
ResetCamera();
if (!pProj) return;
// Update recent projects list

View File

@ -78,6 +78,7 @@ public:
bool CloseWorld();
bool SetArea(CWorld *pWorld, int AreaIndex);
bool CheckUnsavedChanges();
void ResetCamera();
bool HasAnyScriptNodesSelected() const;
inline CWorld* ActiveWorld() const { return mpWorld; }
@ -101,9 +102,10 @@ public slots:
void OpenProject();
void OpenRecentProject();
void CloseProject();
bool Save();
bool SaveAndRepack();
void ExportGame();
void CloseProject();
void ChangeEditMode(int Mode);
void ChangeEditMode(EWorldEditorMode Mode);

View File

@ -57,6 +57,8 @@ void CWorldInfoSidebar::OnActiveProjectChanged(CGameProject *pProj)
mpUI->ProjectInfoWidget->setHidden( pProj == nullptr );
mpUI->WorldInfoWidget->setHidden(true);
mpUI->AreaInfoWidget->setHidden(true);
mpUI->AreaSearchLineEdit->clear();
mProxyModel.SetFilterString("");
bool IsEchoes = pProj && (pProj->Game() == eEchoesDemo || pProj->Game() == eEchoes);
mpUI->GameNameLabel->setText( pProj ? TO_QSTRING(pProj->Name()) : "" );

View File

@ -231,7 +231,13 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="AreaNameLineEdit"/>
<widget class="QLineEdit" name="AreaNameLineEdit">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="AreaLabel">