2012-03-20 01:57:42 +01:00
|
|
|
#include "lc_global.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include "project.h"
|
2012-08-20 06:05:56 +02:00
|
|
|
#include "camera.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "view.h"
|
|
|
|
#include "system.h"
|
2014-05-03 08:08:52 +02:00
|
|
|
#include "tr.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
View::View(Project *project)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project = project;
|
2012-08-20 06:05:56 +02:00
|
|
|
mCamera = NULL;
|
2012-02-05 03:50:57 +01:00
|
|
|
m_OverlayScale = 1.0f;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
if (project->GetActiveView())
|
|
|
|
SetCamera(project->GetActiveView()->mCamera, false);
|
|
|
|
else
|
|
|
|
SetDefaultCamera();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
View::~View()
|
|
|
|
{
|
|
|
|
if (m_Project != NULL)
|
|
|
|
m_Project->RemoveView(this);
|
2012-08-22 03:13:32 +02:00
|
|
|
|
|
|
|
if (mCamera && mCamera->IsSimple())
|
|
|
|
delete mCamera;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2012-11-15 02:14:35 +01:00
|
|
|
void View::SetCamera(Camera* camera, bool ForceCopy)
|
2012-08-20 06:05:56 +02:00
|
|
|
{
|
2012-11-15 02:14:35 +01:00
|
|
|
if (camera->IsSimple() || ForceCopy)
|
2012-08-20 06:05:56 +02:00
|
|
|
{
|
|
|
|
if (!mCamera || !mCamera->IsSimple())
|
|
|
|
mCamera = new Camera(true);
|
|
|
|
|
|
|
|
mCamera->CopyPosition(camera);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (mCamera && mCamera->IsSimple())
|
|
|
|
delete mCamera;
|
|
|
|
|
|
|
|
mCamera = camera;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void View::SetDefaultCamera()
|
|
|
|
{
|
|
|
|
if (!mCamera || !mCamera->IsSimple())
|
|
|
|
mCamera = new Camera(true);
|
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
mCamera->SetViewpoint(LC_VIEWPOINT_HOME, 1, false);
|
2012-08-20 06:05:56 +02:00
|
|
|
}
|
|
|
|
|
2014-05-03 03:22:24 +02:00
|
|
|
lcMatrix44 View::GetProjectionMatrix() const
|
|
|
|
{
|
|
|
|
float AspectRatio = (float)mWidth / (float)mHeight;
|
|
|
|
|
2014-05-03 08:08:52 +02:00
|
|
|
if (mCamera->m_pTR)
|
|
|
|
mCamera->m_pTR->BeginTile();
|
|
|
|
|
2014-05-03 03:22:24 +02:00
|
|
|
if (mCamera->IsOrtho())
|
|
|
|
{
|
|
|
|
// Compute the FOV/plane intersection radius.
|
|
|
|
// d d
|
|
|
|
// a = 2 atan(------) => ~ a = --- => d = af
|
|
|
|
// 2f f
|
|
|
|
float f = (mCamera->mPosition - mCamera->mOrthoTarget).Length();
|
|
|
|
float d = (mCamera->m_fovy * f) * (LC_PI / 180.0f);
|
|
|
|
float r = d / 2;
|
|
|
|
|
|
|
|
float right = r * AspectRatio;
|
|
|
|
return lcMatrix44Ortho(-right, right, -r, r, mCamera->m_zNear, mCamera->m_zFar * 4);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return lcMatrix44Perspective(mCamera->m_fovy, AspectRatio, mCamera->m_zNear, mCamera->m_zFar);
|
|
|
|
}
|
|
|
|
|
2012-07-31 07:27:40 +02:00
|
|
|
LC_CURSOR_TYPE View::GetCursor() const
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
// TODO: check if we're the focused window and return just the default arrow if we aren't.
|
|
|
|
|
|
|
|
switch (m_Project->GetAction())
|
|
|
|
{
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_SELECT:
|
2013-08-09 06:57:18 +02:00
|
|
|
if (mInputState.Control)
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_SELECT_GROUP;
|
|
|
|
else
|
|
|
|
return LC_CURSOR_SELECT;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_INSERT:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_BRICK;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_LIGHT:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_LIGHT;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_SPOTLIGHT:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_SPOTLIGHT;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_CAMERA:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_CAMERA;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_MOVE:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_MOVE;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_ROTATE:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_ROTATE;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_ERASER:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_DELETE;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_PAINT:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_PAINT;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_ZOOM:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_ZOOM;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_ZOOM_REGION:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_ZOOM_REGION;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_PAN:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_PAN;
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_ROTATE_VIEW:
|
2011-09-07 23:06:51 +02:00
|
|
|
switch (m_Project->GetOverlayMode())
|
|
|
|
{
|
2012-11-01 01:34:09 +01:00
|
|
|
case LC_OVERLAY_ROTATE_VIEW_X:
|
2012-03-03 02:16:02 +01:00
|
|
|
return LC_CURSOR_ROTATEX;
|
2012-11-01 01:34:09 +01:00
|
|
|
case LC_OVERLAY_ROTATE_VIEW_Y:
|
2012-03-03 02:16:02 +01:00
|
|
|
return LC_CURSOR_ROTATEY;
|
2012-11-01 01:34:09 +01:00
|
|
|
case LC_OVERLAY_ROTATE_VIEW_Z:
|
2012-03-03 02:16:02 +01:00
|
|
|
return LC_CURSOR_ROLL;
|
2012-11-01 01:34:09 +01:00
|
|
|
case LC_OVERLAY_ROTATE_VIEW_XYZ:
|
2011-09-07 23:06:51 +02:00
|
|
|
default:
|
2012-03-03 02:16:02 +01:00
|
|
|
return LC_CURSOR_ROTATE_VIEW;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
case LC_TOOL_ROLL:
|
2011-09-07 23:06:51 +02:00
|
|
|
return LC_CURSOR_ROLL;
|
|
|
|
|
|
|
|
default:
|
|
|
|
LC_ASSERT_FALSE("Unknown cursor type.");
|
2012-06-23 02:14:09 +02:00
|
|
|
return LC_CURSOR_DEFAULT;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-03 18:59:57 +02:00
|
|
|
lcObjectSection View::FindObjectUnderPointer(bool PiecesOnly) const
|
|
|
|
{
|
|
|
|
lcVector3 StartEnd[2] =
|
|
|
|
{
|
|
|
|
lcVector3((float)mInputState.x, (float)mInputState.y, 0.0f),
|
|
|
|
lcVector3((float)mInputState.x, (float)mInputState.y, 1.0f)
|
|
|
|
};
|
|
|
|
|
|
|
|
UnprojectPoints(StartEnd, 2);
|
|
|
|
|
|
|
|
lcObjectRayTest ObjectRayTest;
|
|
|
|
|
|
|
|
ObjectRayTest.PiecesOnly = PiecesOnly;
|
|
|
|
ObjectRayTest.ViewCamera = mCamera;
|
|
|
|
ObjectRayTest.Start = StartEnd[0];
|
|
|
|
ObjectRayTest.End = StartEnd[1];
|
|
|
|
ObjectRayTest.Distance = FLT_MAX;
|
|
|
|
ObjectRayTest.ObjectSection.Object = NULL;
|
|
|
|
ObjectRayTest.ObjectSection.Section = 0;;
|
|
|
|
|
|
|
|
m_Project->RayTest(ObjectRayTest);
|
|
|
|
|
|
|
|
return ObjectRayTest.ObjectSection;
|
|
|
|
}
|
|
|
|
|
|
|
|
lcArray<lcObjectSection> View::FindObjectsInBox(float x1, float y1, float x2, float y2) const
|
|
|
|
{
|
|
|
|
float Left, Top, Bottom, Right;
|
|
|
|
|
|
|
|
if (x1 < x2)
|
|
|
|
{
|
|
|
|
Left = x1;
|
|
|
|
Right = x2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Left = x2;
|
|
|
|
Right = x1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y1 > y2)
|
|
|
|
{
|
|
|
|
Top = y1;
|
|
|
|
Bottom = y2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Top = y2;
|
|
|
|
Bottom = y1;
|
|
|
|
}
|
|
|
|
|
|
|
|
lcVector3 Corners[6] =
|
|
|
|
{
|
|
|
|
lcVector3(Left, Top, 0),
|
|
|
|
lcVector3(Left, Bottom, 0),
|
|
|
|
lcVector3(Right, Bottom, 0),
|
|
|
|
lcVector3(Right, Top, 0),
|
|
|
|
lcVector3(Left, Top, 1),
|
|
|
|
lcVector3(Right, Bottom, 1)
|
|
|
|
};
|
|
|
|
|
|
|
|
UnprojectPoints(Corners, 6);
|
|
|
|
|
|
|
|
lcVector3 PlaneNormals[6];
|
|
|
|
PlaneNormals[0] = lcNormalize(lcCross(Corners[4] - Corners[0], Corners[1] - Corners[0])); // Left
|
|
|
|
PlaneNormals[1] = lcNormalize(lcCross(Corners[5] - Corners[2], Corners[3] - Corners[2])); // Right
|
|
|
|
PlaneNormals[2] = lcNormalize(lcCross(Corners[3] - Corners[0], Corners[4] - Corners[0])); // Top
|
|
|
|
PlaneNormals[3] = lcNormalize(lcCross(Corners[1] - Corners[2], Corners[5] - Corners[2])); // Bottom
|
|
|
|
PlaneNormals[4] = lcNormalize(lcCross(Corners[1] - Corners[0], Corners[3] - Corners[0])); // Front
|
|
|
|
PlaneNormals[5] = lcNormalize(lcCross(Corners[1] - Corners[2], Corners[3] - Corners[2])); // Back
|
|
|
|
|
|
|
|
lcObjectBoxTest ObjectBoxTest;
|
|
|
|
ObjectBoxTest.ViewCamera = mCamera;
|
|
|
|
ObjectBoxTest.Planes[0] = lcVector4(PlaneNormals[0], -lcDot(PlaneNormals[0], Corners[0]));
|
|
|
|
ObjectBoxTest.Planes[1] = lcVector4(PlaneNormals[1], -lcDot(PlaneNormals[1], Corners[5]));
|
|
|
|
ObjectBoxTest.Planes[2] = lcVector4(PlaneNormals[2], -lcDot(PlaneNormals[2], Corners[0]));
|
|
|
|
ObjectBoxTest.Planes[3] = lcVector4(PlaneNormals[3], -lcDot(PlaneNormals[3], Corners[5]));
|
|
|
|
ObjectBoxTest.Planes[4] = lcVector4(PlaneNormals[4], -lcDot(PlaneNormals[4], Corners[0]));
|
|
|
|
ObjectBoxTest.Planes[5] = lcVector4(PlaneNormals[5], -lcDot(PlaneNormals[5], Corners[5]));
|
|
|
|
|
|
|
|
m_Project->BoxTest(ObjectBoxTest);
|
|
|
|
|
|
|
|
return ObjectBoxTest.ObjectSections;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
void View::OnDraw()
|
|
|
|
{
|
2011-09-20 03:26:31 +02:00
|
|
|
m_Project->Render(this, false);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void View::OnInitialUpdate()
|
|
|
|
{
|
|
|
|
m_Project->AddView(this);
|
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnUpdateCursor()
|
|
|
|
{
|
|
|
|
SetCursor(GetCursor());
|
|
|
|
}
|
|
|
|
|
|
|
|
void View::OnLeftButtonDown()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnLeftButtonDown(this);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnLeftButtonUp()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnLeftButtonUp(this);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnLeftButtonDoubleClick()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnLeftButtonDoubleClick(this);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnMiddleButtonDown()
|
2012-01-28 03:10:19 +01:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnMiddleButtonDown(this);
|
2012-01-28 03:10:19 +01:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnMiddleButtonUp()
|
2012-01-28 03:10:19 +01:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnMiddleButtonUp(this);
|
2012-01-28 03:10:19 +01:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnRightButtonDown()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnRightButtonDown(this);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnRightButtonUp()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnRightButtonUp(this);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnMouseMove()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnMouseMove(this);
|
2013-01-28 20:57:33 +01:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void View::OnMouseWheel(float Direction)
|
2013-01-28 20:57:33 +01:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
m_Project->OnMouseWheel(this, Direction);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|