Added a couple more collision view features; set up a proper UI for changing collision render settings

This commit is contained in:
parax0 2017-01-14 10:32:41 -07:00
parent a2762e034e
commit c62a01e4d9
11 changed files with 246 additions and 64 deletions

View File

@ -1,6 +1,7 @@
#ifndef SVIEWINFO
#define SVIEWINFO
#include "Core/Resource/CCollisionMaterial.h"
#include "Core/Scene/FShowFlags.h"
#include <Math/CFrustumPlanes.h>
#include <Math/CMatrix4f.h>
@ -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

View File

@ -1,6 +1,6 @@
#include "CCollisionMaterial.h"
#include "EGame.h"
#include <map>
#include <unordered_map>
ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const
{
@ -42,7 +42,7 @@ ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const
}
// Type-to-color mappings
const std::map<ECollisionFlag, CColor> gkTypeToColor = {
const std::unordered_map<ECollisionFlag, CColor> 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,51 +6,143 @@
<rect>
<x>0</x>
<y>0</y>
<width>309</width>
<height>89</height>
<width>247</width>
<height>395</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>Collision Render Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="HideMaskLabel">
<property name="text">
<string>Hide Mask</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="HideMaskLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="HighlightMaskLabel">
<property name="text">
<string>Highlight Mask</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="HighlightMaskLineEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="WireframeLabel">
<property name="text">
<string>Wireframe</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="WireframeCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
<widget class="QGroupBox" name="SettingsGroupBox">
<property name="title">
<string>Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="WireframeCheckBox">
<property name="text">
<string>Wireframe</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="StandableTrisCheckBox">
<property name="text">
<string>Show Standable Tris</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="SurfaceTypeCheckBox">
<property name="text">
<string>Show Surface Type</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AreaBoundsCheckBox">
<property name="text">
<string>Show Area Collision Bounds</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="BackfacesCheckBox">
<property name="text">
<string>Draw Backfaces</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="VisibilityGroupBox">
<property name="title">
<string>Visibility</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="HideShootThruCheckBox">
<property name="text">
<string>Hide Shoot Thru</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="HideCameraThruCheckBox">
<property name="text">
<string>Hide Camera Thru</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="HideScanThruCheckBox">
<property name="text">
<string>Hide Scan Thru</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="HideAiWalkThruCheckBox">
<property name="text">
<string>Hide AI Walk Thru</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="HideAiBlockCheckBox">
<property name="text">
<string>Hide AI Block</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Advanced</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="HideMaskLabel">
<property name="text">
<string>Hide Mask</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="HideMaskLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="HighlightMaskLabel">
<property name="text">
<string>Highlight Mask</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="HighlightMaskLineEdit"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>

View File

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

View File

@ -123,7 +123,6 @@ private slots:
void ToggleDrawLights();
void ToggleDrawSky();
void ToggleGameMode();
void ToggleBackfaceCull();
void ToggleDisableAlpha();
void SetNoLighting();
void SetBasicLighting();

View File

@ -464,7 +464,6 @@
<addaction name="menuBloom"/>
<addaction name="separator"/>
<addaction name="ActionCollisionRenderSettings"/>
<addaction name="ActionDisableBackfaceCull"/>
<addaction name="ActionDisableAlpha"/>
</widget>
<widget class="QMenu" name="menuTools">