mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-11 14:41:57 +00:00
Added orbit camera mode, set up orbit in World Editor and Model Editor
This commit is contained in:
@@ -47,8 +47,8 @@ public:
|
||||
void mouseReleaseEvent(QMouseEvent *pEvent);
|
||||
void mouseMoveEvent(QMouseEvent *pEvent);
|
||||
void wheelEvent(QWheelEvent *pEvent);
|
||||
void keyPressEvent(QKeyEvent *pEvent);
|
||||
void keyReleaseEvent(QKeyEvent *pEvent);
|
||||
virtual void keyPressEvent(QKeyEvent *pEvent);
|
||||
virtual void keyReleaseEvent(QKeyEvent *pEvent);
|
||||
void focusOutEvent(QFocusEvent *pEvent);
|
||||
void contextMenuEvent(QContextMenuEvent *pEvent);
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ CModelEditorWindow::CModelEditorWindow(QWidget *parent) :
|
||||
|
||||
CCamera& camera = ui->Viewport->Camera();
|
||||
camera.Snap(CVector3f(0, 3, 1));
|
||||
camera.SetFree();
|
||||
camera.SetMoveMode(eOrbitCamera);
|
||||
camera.SetOrbit(CVector3f(0, 0, 1), 3.f);
|
||||
camera.SetMoveSpeed(0.5f);
|
||||
|
||||
// UI initialization
|
||||
@@ -153,6 +154,7 @@ void CModelEditorWindow::SetActiveModel(CModel *pModel)
|
||||
mpCurrentModelNode->MarkTransformChanged();
|
||||
mpCurrentModel = pModel;
|
||||
mModelToken = CToken(pModel);
|
||||
ui->Viewport->Camera().SetOrbit(pModel->AABox());
|
||||
|
||||
u32 numVertices = (pModel ? pModel->GetVertexCount() : 0);
|
||||
u32 numTriangles = (pModel ? pModel->GetTriangleCount() : 0);
|
||||
@@ -807,3 +809,26 @@ void CModelEditorWindow::on_actionSave_as_triggered()
|
||||
TString name = TString(filename.toStdString());
|
||||
setWindowTitle("Prime World Editor - Model Editor: " + TO_QSTRING(name));
|
||||
}
|
||||
|
||||
void CModelEditorWindow::on_CameraModeButton_clicked()
|
||||
{
|
||||
CCamera *pCam = &ui->Viewport->Camera();
|
||||
|
||||
if (pCam->MoveMode() == eOrbitCamera)
|
||||
{
|
||||
pCam->SetMoveMode(eFreeCamera);
|
||||
ui->CameraModeButton->setIcon(QIcon(":/icons/EditorAssets/Free Camera.png"));
|
||||
ui->CameraModeButton->setToolTip(QString("Free Camera"));
|
||||
}
|
||||
|
||||
else if (pCam->MoveMode() == eFreeCamera)
|
||||
{
|
||||
pCam->SetMoveMode(eOrbitCamera);
|
||||
ui->CameraModeButton->setIcon(QIcon(":/icons/EditorAssets/Orbit Camera v2.png"));
|
||||
ui->CameraModeButton->setToolTip(QString("Orbit Camera"));
|
||||
|
||||
CVector3f Pos = pCam->Position();
|
||||
CVector3f Target = mpCurrentModelNode->AABox().Center();
|
||||
pCam->SetOrbitDistance(Pos.Distance(Target));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ private slots:
|
||||
|
||||
void on_actionSave_as_triggered();
|
||||
|
||||
void on_CameraModeButton_clicked();
|
||||
|
||||
signals:
|
||||
void Closed();
|
||||
};
|
||||
|
||||
@@ -2140,7 +2140,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0,0,0,0,0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0,0,0,0,0,0">
|
||||
<property name="spacing">
|
||||
<number>50</number>
|
||||
</property>
|
||||
@@ -2227,6 +2227,32 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="CameraModeButton">
|
||||
<property name="toolTip">
|
||||
<string>Orbit Camera</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<normaloff>:/icons/EditorAssets/Orbit Camera.png</normaloff>:/icons/EditorAssets/Orbit Camera.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -109,6 +109,26 @@ bool CSceneViewport::IsHoveringGizmo()
|
||||
return mGizmoHovering;
|
||||
}
|
||||
|
||||
void CSceneViewport::keyPressEvent(QKeyEvent* pEvent)
|
||||
{
|
||||
CBasicViewport::keyPressEvent(pEvent);
|
||||
|
||||
if (pEvent->key() == Qt::Key_Z)
|
||||
{
|
||||
mCamera.SetMoveMode(eOrbitCamera);
|
||||
}
|
||||
}
|
||||
|
||||
void CSceneViewport::keyReleaseEvent(QKeyEvent* pEvent)
|
||||
{
|
||||
CBasicViewport::keyReleaseEvent(pEvent);
|
||||
|
||||
if (pEvent->key() == Qt::Key_Z)
|
||||
{
|
||||
mCamera.SetMoveMode(eFreeCamera);
|
||||
}
|
||||
}
|
||||
|
||||
// ************ PROTECTED SLOTS ************
|
||||
void CSceneViewport::CheckUserInput()
|
||||
{
|
||||
|
||||
@@ -34,6 +34,9 @@ public:
|
||||
void ResetHover();
|
||||
bool IsHoveringGizmo();
|
||||
|
||||
void keyPressEvent(QKeyEvent* pEvent);
|
||||
void keyReleaseEvent(QKeyEvent* pEvent);
|
||||
|
||||
signals:
|
||||
void GizmoMoved();
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
||||
ui->ModifyTabContents->ClearCachedEditors();
|
||||
ui->InstancesTabContents->SetMaster(nullptr);
|
||||
ui->InstancesTabContents->SetArea(pArea);
|
||||
mUndoStack.clear();
|
||||
|
||||
// Clear old area - hack until better world/area loader is implemented
|
||||
if ((mpArea) && (pArea != mpArea))
|
||||
@@ -109,10 +110,17 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
||||
mScene.SetActiveWorld(pWorld);
|
||||
mScene.SetActiveArea(pArea);
|
||||
|
||||
// Snap camera to location of area
|
||||
CTransform4f AreaTransform = pArea->GetTransform();
|
||||
CVector3f AreaPosition(AreaTransform[0][3], AreaTransform[1][3], AreaTransform[2][3]);
|
||||
ui->MainViewport->Camera().Snap(AreaPosition);
|
||||
// Snap camera to new area
|
||||
CCamera *pCamera = &ui->MainViewport->Camera();
|
||||
|
||||
if (pCamera->MoveMode() == eFreeCamera)
|
||||
{
|
||||
CTransform4f AreaTransform = pArea->GetTransform();
|
||||
CVector3f AreaPosition(AreaTransform[0][3], AreaTransform[1][3], AreaTransform[2][3]);
|
||||
pCamera->Snap(AreaPosition);
|
||||
}
|
||||
|
||||
UpdateCameraOrbit();
|
||||
|
||||
// Default bloom to Fake Bloom for Metroid Prime 3; disable for other games
|
||||
if (mpWorld->Version() == eCorruption)
|
||||
@@ -137,63 +145,7 @@ CGameArea* CWorldEditor::ActiveArea()
|
||||
return mpArea;
|
||||
}
|
||||
|
||||
// ************ SLOTS ************
|
||||
void CWorldEditor::UpdateCursor()
|
||||
{
|
||||
if (ui->MainViewport->IsCursorVisible())
|
||||
{
|
||||
CSceneNode *pHoverNode = ui->MainViewport->HoverNode();
|
||||
|
||||
if (ui->MainViewport->IsHoveringGizmo())
|
||||
ui->MainViewport->SetCursorState(Qt::SizeAllCursor);
|
||||
else if ((pHoverNode) && (pHoverNode->NodeType() != eStaticNode))
|
||||
ui->MainViewport->SetCursorState(Qt::PointingHandCursor);
|
||||
else
|
||||
ui->MainViewport->SetCursorState(Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::UpdateStatusBar()
|
||||
{
|
||||
// Would be cool to do more frequent status bar updates with more info. Unfortunately, this causes lag.
|
||||
QString StatusText = "";
|
||||
|
||||
if (!mGizmoHovering)
|
||||
{
|
||||
if (ui->MainViewport->underMouse())
|
||||
{
|
||||
CSceneNode *pHoverNode = ui->MainViewport->HoverNode();
|
||||
|
||||
if (pHoverNode && (pHoverNode->NodeType() != eStaticNode))
|
||||
StatusText = TO_QSTRING(pHoverNode->Name());
|
||||
}
|
||||
}
|
||||
|
||||
if (ui->statusbar->currentMessage() != StatusText)
|
||||
ui->statusbar->showMessage(StatusText);
|
||||
}
|
||||
|
||||
void CWorldEditor::UpdateSelectionUI()
|
||||
{
|
||||
// Update sidebar
|
||||
ui->ModifyTabContents->GenerateUI(mSelection);
|
||||
|
||||
// Update selection info text
|
||||
QString SelectionText;
|
||||
|
||||
if (mSelection.size() == 1)
|
||||
SelectionText = TO_QSTRING(mSelection.front()->Name());
|
||||
else if (mSelection.size() > 1)
|
||||
SelectionText = QString("%1 objects selected").arg(mSelection.size());
|
||||
|
||||
QFontMetrics Metrics(ui->SelectionInfoLabel->font());
|
||||
SelectionText = Metrics.elidedText(SelectionText, Qt::ElideRight, ui->SelectionInfoFrame->width() - 10);
|
||||
ui->SelectionInfoLabel->setText(SelectionText);
|
||||
|
||||
// Update gizmo stuff
|
||||
UpdateGizmoUI();
|
||||
}
|
||||
|
||||
// ************ UPDATE UI ************
|
||||
void CWorldEditor::UpdateGizmoUI()
|
||||
{
|
||||
// Update transform XYZ spin boxes
|
||||
@@ -248,13 +200,83 @@ void CWorldEditor::UpdateGizmoUI()
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::UpdateSelectionUI()
|
||||
{
|
||||
// Update camera orbit
|
||||
UpdateCameraOrbit();
|
||||
|
||||
// Update sidebar
|
||||
ui->ModifyTabContents->GenerateUI(mSelection);
|
||||
|
||||
// Update selection info text
|
||||
QString SelectionText;
|
||||
|
||||
if (mSelection.size() == 1)
|
||||
SelectionText = TO_QSTRING(mSelection.front()->Name());
|
||||
else if (mSelection.size() > 1)
|
||||
SelectionText = QString("%1 objects selected").arg(mSelection.size());
|
||||
|
||||
QFontMetrics Metrics(ui->SelectionInfoLabel->font());
|
||||
SelectionText = Metrics.elidedText(SelectionText, Qt::ElideRight, ui->SelectionInfoFrame->width() - 10);
|
||||
ui->SelectionInfoLabel->setText(SelectionText);
|
||||
|
||||
// Update gizmo stuff
|
||||
UpdateGizmoUI();
|
||||
}
|
||||
|
||||
void CWorldEditor::UpdateStatusBar()
|
||||
{
|
||||
// Would be cool to do more frequent status bar updates with more info. Unfortunately, this causes lag.
|
||||
QString StatusText = "";
|
||||
|
||||
if (!mGizmoHovering)
|
||||
{
|
||||
if (ui->MainViewport->underMouse())
|
||||
{
|
||||
CSceneNode *pHoverNode = ui->MainViewport->HoverNode();
|
||||
|
||||
if (pHoverNode && (pHoverNode->NodeType() != eStaticNode))
|
||||
StatusText = TO_QSTRING(pHoverNode->Name());
|
||||
}
|
||||
}
|
||||
|
||||
if (ui->statusbar->currentMessage() != StatusText)
|
||||
ui->statusbar->showMessage(StatusText);
|
||||
}
|
||||
|
||||
// ************ PROTECTED ************
|
||||
void CWorldEditor::GizmoModeChanged(CGizmo::EGizmoMode mode)
|
||||
{
|
||||
ui->TransformSpinBox->SetSingleStep( (mode == CGizmo::eRotate ? 1.0 : 0.1) );
|
||||
ui->TransformSpinBox->SetDefaultValue( (mode == CGizmo::eScale ? 1.0 : 0.0) );
|
||||
}
|
||||
|
||||
// ************ ACTIONS ************
|
||||
void CWorldEditor::UpdateCursor()
|
||||
{
|
||||
if (ui->MainViewport->IsCursorVisible())
|
||||
{
|
||||
CSceneNode *pHoverNode = ui->MainViewport->HoverNode();
|
||||
|
||||
if (ui->MainViewport->IsHoveringGizmo())
|
||||
ui->MainViewport->SetCursorState(Qt::SizeAllCursor);
|
||||
else if ((pHoverNode) && (pHoverNode->NodeType() != eStaticNode))
|
||||
ui->MainViewport->SetCursorState(Qt::PointingHandCursor);
|
||||
else
|
||||
ui->MainViewport->SetCursorState(Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::UpdateCameraOrbit()
|
||||
{
|
||||
CCamera *pCamera = &ui->MainViewport->Camera();
|
||||
|
||||
if (!mSelection.isEmpty())
|
||||
pCamera->SetOrbit(mSelectionBounds);
|
||||
else
|
||||
pCamera->SetOrbit(mpArea->AABox(), 0.8f);
|
||||
}
|
||||
|
||||
// ************ PRIVATE SLOTS ************
|
||||
void CWorldEditor::RefreshViewport()
|
||||
{
|
||||
if (!mGizmo.IsTransforming())
|
||||
@@ -413,37 +435,6 @@ void CWorldEditor::on_ActionBloom_triggered()
|
||||
ui->ActionBloom->setChecked(true);
|
||||
}
|
||||
|
||||
void CWorldEditor::on_ActionZoomOnSelection_triggered()
|
||||
{
|
||||
static const float skDistScale = 2.5f;
|
||||
static const float skAreaDistScale = 0.8f;
|
||||
|
||||
CCamera& Camera = ui->MainViewport->Camera();
|
||||
CVector3f CamDir = Camera.Direction();
|
||||
CVector3f NewPos;
|
||||
|
||||
// Zoom on selection
|
||||
if (mSelection.size() != 0)
|
||||
{
|
||||
CVector3f Min = mSelectionBounds.Min();
|
||||
CVector3f Max = mSelectionBounds.Max();
|
||||
float Dist = ((Max.x - Min.x) + (Max.y - Min.y) + (Max.z - Min.z)) / 3.f;
|
||||
NewPos = mSelectionBounds.Center() + (CamDir * -(Dist * skDistScale));
|
||||
}
|
||||
|
||||
// Zoom on area
|
||||
else
|
||||
{
|
||||
CAABox AreaBox = mpArea->AABox();
|
||||
CVector3f Min = AreaBox.Min();
|
||||
CVector3f Max = AreaBox.Max();
|
||||
float Dist = ((Max.x - Min.x) + (Max.y - Min.y) + (Max.z - Min.z)) / 3.f;
|
||||
NewPos = AreaBox.Center() + (CamDir * -(Dist * skAreaDistScale));
|
||||
}
|
||||
|
||||
Camera.SetPosition(NewPos);
|
||||
}
|
||||
|
||||
void CWorldEditor::on_ActionDisableBackfaceCull_triggered()
|
||||
{
|
||||
ui->MainViewport->Renderer()->ToggleBackfaceCull(!ui->ActionDisableBackfaceCull->isChecked());
|
||||
|
||||
@@ -50,10 +50,8 @@ public:
|
||||
|
||||
protected:
|
||||
void GizmoModeChanged(CGizmo::EGizmoMode mode);
|
||||
|
||||
private:
|
||||
void UpdateCursor();
|
||||
void OnSidebarResize();
|
||||
void UpdateCameraOrbit();
|
||||
|
||||
private slots:
|
||||
void RefreshViewport();
|
||||
@@ -72,7 +70,6 @@ private slots:
|
||||
void on_ActionBloomMaps_triggered();
|
||||
void on_ActionFakeBloom_triggered();
|
||||
void on_ActionBloom_triggered();
|
||||
void on_ActionZoomOnSelection_triggered();
|
||||
void on_ActionDisableBackfaceCull_triggered();
|
||||
void on_ActionDisableAlpha_triggered();
|
||||
void on_ActionEditLayers_triggered();
|
||||
|
||||
@@ -267,8 +267,6 @@
|
||||
<addaction name="ActionFakeBloom"/>
|
||||
<addaction name="ActionBloom"/>
|
||||
</widget>
|
||||
<addaction name="ActionZoomOnSelection"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="ActionDrawWorld"/>
|
||||
<addaction name="ActionDrawObjects"/>
|
||||
<addaction name="ActionDrawCollision"/>
|
||||
|
||||
Reference in New Issue
Block a user