2015-09-01 17:05:48 +00:00
|
|
|
#include "CSceneViewport.h"
|
|
|
|
#include "undo/UndoCommands.h"
|
2015-11-25 21:37:34 +00:00
|
|
|
#include <Core/SViewInfo.h>
|
2015-09-01 17:05:48 +00:00
|
|
|
|
|
|
|
CSceneViewport::CSceneViewport(QWidget *pParent)
|
|
|
|
: CBasicViewport(pParent),
|
|
|
|
mpEditor(nullptr),
|
|
|
|
mpScene(nullptr),
|
|
|
|
mDrawSky(true),
|
|
|
|
mGizmoTransforming(false),
|
|
|
|
mpHoverNode(nullptr),
|
|
|
|
mHoverPoint(CVector3f::skZero)
|
|
|
|
{
|
|
|
|
mpRenderer = new CRenderer();
|
|
|
|
mpRenderer->SetClearColor(CColor::skBlack);
|
|
|
|
mpRenderer->SetViewportSize(width(), height());
|
2015-11-25 21:37:34 +00:00
|
|
|
|
|
|
|
mViewInfo.pScene = mpScene;
|
|
|
|
mViewInfo.pRenderer = mpRenderer;
|
2015-09-01 17:05:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSceneViewport::~CSceneViewport()
|
|
|
|
{
|
|
|
|
delete mpRenderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::SetScene(INodeEditor *pEditor, CSceneManager *pScene)
|
|
|
|
{
|
|
|
|
mpEditor = pEditor;
|
|
|
|
mpScene = pScene;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::SetSkyEnabled(bool b)
|
|
|
|
{
|
|
|
|
mDrawSky = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRenderer* CSceneViewport::Renderer()
|
|
|
|
{
|
|
|
|
return mpRenderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
CSceneNode* CSceneViewport::HoverNode()
|
|
|
|
{
|
|
|
|
return mpHoverNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
CVector3f CSceneViewport::HoverPoint()
|
|
|
|
{
|
|
|
|
return mHoverPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::CheckGizmoInput(const CRay& ray)
|
|
|
|
{
|
|
|
|
CGizmo *pGizmo = mpEditor->Gizmo();
|
|
|
|
|
|
|
|
// Gizmo not transforming: Check for gizmo hover
|
|
|
|
if (!pGizmo->IsTransforming())
|
|
|
|
{
|
|
|
|
if (mpEditor->IsGizmoVisible())
|
|
|
|
mGizmoHovering = pGizmo->CheckSelectedAxes(ray);
|
|
|
|
else
|
|
|
|
mGizmoHovering = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Gizmo transforming: Run gizmo input with ray/mouse coords
|
|
|
|
else if (mGizmoTransforming)
|
|
|
|
{
|
|
|
|
bool transformed = pGizmo->TransformFromInput(ray, mCamera);
|
|
|
|
if (transformed) emit GizmoMoved();
|
|
|
|
}
|
|
|
|
|
|
|
|
else mGizmoHovering = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::SceneRayCast(const CRay& ray)
|
|
|
|
{
|
|
|
|
if (mpEditor->Gizmo()->IsTransforming())
|
|
|
|
{
|
|
|
|
ResetHover();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-11-25 21:37:34 +00:00
|
|
|
SRayIntersection result = mpScene->SceneRayCast(ray, mViewInfo);
|
2015-09-01 17:05:48 +00:00
|
|
|
|
|
|
|
if (result.Hit)
|
|
|
|
{
|
|
|
|
if (mpHoverNode)
|
|
|
|
mpHoverNode->SetMouseHovering(false);
|
|
|
|
|
|
|
|
mpHoverNode = result.pNode;
|
|
|
|
mpHoverNode->SetMouseHovering(true);
|
|
|
|
mHoverPoint = ray.PointOnRay(result.Distance);
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
ResetHover();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::ResetHover()
|
|
|
|
{
|
|
|
|
if (mpHoverNode) mpHoverNode->SetMouseHovering(false);
|
|
|
|
mpHoverNode = nullptr;
|
|
|
|
mHoverPoint = CVector3f::skZero;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CSceneViewport::IsHoveringGizmo()
|
|
|
|
{
|
|
|
|
return mGizmoHovering;
|
|
|
|
}
|
|
|
|
|
2015-11-26 07:47:02 +00:00
|
|
|
void CSceneViewport::keyPressEvent(QKeyEvent* pEvent)
|
|
|
|
{
|
|
|
|
CBasicViewport::keyPressEvent(pEvent);
|
|
|
|
|
2015-11-27 21:18:22 +00:00
|
|
|
if (!pEvent->modifiers() && pEvent->key() == Qt::Key_Z && !pEvent->isAutoRepeat())
|
2015-11-26 07:47:02 +00:00
|
|
|
{
|
|
|
|
mCamera.SetMoveMode(eOrbitCamera);
|
2015-11-27 21:18:22 +00:00
|
|
|
emit CameraOrbit();
|
2015-11-26 07:47:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::keyReleaseEvent(QKeyEvent* pEvent)
|
|
|
|
{
|
|
|
|
CBasicViewport::keyReleaseEvent(pEvent);
|
|
|
|
|
2015-11-27 21:18:22 +00:00
|
|
|
if (pEvent->key() == Qt::Key_Z && !pEvent->isAutoRepeat())
|
2015-11-26 07:47:02 +00:00
|
|
|
{
|
|
|
|
mCamera.SetMoveMode(eFreeCamera);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-01 17:05:48 +00:00
|
|
|
// ************ PROTECTED SLOTS ************
|
|
|
|
void CSceneViewport::CheckUserInput()
|
|
|
|
{
|
2015-11-26 09:05:26 +00:00
|
|
|
bool MouseActive = (underMouse() && !IsMouseInputActive());
|
|
|
|
|
|
|
|
if (!MouseActive || mViewInfo.GameMode)
|
2015-09-01 17:05:48 +00:00
|
|
|
{
|
|
|
|
ResetHover();
|
|
|
|
mGizmoHovering = false;
|
2015-11-26 09:05:26 +00:00
|
|
|
|
|
|
|
if (!MouseActive)
|
|
|
|
return;
|
2015-09-01 17:05:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CRay ray = CastRay();
|
2015-11-26 09:05:26 +00:00
|
|
|
|
|
|
|
if (!mViewInfo.GameMode)
|
|
|
|
CheckGizmoInput(ray);
|
2015-09-01 17:05:48 +00:00
|
|
|
|
|
|
|
if (!mpEditor->Gizmo()->IsTransforming())
|
|
|
|
SceneRayCast(ray);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::Paint()
|
|
|
|
{
|
|
|
|
if (!mpScene) return;
|
|
|
|
|
|
|
|
mpRenderer->BeginFrame();
|
|
|
|
|
2015-11-26 09:05:26 +00:00
|
|
|
if (mDrawSky || mViewInfo.GameMode)
|
2015-09-01 17:05:48 +00:00
|
|
|
{
|
|
|
|
CModel *pSky = mpScene->GetActiveSkybox();
|
2015-11-25 21:37:34 +00:00
|
|
|
if (pSky) mpRenderer->RenderSky(pSky, mViewInfo);
|
2015-09-01 17:05:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mCamera.LoadMatrices();
|
2015-11-25 21:37:34 +00:00
|
|
|
mpScene->AddSceneToRenderer(mpRenderer, mViewInfo);
|
|
|
|
mpRenderer->RenderBuckets(mViewInfo);
|
2015-09-01 17:05:48 +00:00
|
|
|
mpRenderer->RenderBloom();
|
|
|
|
|
2015-11-26 09:05:26 +00:00
|
|
|
if (mpEditor->IsGizmoVisible() && !mViewInfo.GameMode)
|
2015-09-01 17:05:48 +00:00
|
|
|
{
|
|
|
|
CGizmo *pGizmo = mpEditor->Gizmo();
|
|
|
|
mCamera.LoadMatrices();
|
|
|
|
|
|
|
|
mpRenderer->ClearDepthBuffer();
|
|
|
|
pGizmo->UpdateForCamera(mCamera);
|
2015-11-25 21:37:34 +00:00
|
|
|
pGizmo->AddToRenderer(mpRenderer, mViewInfo);
|
|
|
|
mpRenderer->RenderBuckets(mViewInfo);
|
2015-09-01 17:05:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mpRenderer->EndFrame();
|
|
|
|
}
|
|
|
|
|
2015-11-24 10:22:37 +00:00
|
|
|
void CSceneViewport::ContextMenu(QContextMenuEvent* /*pEvent*/)
|
2015-09-01 17:05:48 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::OnResize()
|
|
|
|
{
|
|
|
|
mpRenderer->SetViewportSize(width(), height());
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::OnMouseClick(QMouseEvent *pEvent)
|
|
|
|
{
|
|
|
|
bool altPressed = ((pEvent->modifiers() & Qt::AltModifier) != 0);
|
|
|
|
bool ctrlPressed = ((pEvent->modifiers() & Qt::ControlModifier) != 0);
|
|
|
|
|
|
|
|
if (mGizmoHovering && !altPressed && !ctrlPressed)
|
|
|
|
{
|
|
|
|
mGizmoTransforming = true;
|
|
|
|
mpEditor->Gizmo()->StartTransform();
|
|
|
|
mpEditor->BeginGizmoTransform();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneViewport::OnMouseRelease(QMouseEvent *pEvent)
|
|
|
|
{
|
|
|
|
if (pEvent->button() == Qt::LeftButton)
|
|
|
|
{
|
|
|
|
// Stop gizmo transform
|
|
|
|
if (mGizmoTransforming)
|
|
|
|
{
|
|
|
|
CGizmo *pGizmo = mpEditor->Gizmo();
|
|
|
|
pGizmo->EndTransform();
|
|
|
|
mpEditor->EndGizmoTransform();
|
|
|
|
mGizmoTransforming = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Object selection/deselection
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bool validNode = (mpHoverNode && (mpHoverNode->NodeType() != eStaticNode));
|
|
|
|
bool altPressed = ((pEvent->modifiers() & Qt::AltModifier) != 0);
|
|
|
|
bool ctrlPressed = ((pEvent->modifiers() & Qt::ControlModifier) != 0);
|
|
|
|
|
|
|
|
// Alt: Deselect
|
|
|
|
if (altPressed)
|
|
|
|
{
|
|
|
|
if (!validNode)
|
|
|
|
return;
|
|
|
|
|
|
|
|
mpEditor->DeselectNode(mpHoverNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ctrl: Add to selection
|
|
|
|
else if (ctrlPressed)
|
|
|
|
{
|
|
|
|
if (validNode)
|
|
|
|
mpEditor->SelectNode(mpHoverNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Neither: clear selection + select
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!mGizmoHovering)
|
|
|
|
{
|
|
|
|
if (validNode)
|
|
|
|
mpEditor->ClearAndSelectNode(mpHoverNode);
|
|
|
|
else
|
|
|
|
mpEditor->ClearSelection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mpEditor->UpdateSelectionUI();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|