diff --git a/src/Core/Render/SViewInfo.h b/src/Core/Render/SViewInfo.h index a3019493..2c75e3d0 100644 --- a/src/Core/Render/SViewInfo.h +++ b/src/Core/Render/SViewInfo.h @@ -1,6 +1,7 @@ #ifndef SVIEWINFO #define SVIEWINFO +#include "Core/Resource/CCollisionMaterial.h" #include "Core/Scene/FShowFlags.h" #include #include @@ -10,6 +11,8 @@ struct SCollisionRenderSettings { u64 HighlightMask; u64 HideMask; + + CCollisionMaterial HideMaterial; bool DrawWireframe; bool DrawBackfaces; bool DrawAreaCollisionBounds; @@ -23,7 +26,7 @@ struct SCollisionRenderSettings , DrawBackfaces(false) , DrawAreaCollisionBounds(true) , TintWithSurfaceColor(true) - , TintUnwalkableTris(false) {} + , TintUnwalkableTris(true) {} }; struct SViewInfo diff --git a/src/Core/Resource/CCollisionMaterial.cpp b/src/Core/Resource/CCollisionMaterial.cpp index 046071bc..c7e5abcd 100644 --- a/src/Core/Resource/CCollisionMaterial.cpp +++ b/src/Core/Resource/CCollisionMaterial.cpp @@ -1,6 +1,6 @@ #include "CCollisionMaterial.h" #include "EGame.h" -#include +#include ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const { @@ -42,7 +42,7 @@ ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const } // Type-to-color mappings -const std::map gkTypeToColor = { +const std::unordered_map gkTypeToColor = { { eCF_Stone, CColor::Integral(220, 215, 160) }, // Brownish/greenish { eCF_Metal, CColor::Integral(143, 143, 143) }, // Gray { eCF_Grass, CColor::Integral( 90, 150, 70) }, // Green diff --git a/src/Core/Resource/CCollisionMesh.cpp b/src/Core/Resource/CCollisionMesh.cpp index d9c3ad0c..dc85a462 100644 --- a/src/Core/Resource/CCollisionMesh.cpp +++ b/src/Core/Resource/CCollisionMesh.cpp @@ -122,7 +122,7 @@ void CCollisionMesh::Draw() mVBO.Unbind(); } -void CCollisionMesh::DrawMaterial(u32 MatIdx) +void CCollisionMesh::DrawMaterial(u32 MatIdx, bool Wireframe) { if (!mBuffered) BufferGL(); ASSERT(MatIdx < mMaterials.size()); @@ -130,7 +130,18 @@ void CCollisionMesh::DrawMaterial(u32 MatIdx) mVBO.Bind(); u32 StartIdx = (MatIdx == 0 ? 0 : mMaterialOffsets[MatIdx - 1]); u32 NumElements = mMaterialOffsets[MatIdx] - StartIdx; + + if (Wireframe) + { + CDrawUtil::UseColorShader(CColor::skBlack); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + mIBO.DrawElements(StartIdx, NumElements); + + if (Wireframe) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + mVBO.Unbind(); } diff --git a/src/Core/Resource/CCollisionMesh.h b/src/Core/Resource/CCollisionMesh.h index 797f143e..bd9bbe59 100644 --- a/src/Core/Resource/CCollisionMesh.h +++ b/src/Core/Resource/CCollisionMesh.h @@ -78,7 +78,7 @@ public: void BufferGL(); void Draw(); - void DrawMaterial(u32 MatIdx); + void DrawMaterial(u32 MatIdx, bool Wireframe); void DrawWireframe(); inline u32 NumMaterials() const { return mMaterials.size(); } diff --git a/src/Core/Scene/CCollisionNode.cpp b/src/Core/Scene/CCollisionNode.cpp index a2e2b61d..fcd0b65b 100644 --- a/src/Core/Scene/CCollisionNode.cpp +++ b/src/Core/Scene/CCollisionNode.cpp @@ -54,7 +54,10 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER { CCollisionMaterial& rMat = pMesh->GetMaterial(iMat); - if (rkViewInfo.CollisionSettings.HideMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HideMask) == rkViewInfo.CollisionSettings.HideMask) + if (rkViewInfo.CollisionSettings.HideMaterial & rMat) + continue; + + if (rkViewInfo.CollisionSettings.HideMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HideMask) != 0) continue; CColor Tint = BaseTint; @@ -65,17 +68,14 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER else if (CollisionGame != eReturns && rkViewInfo.CollisionSettings.TintWithSurfaceColor) Tint *= rMat.SurfaceColor(CollisionGame); - bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_Floor) : true); - bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_JumpNotAllowed) : false); + bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_Floor) : true) || CollisionGame == eReturns; + bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_JumpNotAllowed) : false) && CollisionGame != eReturns; CDrawUtil::UseCollisionShader(IsFloor, IsUnstandable, Tint); - pMesh->DrawMaterial(iMat); - } - } + pMesh->DrawMaterial(iMat, false); - if (rkViewInfo.CollisionSettings.DrawWireframe) - { - CDrawUtil::UseColorShader(CColor::skTransparentBlack); - mpCollision->DrawWireframe(); + if (rkViewInfo.CollisionSettings.DrawWireframe) + pMesh->DrawMaterial(iMat, true); + } } // Restore backface culling setting @@ -85,7 +85,7 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER // Draw collision bounds for area collision // note: right now checking parent is the best way to check whether this node is area collision instead of actor collision // actor collision will have a script node parent whereas area collision will have a root node parent - if (rkViewInfo.CollisionSettings.DrawAreaCollisionBounds && Parent()->NodeType() == eRootNode) + if (rkViewInfo.CollisionSettings.DrawAreaCollisionBounds && Parent()->NodeType() == eRootNode && CollisionGame != eReturns) CDrawUtil::DrawWireCube( mpCollision->MeshByIndex(0)->BoundingBox(), CColor::skRed ); } diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp index 79f17e60..2a9589b8 100644 --- a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp @@ -10,9 +10,20 @@ CCollisionRenderSettingsDialog::CCollisionRenderSettingsDialog(CWorldEditor *pEd { mpUi->setupUi(this); + SetupWidgets(); connect(mpUi->HideMaskLineEdit, SIGNAL(textChanged(QString)), this, SLOT(OnHideMaskChanged(QString))); connect(mpUi->HighlightMaskLineEdit, SIGNAL(textChanged(QString)), this, SLOT(OnHighlightMaskChanged(QString))); connect(mpUi->WireframeCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnWireframeToggled(bool))); + connect(mpUi->SurfaceTypeCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnSurfaceTypeToggled(bool))); + connect(mpUi->StandableTrisCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnStandableTrisToggled(bool))); + connect(mpUi->AreaBoundsCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnAreaBoundsToggled(bool))); + connect(mpUi->BackfacesCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnBackfacesToggled(bool))); + + connect(mpUi->HideShootThruCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); + connect(mpUi->HideCameraThruCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); + connect(mpUi->HideScanThruCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); + connect(mpUi->HideAiWalkThruCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); + connect(mpUi->HideAiBlockCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); } CCollisionRenderSettingsDialog::~CCollisionRenderSettingsDialog() @@ -20,6 +31,40 @@ CCollisionRenderSettingsDialog::~CCollisionRenderSettingsDialog() delete mpUi; } +void CCollisionRenderSettingsDialog::SetupWidgets() +{ + SCollisionRenderSettings& rSettings = mpEditor->Viewport()->CollisionRenderSettings(); + EGame Game = mpEditor->CurrentGame(); + + // Set widgets to match current render setting values + mpUi->HideMaskLineEdit->setText( "0x" + QString::number(rSettings.HideMask, 16).toUpper() ); + mpUi->HighlightMaskLineEdit->setText( "0x" + QString::number(rSettings.HighlightMask, 16).toUpper() ); + mpUi->WireframeCheckBox->setChecked(rSettings.DrawWireframe); + mpUi->SurfaceTypeCheckBox->setChecked(rSettings.TintWithSurfaceColor); + mpUi->StandableTrisCheckBox->setChecked(rSettings.TintUnwalkableTris); + mpUi->AreaBoundsCheckBox->setChecked(rSettings.DrawAreaCollisionBounds); + mpUi->BackfacesCheckBox->setChecked(rSettings.DrawBackfaces); + + mpUi->HideShootThruCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_ShootThru)); + mpUi->HideCameraThruCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_CameraThru)); + mpUi->HideScanThruCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_ScanThru)); + mpUi->HideAiWalkThruCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_AiWalkThru)); + mpUi->HideAiBlockCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_AiBlock)); + + // Toggle visibility of game-exclusive widgets + mpUi->SurfaceTypeCheckBox->setHidden( Game == eReturns ); + mpUi->StandableTrisCheckBox->setHidden( Game == eReturns ); + mpUi->AreaBoundsCheckBox->setHidden( Game == eReturns ); + mpUi->BackfacesCheckBox->setHidden( Game == eReturns ); + + mpUi->VisibilityGroupBox->setHidden( Game == eReturns ); + mpUi->HideShootThruCheckBox->setHidden( Game == eReturns ); + mpUi->HideCameraThruCheckBox->setHidden( Game == eReturns ); + mpUi->HideScanThruCheckBox->setHidden( Game == eReturns ); + mpUi->HideAiWalkThruCheckBox->setHidden( Game == eReturns ); + mpUi->HideAiBlockCheckBox->setHidden( Game < eEchoesDemo || Game == eReturns ); +} + void CCollisionRenderSettingsDialog::OnHideMaskChanged(QString NewMask) { TString MaskStr = TO_TSTRING(NewMask); @@ -38,3 +83,33 @@ void CCollisionRenderSettingsDialog::OnWireframeToggled(bool Enable) { mpEditor->Viewport()->CollisionRenderSettings().DrawWireframe = Enable; } + +void CCollisionRenderSettingsDialog::OnSurfaceTypeToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().TintWithSurfaceColor = Enable; +} + +void CCollisionRenderSettingsDialog::OnStandableTrisToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().TintUnwalkableTris = Enable; +} + +void CCollisionRenderSettingsDialog::OnAreaBoundsToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().DrawAreaCollisionBounds = Enable; +} + +void CCollisionRenderSettingsDialog::OnBackfacesToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().DrawBackfaces = Enable; +} + +void CCollisionRenderSettingsDialog::OnHideCheckboxesToggled() +{ + CCollisionMaterial& rMat = mpEditor->Viewport()->CollisionRenderSettings().HideMaterial; + mpUi->HideShootThruCheckBox->isChecked() ? rMat |= eCF_ShootThru : rMat &= ~eCF_ShootThru; + mpUi->HideCameraThruCheckBox->isChecked() ? rMat |= eCF_CameraThru : rMat &= ~eCF_CameraThru; + mpUi->HideScanThruCheckBox->isChecked() ? rMat |= eCF_ScanThru : rMat &= ~eCF_ScanThru; + mpUi->HideAiWalkThruCheckBox->isChecked() ? rMat |= eCF_AiWalkThru : rMat &= ~eCF_AiWalkThru; + mpUi->HideAiBlockCheckBox->isChecked() ? rMat |= eCF_AiBlock : rMat &= ~eCF_AiBlock; +} diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h index 826e230a..6219dce2 100644 --- a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h @@ -21,9 +21,15 @@ public: ~CCollisionRenderSettingsDialog(); public slots: + void SetupWidgets(); void OnHideMaskChanged(QString NewMask); void OnHighlightMaskChanged(QString NewMask); void OnWireframeToggled(bool Enable); + void OnSurfaceTypeToggled(bool Enable); + void OnStandableTrisToggled(bool Enable); + void OnAreaBoundsToggled(bool Enable); + void OnBackfacesToggled(bool Enable); + void OnHideCheckboxesToggled(); }; #endif // CCOLLISIONRENDERSETTINGSDIALOG_H diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui index 58d9d443..d37c78bb 100644 --- a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui @@ -6,51 +6,143 @@ 0 0 - 309 - 89 + 247 + 395 + + + 0 + 0 + + - Dialog + Collision Render Settings + + QLayout::SetFixedSize + - - - - - Hide Mask - - - - - - - - - - Highlight Mask - - - - - - - - - - Wireframe - - - - - - - - - - - + + + Settings + + + + + + Wireframe + + + + + + + Show Standable Tris + + + + + + + Show Surface Type + + + + + + + Show Area Collision Bounds + + + + + + + Draw Backfaces + + + + + + + + + + Visibility + + + + + + Hide Shoot Thru + + + + + + + Hide Camera Thru + + + + + + + Hide Scan Thru + + + + + + + Hide AI Walk Thru + + + + + + + Hide AI Block + + + + + + + + + + Advanced + + + + + + + + Hide Mask + + + + + + + + + + Highlight Mask + + + + + + + + + + diff --git a/src/Editor/WorldEditor/CWorldEditor.cpp b/src/Editor/WorldEditor/CWorldEditor.cpp index e0cd3b7e..cbe2e847 100644 --- a/src/Editor/WorldEditor/CWorldEditor.cpp +++ b/src/Editor/WorldEditor/CWorldEditor.cpp @@ -34,7 +34,6 @@ CWorldEditor::CWorldEditor(QWidget *parent) , ui(new Ui::CWorldEditor) , mpArea(nullptr) , mpWorld(nullptr) - , mpCollisionDialog(new CCollisionRenderSettingsDialog(this, this)) , mpLinkDialog(new CLinkDialog(this, this)) , mpPoiDialog(nullptr) , mIsMakingLink(false) @@ -93,6 +92,8 @@ CWorldEditor::CWorldEditor(QWidget *parent) ui->ActionDelete->setAutoRepeat(false); ui->ActionDelete->setShortcut(QKeySequence::Delete); + mpCollisionDialog = new CCollisionRenderSettingsDialog(this, this); + // Connect signals and slots connect(ui->MainViewport, SIGNAL(ViewportClick(SRayIntersection,QMouseEvent*)), this, SLOT(OnViewportClick(SRayIntersection,QMouseEvent*))); connect(ui->MainViewport, SIGNAL(InputProcessed(SRayIntersection,QMouseEvent*)), this, SLOT(OnViewportInputProcessed(SRayIntersection,QMouseEvent*))); @@ -129,7 +130,6 @@ CWorldEditor::CWorldEditor(QWidget *parent) connect(ui->ActionDrawLights, SIGNAL(triggered()), this, SLOT(ToggleDrawLights())); connect(ui->ActionDrawSky, SIGNAL(triggered()), this, SLOT(ToggleDrawSky())); connect(ui->ActionGameMode, SIGNAL(triggered()), this, SLOT(ToggleGameMode())); - connect(ui->ActionDisableBackfaceCull, SIGNAL(triggered()), this, SLOT(ToggleBackfaceCull())); connect(ui->ActionDisableAlpha, SIGNAL(triggered()), this, SLOT(ToggleDisableAlpha())); connect(ui->ActionNoLighting, SIGNAL(triggered()), this, SLOT(SetNoLighting())); connect(ui->ActionBasicLighting, SIGNAL(triggered()), this, SLOT(SetBasicLighting())); @@ -162,6 +162,7 @@ void CWorldEditor::closeEvent(QCloseEvent *pEvent) if (ShouldClose) { mUndoStack.clear(); + mpCollisionDialog->close(); mpLinkDialog->close(); if (mpPoiDialog) @@ -228,6 +229,7 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea) ui->InstancesTabContents->SetMaster(pMaster); // Set up dialogs + mpCollisionDialog->SetupWidgets(); // Won't modify any settings but will update widget visibility status if we've changed games mpLinkDialog->SetMaster(pMaster); // Set window title @@ -1026,11 +1028,6 @@ void CWorldEditor::ToggleGameMode() ui->MainViewport->SetGameMode(ui->ActionGameMode->isChecked()); } -void CWorldEditor::ToggleBackfaceCull() -{ - ui->MainViewport->Renderer()->ToggleBackfaceCull(!ui->ActionDisableBackfaceCull->isChecked()); -} - void CWorldEditor::ToggleDisableAlpha() { ui->MainViewport->Renderer()->ToggleAlphaDisabled(ui->ActionDisableAlpha->isChecked()); diff --git a/src/Editor/WorldEditor/CWorldEditor.h b/src/Editor/WorldEditor/CWorldEditor.h index 766ca61a..c70eda2c 100644 --- a/src/Editor/WorldEditor/CWorldEditor.h +++ b/src/Editor/WorldEditor/CWorldEditor.h @@ -123,7 +123,6 @@ private slots: void ToggleDrawLights(); void ToggleDrawSky(); void ToggleGameMode(); - void ToggleBackfaceCull(); void ToggleDisableAlpha(); void SetNoLighting(); void SetBasicLighting(); diff --git a/src/Editor/WorldEditor/CWorldEditor.ui b/src/Editor/WorldEditor/CWorldEditor.ui index b63382ac..ae3e34d6 100644 --- a/src/Editor/WorldEditor/CWorldEditor.ui +++ b/src/Editor/WorldEditor/CWorldEditor.ui @@ -464,7 +464,6 @@ -