2012-03-20 01:57:42 +01:00
|
|
|
#include "lc_global.h"
|
2012-03-29 03:10:55 +02:00
|
|
|
#include "lc_math.h"
|
2012-03-25 01:47:53 +01:00
|
|
|
#include "lc_colors.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
2013-01-27 02:22:37 +01:00
|
|
|
#include <float.h>
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "opengl.h"
|
2012-03-21 02:54:03 +01:00
|
|
|
#include "lc_file.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "camera.h"
|
2012-08-20 06:05:56 +02:00
|
|
|
#include "view.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "tr.h"
|
2014-04-14 05:20:16 +02:00
|
|
|
#include "lc_application.h"
|
|
|
|
#include "lc_context.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-08-30 21:48:36 +02:00
|
|
|
#define LC_CAMERA_SAVE_VERSION 7 // LeoCAD 0.80
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
static LC_OBJECT_KEY_INFO camera_key_info[LC_CK_COUNT] =
|
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
{ "Camera Position", 3, LC_CK_EYE },
|
|
|
|
{ "Camera Target", 3, LC_CK_TARGET },
|
|
|
|
{ "Camera Up Vector", 3, LC_CK_UP }
|
2011-09-07 23:06:51 +02:00
|
|
|
};
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
lcCamera::lcCamera(bool Simple)
|
2014-08-07 17:22:33 +02:00
|
|
|
: lcObject(LC_OBJECT_CAMERA)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-20 06:05:56 +02:00
|
|
|
Initialize();
|
|
|
|
|
|
|
|
if (Simple)
|
2014-05-18 01:03:05 +02:00
|
|
|
mState |= LC_CAMERA_SIMPLE;
|
2012-08-23 20:47:37 +02:00
|
|
|
else
|
|
|
|
{
|
2014-08-30 21:48:36 +02:00
|
|
|
mPosition = lcVector3(-250.0f, -250.0f, 75.0f);
|
2012-08-23 20:47:37 +02:00
|
|
|
mTargetPosition = lcVector3(0.0f, 0.0f, 0.0f);
|
2013-12-17 03:43:16 +01:00
|
|
|
mOrthoTarget = mTargetPosition;
|
2012-08-23 20:47:37 +02:00
|
|
|
mUpVector = lcVector3(-0.2357f, -0.2357f, 0.94281f);
|
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(1, true, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(1, true, mTargetPosition, LC_CK_TARGET);
|
|
|
|
ChangeKey(1, true, mUpVector, LC_CK_UP);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
UpdatePosition(1);
|
2012-08-23 20:47:37 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
lcCamera::lcCamera(float ex, float ey, float ez, float tx, float ty, float tz)
|
2014-08-07 17:22:33 +02:00
|
|
|
: lcObject(LC_OBJECT_CAMERA)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-22 03:13:32 +02:00
|
|
|
// Fix the up vector
|
|
|
|
lcVector3 UpVector(0, 0, 1), FrontVector(ex - tx, ey - ty, ez - tz), SideVector;
|
|
|
|
FrontVector.Normalize();
|
|
|
|
if (FrontVector == UpVector)
|
|
|
|
SideVector = lcVector3(1, 0, 0);
|
|
|
|
else
|
|
|
|
SideVector = lcCross(FrontVector, UpVector);
|
|
|
|
UpVector = lcCross(SideVector, FrontVector);
|
|
|
|
UpVector.Normalize();
|
|
|
|
|
|
|
|
Initialize();
|
|
|
|
|
|
|
|
float eye[3] = { ex, ey, ez }, target[3] = { tx, ty, tz };
|
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(1, true, eye, LC_CK_EYE);
|
|
|
|
ChangeKey(1, true, target, LC_CK_TARGET);
|
|
|
|
ChangeKey(1, true, UpVector, LC_CK_UP);
|
2012-08-22 03:13:32 +02:00
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
UpdatePosition(1);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
lcCamera::~lcCamera()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
void lcCamera::Initialize()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
m_fovy = 30.0f;
|
2014-08-30 21:48:36 +02:00
|
|
|
m_zNear = 25.0f;
|
|
|
|
m_zFar = 12500.0f;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
mState = 0;
|
2012-08-23 20:47:37 +02:00
|
|
|
m_nType = LC_CAMERA_USER;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-23 20:47:37 +02:00
|
|
|
m_pTR = NULL;
|
|
|
|
memset(m_strName, 0, sizeof(m_strName));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-23 20:47:37 +02:00
|
|
|
float *values[] = { mPosition, mTargetPosition, mUpVector };
|
|
|
|
RegisterKeys(values, camera_key_info, LC_CK_COUNT);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-08-07 17:22:33 +02:00
|
|
|
void lcCamera::CreateName(const lcArray<lcCamera*>& Cameras)
|
2012-08-22 03:13:32 +02:00
|
|
|
{
|
|
|
|
int i, max = 0;
|
|
|
|
const char* Prefix = "Camera ";
|
|
|
|
|
|
|
|
for (int CameraIdx = 0; CameraIdx < Cameras.GetSize(); CameraIdx++)
|
|
|
|
if (strncmp(Cameras[CameraIdx]->m_strName, Prefix, strlen(Prefix)) == 0)
|
|
|
|
if (sscanf(Cameras[CameraIdx]->m_strName + strlen(Prefix), " %d", &i) == 1)
|
2013-01-06 20:24:25 +01:00
|
|
|
if (i > max)
|
2012-08-22 03:13:32 +02:00
|
|
|
max = i;
|
|
|
|
|
|
|
|
sprintf(m_strName, "%s %d", Prefix, max+1);
|
|
|
|
}
|
|
|
|
|
2014-08-30 01:52:42 +02:00
|
|
|
QJsonObject lcCamera::Save()
|
|
|
|
{
|
|
|
|
QJsonObject Camera;
|
|
|
|
|
|
|
|
Camera[QStringLiteral("FOV")] = QString::number(m_fovy);
|
|
|
|
Camera[QStringLiteral("ZNear")] = QString::number(m_zNear);
|
|
|
|
Camera[QStringLiteral("ZFar")] = QString::number(m_zFar);
|
|
|
|
Camera[QStringLiteral("Name")] = QString::fromLatin1(m_strName); // todo: replace with qstring
|
|
|
|
if (IsHidden())
|
|
|
|
Camera[QStringLiteral("Hidden")] = QStringLiteral("true");
|
|
|
|
if (IsOrtho())
|
|
|
|
Camera[QStringLiteral("Orthographic")] = QStringLiteral("true");
|
|
|
|
|
|
|
|
QJsonArray PositionKeys, TargetPositionKeys, UpVectorKeys;
|
|
|
|
|
|
|
|
for (LC_OBJECT_KEY* Node = m_pInstructionKeys; Node; Node = Node->next)
|
|
|
|
{
|
|
|
|
QJsonObject Key;
|
|
|
|
|
|
|
|
Key[QStringLiteral("Step")] = QString::number(Node->Step);
|
|
|
|
Key["Value"] = QStringLiteral("%1 %2 %3").arg(QString::number(Node->param[0]), QString::number(Node->param[1]), QString::number(Node->param[2]));
|
|
|
|
|
|
|
|
if (Node->type == LC_CK_EYE)
|
|
|
|
PositionKeys.append(Key);
|
|
|
|
else if (Node->type == LC_CK_TARGET)
|
|
|
|
TargetPositionKeys.append(Key);
|
|
|
|
else if (Node->type == LC_CK_UP)
|
|
|
|
UpVectorKeys.append(Key);
|
|
|
|
}
|
|
|
|
|
2014-08-30 21:48:36 +02:00
|
|
|
if (PositionKeys.size() == 1)
|
|
|
|
Camera[QStringLiteral("Position")] = PositionKeys.first().toObject()[QStringLiteral("Value")].toString();
|
2014-08-30 01:52:42 +02:00
|
|
|
else
|
2014-08-30 21:48:36 +02:00
|
|
|
Camera[QStringLiteral("PositionKeys")] = PositionKeys;
|
|
|
|
|
|
|
|
if (TargetPositionKeys.size() == 1)
|
|
|
|
Camera[QStringLiteral("TargetPosition")] = TargetPositionKeys.first().toObject()[QStringLiteral("Value")].toString();
|
|
|
|
else
|
|
|
|
Camera[QStringLiteral("UpVectorKeys")] = UpVectorKeys;
|
|
|
|
|
|
|
|
if (UpVectorKeys.size() == 1)
|
|
|
|
Camera[QStringLiteral("UpVector")] = UpVectorKeys.first().toObject()[QStringLiteral("Value")].toString();
|
|
|
|
else
|
|
|
|
Camera[QStringLiteral("TargetPositionKeys")] = TargetPositionKeys;
|
2014-08-30 01:52:42 +02:00
|
|
|
|
|
|
|
return Camera;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcCamera::Load(QJsonObject Camera)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Camera save/load
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
bool lcCamera::FileLoad(lcFile& file)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
lcuint8 version, ch;
|
|
|
|
|
|
|
|
version = file.ReadU8();
|
|
|
|
|
|
|
|
if (version > LC_CAMERA_SAVE_VERSION)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (version > 5)
|
2014-08-07 17:22:33 +02:00
|
|
|
if (!lcObject::FileLoad(file))
|
2012-08-23 20:47:37 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (version == 4)
|
|
|
|
{
|
|
|
|
file.ReadBuffer(m_strName, 80);
|
|
|
|
m_strName[80] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ch = file.ReadU8();
|
|
|
|
if (ch == 0xFF)
|
|
|
|
return false; // don't read CString
|
|
|
|
file.ReadBuffer(m_strName, ch);
|
|
|
|
m_strName[ch] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (version < 3)
|
|
|
|
{
|
|
|
|
double d[3];
|
|
|
|
float f[3];
|
|
|
|
|
|
|
|
file.ReadDoubles(d, 3);
|
|
|
|
f[0] = (float)d[0];
|
|
|
|
f[1] = (float)d[1];
|
|
|
|
f[2] = (float)d[2];
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(1, true, f, LC_CK_EYE);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
|
|
|
file.ReadDoubles(d, 3);
|
|
|
|
f[0] = (float)d[0];
|
|
|
|
f[1] = (float)d[1];
|
|
|
|
f[2] = (float)d[2];
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(1, true, f, LC_CK_TARGET);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
|
|
|
file.ReadDoubles(d, 3);
|
|
|
|
f[0] = (float)d[0];
|
|
|
|
f[1] = (float)d[1];
|
|
|
|
f[2] = (float)d[2];
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(1, true, f, LC_CK_UP);
|
2012-08-23 20:47:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (version == 3)
|
|
|
|
{
|
|
|
|
ch = file.ReadU8();
|
|
|
|
|
|
|
|
while (ch--)
|
|
|
|
{
|
|
|
|
lcuint8 step;
|
|
|
|
double eye[3], target[3], up[3];
|
|
|
|
float f[3];
|
|
|
|
|
|
|
|
file.ReadDoubles(eye, 3);
|
|
|
|
file.ReadDoubles(target, 3);
|
|
|
|
file.ReadDoubles(up, 3);
|
|
|
|
file.ReadU8(&step, 1);
|
|
|
|
|
|
|
|
if (up[0] == 0 && up[1] == 0 && up[2] == 0)
|
|
|
|
up[2] = 1;
|
|
|
|
|
|
|
|
f[0] = (float)eye[0];
|
|
|
|
f[1] = (float)eye[1];
|
|
|
|
f[2] = (float)eye[2];
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(step, true, f, LC_CK_EYE);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
|
|
|
f[0] = (float)target[0];
|
|
|
|
f[1] = (float)target[1];
|
|
|
|
f[2] = (float)target[2];
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(step, true, f, LC_CK_TARGET);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
|
|
|
f[0] = (float)up[0];
|
|
|
|
f[1] = (float)up[1];
|
|
|
|
f[2] = (float)up[2];
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(step, true, f, LC_CK_UP);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
|
|
|
file.ReadS32(); // snapshot
|
|
|
|
file.ReadS32(); // cam
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (version < 4)
|
|
|
|
{
|
|
|
|
m_fovy = (float)file.ReadDouble();
|
|
|
|
m_zFar = (float)file.ReadDouble();
|
|
|
|
m_zNear= (float)file.ReadDouble();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lcint32 n;
|
|
|
|
|
|
|
|
if (version < 6)
|
|
|
|
{
|
|
|
|
lcuint16 time;
|
|
|
|
float param[4];
|
|
|
|
lcuint8 type;
|
|
|
|
|
|
|
|
n = file.ReadS32();
|
|
|
|
while (n--)
|
|
|
|
{
|
|
|
|
file.ReadU16(&time, 1);
|
|
|
|
file.ReadFloats(param, 3);
|
|
|
|
file.ReadU8(&type, 1);
|
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
ChangeKey(time, true, param, type);
|
2012-08-23 20:47:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
n = file.ReadS32();
|
|
|
|
while (n--)
|
|
|
|
{
|
|
|
|
file.ReadU16(&time, 1);
|
|
|
|
file.ReadFloats(param, 3);
|
|
|
|
file.ReadU8(&type, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
file.ReadFloats(&m_fovy, 1);
|
|
|
|
file.ReadFloats(&m_zFar, 1);
|
|
|
|
file.ReadFloats(&m_zNear, 1);
|
|
|
|
|
|
|
|
if (version < 5)
|
|
|
|
{
|
|
|
|
n = file.ReadS32();
|
|
|
|
if (n != 0)
|
2014-05-01 16:55:12 +02:00
|
|
|
mState |= LC_CAMERA_HIDDEN;
|
2012-08-23 20:47:37 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-01 16:55:12 +02:00
|
|
|
ch = file.ReadU8();
|
|
|
|
if (ch & 1)
|
|
|
|
mState |= LC_CAMERA_HIDDEN;
|
2012-08-23 20:47:37 +02:00
|
|
|
m_nType = file.ReadU8();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((version > 1) && (version < 4))
|
|
|
|
{
|
|
|
|
lcuint32 show;
|
|
|
|
lcint32 user;
|
|
|
|
|
2013-01-06 20:24:25 +01:00
|
|
|
file.ReadU32(&show, 1);
|
2012-08-23 20:47:37 +02:00
|
|
|
// if (version > 2)
|
2013-01-06 20:24:25 +01:00
|
|
|
file.ReadS32(&user, 1);
|
2012-08-23 20:47:37 +02:00
|
|
|
if (show == 0)
|
2014-05-01 16:55:12 +02:00
|
|
|
mState |= LC_CAMERA_HIDDEN;
|
2012-08-23 20:47:37 +02:00
|
|
|
}
|
|
|
|
|
2014-08-30 21:48:36 +02:00
|
|
|
if (version < 7)
|
|
|
|
{
|
|
|
|
m_zFar *= 25.0f;
|
|
|
|
m_zNear *= 25.0f;
|
|
|
|
|
|
|
|
for (LC_OBJECT_KEY* Key = m_pInstructionKeys; Key; Key = Key->next)
|
|
|
|
{
|
|
|
|
if (Key->type == LC_CK_EYE || Key->type == LC_CK_TARGET)
|
|
|
|
{
|
|
|
|
Key->param[0] *= 25.0f;
|
|
|
|
Key->param[1] *= 25.0f;
|
|
|
|
Key->param[2] *= 25.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-23 20:47:37 +02:00
|
|
|
return true;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
void lcCamera::FileSave(lcFile& file) const
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
file.WriteU8(LC_CAMERA_SAVE_VERSION);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-08-07 17:22:33 +02:00
|
|
|
lcObject::FileSave(file);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
lcuint8 ch = (lcuint8)strlen(m_strName);
|
2012-08-23 20:47:37 +02:00
|
|
|
file.WriteU8(ch);
|
|
|
|
file.WriteBuffer(m_strName, ch);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-23 20:47:37 +02:00
|
|
|
file.WriteFloat(m_fovy);
|
|
|
|
file.WriteFloat(m_zFar);
|
|
|
|
file.WriteFloat(m_zNear);
|
|
|
|
// version 5
|
2014-05-01 16:55:12 +02:00
|
|
|
file.WriteU8(mState & LC_CAMERA_HIDDEN ? 1 : 0);
|
2012-08-23 20:47:37 +02:00
|
|
|
file.WriteU8(m_nType);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Camera operations
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::Move(lcStep Step, bool AddKey, const lcVector3& Distance)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-06-22 19:39:15 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
if (IsSelected(LC_CAMERA_SECTION_POSITION))
|
2012-05-29 01:33:22 +02:00
|
|
|
{
|
2014-06-22 19:39:15 +02:00
|
|
|
mPosition += Distance;
|
2013-12-17 03:43:16 +01:00
|
|
|
lcAlign(mOrthoTarget, mPosition, mTargetPosition);
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
2012-08-20 06:05:56 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
if (IsSelected(LC_CAMERA_SECTION_TARGET))
|
2012-08-20 06:05:56 +02:00
|
|
|
{
|
2014-06-22 19:39:15 +02:00
|
|
|
mTargetPosition += Distance;
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
2012-08-20 06:05:56 +02:00
|
|
|
}
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
if (IsSelected(LC_CAMERA_SECTION_UPVECTOR))
|
2012-08-23 20:47:37 +02:00
|
|
|
{
|
2014-06-22 19:39:15 +02:00
|
|
|
mUpVector += Distance;
|
2014-05-01 16:55:12 +02:00
|
|
|
mUpVector.Normalize();
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_UP);
|
2012-08-23 20:47:37 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
lcVector3 FrontVector(mTargetPosition - mPosition);
|
|
|
|
lcVector3 SideVector = lcCross(FrontVector, mUpVector);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
if (fabsf(lcDot(mUpVector, SideVector)) > 0.99f)
|
|
|
|
SideVector = lcVector3(1, 0, 0);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
mUpVector = lcCross(SideVector, FrontVector);
|
|
|
|
mUpVector.Normalize();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::UpdatePosition(lcStep Step)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-07-06 08:04:09 +02:00
|
|
|
CalculateKeys(Step);
|
2012-05-29 01:33:22 +02:00
|
|
|
|
|
|
|
lcVector3 FrontVector(mPosition - mTargetPosition);
|
|
|
|
lcVector3 SideVector = lcCross(FrontVector, mUpVector);
|
|
|
|
mUpVector = lcNormalize(lcCross(SideVector, FrontVector));
|
|
|
|
|
|
|
|
mWorldView = lcMatrix44LookAt(mPosition, mTargetPosition, mUpVector);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-08-07 17:22:33 +02:00
|
|
|
void lcCamera::CopyPosition(const lcCamera* camera)
|
2012-08-20 06:05:56 +02:00
|
|
|
{
|
|
|
|
m_fovy = camera->m_fovy;
|
|
|
|
m_zNear = camera->m_zNear;
|
|
|
|
m_zFar = camera->m_zFar;
|
|
|
|
|
|
|
|
mWorldView = camera->mWorldView;
|
|
|
|
mPosition = camera->mPosition;
|
|
|
|
mTargetPosition = camera->mTargetPosition;
|
2013-12-17 03:43:16 +01:00
|
|
|
mOrthoTarget = camera->mOrthoTarget;
|
2012-08-20 06:05:56 +02:00
|
|
|
mUpVector = camera->mUpVector;
|
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
void lcCamera::Render(View* View)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-14 05:20:16 +02:00
|
|
|
float LineWidth = lcGetPreferences().mLineWidth;
|
|
|
|
const lcMatrix44& ViewMatrix = View->mCamera->mWorldView;
|
|
|
|
lcContext* Context = View->mContext;
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2014-04-14 05:20:16 +02:00
|
|
|
lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView);
|
2014-05-01 16:55:12 +02:00
|
|
|
lcVector3 UpVectorPosition = lcMul31(lcVector3(0, 1, 0), ViewWorld);
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
float Verts[34 + 24 + 4][3] =
|
2012-05-29 01:33:22 +02:00
|
|
|
{
|
|
|
|
{ 0.3f, 0.3f, 0.3f }, { -0.3f, 0.3f, 0.3f },
|
|
|
|
{ -0.3f, 0.3f, 0.3f }, { -0.3f, -0.3f, 0.3f },
|
|
|
|
{ -0.3f, -0.3f, 0.3f }, { 0.3f, -0.3f, 0.3f },
|
|
|
|
{ 0.3f, -0.3f, 0.3f }, { 0.3f, 0.3f, 0.3f },
|
|
|
|
{ 0.3f, 0.3f, -0.3f }, { -0.3f, 0.3f, -0.3f },
|
|
|
|
{ -0.3f, 0.3f, -0.3f }, { -0.3f, -0.3f, -0.3f },
|
|
|
|
{ -0.3f, -0.3f, -0.3f }, { 0.3f, -0.3f, -0.3f },
|
|
|
|
{ 0.3f, -0.3f, -0.3f }, { 0.3f, 0.3f, -0.3f },
|
|
|
|
{ 0.3f, 0.3f, 0.3f }, { 0.3f, 0.3f, -0.3f },
|
|
|
|
{ -0.3f, 0.3f, 0.3f }, { -0.3f, 0.3f, -0.3f },
|
|
|
|
{ -0.3f, -0.3f, 0.3f }, { -0.3f, -0.3f, -0.3f },
|
|
|
|
{ 0.3f, -0.3f, 0.3f }, { 0.3f, -0.3f, -0.3f },
|
|
|
|
{ -0.3f, -0.3f, -0.6f }, { -0.3f, 0.3f, -0.6f },
|
|
|
|
{ 0.0f, 0.0f, -0.3f }, { -0.3f, -0.3f, -0.6f },
|
|
|
|
{ 0.3f, -0.3f, -0.6f }, { 0.0f, 0.0f, -0.3f },
|
|
|
|
{ 0.3f, 0.3f, -0.6f }, { 0.3f, -0.3f, -0.6f },
|
2014-05-01 16:55:12 +02:00
|
|
|
{ 0.3f, 0.3f, -0.6f }, { -0.3f, 0.3f, -0.6f },
|
|
|
|
|
|
|
|
{ 0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, 0.2f },
|
|
|
|
{ -0.2f, 0.2f, 0.2f }, { -0.2f, -0.2f, 0.2f },
|
|
|
|
{ -0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, 0.2f },
|
|
|
|
{ 0.2f, -0.2f, 0.2f }, { 0.2f, 0.2f, 0.2f },
|
|
|
|
{ 0.2f, 0.2f, -0.2f }, { -0.2f, 0.2f, -0.2f },
|
|
|
|
{ -0.2f, 0.2f, -0.2f }, { -0.2f, -0.2f, -0.2f },
|
|
|
|
{ -0.2f, -0.2f, -0.2f }, { 0.2f, -0.2f, -0.2f },
|
|
|
|
{ 0.2f, -0.2f, -0.2f }, { 0.2f, 0.2f, -0.2f },
|
|
|
|
{ 0.2f, 0.2f, 0.2f }, { 0.2f, 0.2f, -0.2f },
|
|
|
|
{ -0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, -0.2f },
|
|
|
|
{ -0.2f, -0.2f, 0.2f }, { -0.2f, -0.2f, -0.2f },
|
|
|
|
{ 0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, -0.2f },
|
|
|
|
|
|
|
|
{ mPosition[0], mPosition[1], mPosition[2] },
|
|
|
|
{ mTargetPosition[0], mTargetPosition[1], mTargetPosition[2] },
|
|
|
|
{ mPosition[0], mPosition[1], mPosition[2] },
|
|
|
|
{ UpVectorPosition[0], UpVectorPosition[1], UpVectorPosition[2] },
|
2012-05-29 01:33:22 +02:00
|
|
|
};
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
Context->SetWorldViewMatrix(lcMul(ViewWorld, ViewMatrix));
|
|
|
|
|
|
|
|
if (IsSelected(LC_CAMERA_SECTION_POSITION))
|
2012-08-23 20:47:37 +02:00
|
|
|
{
|
2014-04-14 05:20:16 +02:00
|
|
|
Context->SetLineWidth(2.0f * LineWidth);
|
2014-05-01 16:55:12 +02:00
|
|
|
if (IsFocused(LC_CAMERA_SECTION_POSITION))
|
2012-08-23 20:47:37 +02:00
|
|
|
lcSetColorFocused();
|
|
|
|
else
|
|
|
|
lcSetColorSelected();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-04-14 05:20:16 +02:00
|
|
|
Context->SetLineWidth(LineWidth);
|
2012-08-23 20:47:37 +02:00
|
|
|
lcSetColorCamera();
|
|
|
|
}
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
glVertexPointer(3, GL_FLOAT, 0, Verts);
|
2012-05-29 01:33:22 +02:00
|
|
|
glDrawArrays(GL_LINES, 0, 24);
|
|
|
|
glDrawArrays(GL_LINE_STRIP, 24, 10);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-12-17 03:43:16 +01:00
|
|
|
lcMatrix44 TargetMat = ViewWorld;
|
2012-08-23 20:47:37 +02:00
|
|
|
TargetMat.SetTranslation(mTargetPosition);
|
2014-05-01 16:55:12 +02:00
|
|
|
Context->SetWorldViewMatrix(lcMul(TargetMat, ViewMatrix));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
if (IsSelected(LC_CAMERA_SECTION_TARGET))
|
2012-08-23 20:47:37 +02:00
|
|
|
{
|
2014-04-14 05:20:16 +02:00
|
|
|
Context->SetLineWidth(2.0f * LineWidth);
|
2014-05-01 16:55:12 +02:00
|
|
|
if (IsFocused(LC_CAMERA_SECTION_TARGET))
|
2012-08-23 20:47:37 +02:00
|
|
|
lcSetColorFocused();
|
|
|
|
else
|
|
|
|
lcSetColorSelected();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-04-14 05:20:16 +02:00
|
|
|
Context->SetLineWidth(LineWidth);
|
2012-08-23 20:47:37 +02:00
|
|
|
lcSetColorCamera();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
glDrawArrays(GL_LINES, 34, 24);
|
2014-02-16 08:23:55 +01:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
lcMatrix44 UpVectorMat = ViewWorld;
|
|
|
|
UpVectorMat.SetTranslation(UpVectorPosition);
|
|
|
|
Context->SetWorldViewMatrix(lcMul(UpVectorMat, ViewMatrix));
|
2012-08-23 20:47:37 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
if (IsSelected(LC_CAMERA_SECTION_UPVECTOR))
|
2012-08-23 20:47:37 +02:00
|
|
|
{
|
2014-05-01 16:55:12 +02:00
|
|
|
Context->SetLineWidth(2.0f * LineWidth);
|
|
|
|
if (IsFocused(LC_CAMERA_SECTION_UPVECTOR))
|
|
|
|
lcSetColorFocused();
|
|
|
|
else
|
|
|
|
lcSetColorSelected();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Context->SetLineWidth(LineWidth);
|
|
|
|
lcSetColorCamera();
|
|
|
|
}
|
2012-08-23 20:47:37 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
glDrawArrays(GL_LINES, 34, 24);
|
|
|
|
|
|
|
|
Context->SetWorldViewMatrix(ViewMatrix);
|
|
|
|
|
|
|
|
lcSetColorCamera();
|
2014-04-14 05:20:16 +02:00
|
|
|
Context->SetLineWidth(LineWidth);
|
2014-05-01 16:55:12 +02:00
|
|
|
|
|
|
|
glDrawArrays(GL_LINES, 34 + 24, 4);
|
2012-08-23 20:47:37 +02:00
|
|
|
|
|
|
|
if (IsSelected())
|
2012-05-29 01:33:22 +02:00
|
|
|
{
|
2014-05-01 16:55:12 +02:00
|
|
|
Context->SetWorldViewMatrix(lcMul(ViewWorld, ViewMatrix));
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2012-08-23 20:47:37 +02:00
|
|
|
float Dist = lcLength(mTargetPosition - mPosition);
|
|
|
|
lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, 1.33f, 0.01f, Dist);
|
|
|
|
Projection = lcMatrix44Inverse(Projection);
|
|
|
|
glMultMatrixf(Projection);
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2013-02-13 00:36:30 +01:00
|
|
|
float ProjVerts[16][3] =
|
2012-05-29 01:33:22 +02:00
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
{ 1, 1, 1 }, { -1, 1, 1 },
|
|
|
|
{ -1, 1, 1 }, { -1, -1, 1 },
|
|
|
|
{ -1, -1, 1 }, { 1, -1, 1 },
|
|
|
|
{ 1, -1, 1 }, { 1, 1, 1 },
|
|
|
|
{ 1, 1, -1 }, { 1, 1, 1 },
|
|
|
|
{ -1, 1, -1 }, { -1, 1, 1 },
|
|
|
|
{ -1, -1, -1 }, { -1, -1, 1 },
|
|
|
|
{ 1, -1, -1 }, { 1, -1, 1 },
|
2012-05-29 01:33:22 +02:00
|
|
|
};
|
|
|
|
|
2013-02-13 00:36:30 +01:00
|
|
|
glVertexPointer(3, GL_FLOAT, 0, ProjVerts);
|
2012-08-23 20:47:37 +02:00
|
|
|
glDrawArrays(GL_LINES, 0, 16);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
void lcCamera::RayTest(lcObjectRayTest& ObjectRayTest) const
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-17 01:50:40 +02:00
|
|
|
lcVector3 Min = lcVector3(-0.3f, -0.3f, -0.3f);
|
|
|
|
lcVector3 Max = lcVector3(0.3f, 0.3f, 0.3f);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
lcVector3 Start = lcMul31(ObjectRayTest.Start, mWorldView);
|
|
|
|
lcVector3 End = lcMul31(ObjectRayTest.End, mWorldView);
|
|
|
|
|
|
|
|
float Distance;
|
|
|
|
if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
|
|
|
{
|
2014-08-07 17:22:33 +02:00
|
|
|
ObjectRayTest.ObjectSection.Object = const_cast<lcCamera*>(this);
|
2014-05-01 16:55:12 +02:00
|
|
|
ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_POSITION;
|
|
|
|
ObjectRayTest.Distance = Distance;
|
|
|
|
}
|
|
|
|
|
|
|
|
Min = lcVector3(-0.2f, -0.2f, -0.2f);
|
|
|
|
Max = lcVector3(0.2f, 0.2f, 0.2f);
|
|
|
|
|
|
|
|
lcMatrix44 WorldView = mWorldView;
|
|
|
|
WorldView.SetTranslation(lcMul30(-mTargetPosition, WorldView));
|
|
|
|
|
|
|
|
Start = lcMul31(ObjectRayTest.Start, WorldView);
|
|
|
|
End = lcMul31(ObjectRayTest.End, WorldView);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
2012-08-17 01:50:40 +02:00
|
|
|
{
|
2014-08-07 17:22:33 +02:00
|
|
|
ObjectRayTest.ObjectSection.Object = const_cast<lcCamera*>(this);
|
2014-05-01 16:55:12 +02:00
|
|
|
ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_TARGET;
|
|
|
|
ObjectRayTest.Distance = Distance;
|
2012-08-17 01:50:40 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView);
|
|
|
|
lcVector3 UpVectorPosition = lcMul31(lcVector3(0, 1, 0), ViewWorld);
|
|
|
|
|
|
|
|
WorldView = mWorldView;
|
|
|
|
WorldView.SetTranslation(lcMul30(-UpVectorPosition, WorldView));
|
|
|
|
|
|
|
|
Start = lcMul31(ObjectRayTest.Start, WorldView);
|
|
|
|
End = lcMul31(ObjectRayTest.End, WorldView);
|
|
|
|
|
|
|
|
if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance))
|
|
|
|
{
|
2014-08-07 17:22:33 +02:00
|
|
|
ObjectRayTest.ObjectSection.Object = const_cast<lcCamera*>(this);
|
2014-05-01 16:55:12 +02:00
|
|
|
ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_UPVECTOR;
|
|
|
|
ObjectRayTest.Distance = Distance;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
void lcCamera::BoxTest(lcObjectBoxTest& ObjectBoxTest) const
|
2012-08-23 20:47:37 +02:00
|
|
|
{
|
|
|
|
lcVector3 Min(-0.3f, -0.3f, -0.3f);
|
|
|
|
lcVector3 Max(0.3f, 0.3f, 0.3f);
|
|
|
|
|
|
|
|
lcVector4 LocalPlanes[6];
|
|
|
|
|
|
|
|
for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++)
|
|
|
|
{
|
2014-05-01 16:55:12 +02:00
|
|
|
lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], mWorldView);
|
|
|
|
LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(mWorldView[3], Normal));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes))
|
|
|
|
{
|
|
|
|
lcObjectSection& ObjectSection = ObjectBoxTest.ObjectSections.Add();
|
2014-08-07 17:22:33 +02:00
|
|
|
ObjectSection.Object = const_cast<lcCamera*>(this);
|
2014-05-01 16:55:12 +02:00
|
|
|
ObjectSection.Section = LC_CAMERA_SECTION_POSITION;
|
|
|
|
}
|
|
|
|
|
|
|
|
Min = lcVector3(-0.2f, -0.2f, -0.2f);
|
|
|
|
Max = lcVector3(0.2f, 0.2f, 0.2f);
|
|
|
|
|
|
|
|
lcMatrix44 WorldView = mWorldView;
|
|
|
|
WorldView.SetTranslation(lcMul30(-mTargetPosition, WorldView));
|
|
|
|
|
|
|
|
for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++)
|
|
|
|
{
|
|
|
|
lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], WorldView);
|
|
|
|
LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(WorldView[3], Normal));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes))
|
|
|
|
{
|
|
|
|
lcObjectSection& ObjectSection = ObjectBoxTest.ObjectSections.Add();
|
2014-08-07 17:22:33 +02:00
|
|
|
ObjectSection.Object = const_cast<lcCamera*>(this);
|
2014-05-01 16:55:12 +02:00
|
|
|
ObjectSection.Section = LC_CAMERA_SECTION_TARGET;
|
|
|
|
}
|
|
|
|
|
|
|
|
lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView);
|
|
|
|
lcVector3 UpVectorPosition = lcMul31(lcVector3(0, 1, 0), ViewWorld);
|
|
|
|
|
|
|
|
WorldView = mWorldView;
|
|
|
|
WorldView.SetTranslation(lcMul30(-UpVectorPosition, WorldView));
|
|
|
|
|
|
|
|
for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++)
|
|
|
|
{
|
|
|
|
lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], WorldView);
|
|
|
|
LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(WorldView[3], Normal));
|
2012-08-23 20:47:37 +02:00
|
|
|
}
|
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes))
|
|
|
|
{
|
|
|
|
lcObjectSection& ObjectSection = ObjectBoxTest.ObjectSections.Add();
|
2014-08-07 17:22:33 +02:00
|
|
|
ObjectSection.Object = const_cast<lcCamera*>(this);
|
2014-05-01 16:55:12 +02:00
|
|
|
ObjectSection.Section = LC_CAMERA_SECTION_UPVECTOR;
|
|
|
|
}
|
2012-08-23 20:47:37 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::ZoomExtents(View* view, const lcVector3& Center, const lcVector3* Points, int NumPoints, lcStep Step, bool AddKey)
|
2012-08-20 06:05:56 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight };
|
2012-08-20 06:05:56 +02:00
|
|
|
|
|
|
|
float Aspect = (float)Viewport[2]/(float)Viewport[3];
|
|
|
|
|
|
|
|
lcVector3 Position(mPosition + Center - mTargetPosition);
|
|
|
|
|
|
|
|
lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, Aspect, m_zNear, m_zFar);
|
|
|
|
|
|
|
|
mPosition = lcZoomExtents(Position, mWorldView, Projection, Points, NumPoints);
|
|
|
|
mTargetPosition = Center;
|
2013-12-17 03:43:16 +01:00
|
|
|
mOrthoTarget = mTargetPosition;
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2012-08-20 06:05:56 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::ZoomRegion(const lcVector3* Points, float RatioX, float RatioY, lcStep Step, bool AddKey)
|
2013-04-10 02:52:06 +02:00
|
|
|
{
|
|
|
|
// Center camera.
|
|
|
|
lcVector3 Eye = mPosition;
|
|
|
|
Eye = Eye + (Points[0] - Points[1]);
|
|
|
|
|
|
|
|
lcVector3 Target = mTargetPosition;
|
|
|
|
Target = Target + (Points[0] - Points[1]);
|
|
|
|
|
|
|
|
// Zoom in/out.
|
|
|
|
float ZoomFactor = -lcMax(RatioX, RatioY) + 0.75f;
|
|
|
|
|
|
|
|
lcVector3 Dir = Points[1] - Points[2];
|
|
|
|
mPosition = Eye + Dir * ZoomFactor;
|
|
|
|
mTargetPosition = Target + Dir * ZoomFactor;
|
|
|
|
|
|
|
|
// Change the camera and redraw.
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
2013-04-10 02:52:06 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2013-04-10 02:52:06 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::Zoom(float Distance, lcStep Step, bool AddKey)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-05-29 01:33:22 +02:00
|
|
|
lcVector3 FrontVector(mPosition - mTargetPosition);
|
|
|
|
FrontVector.Normalize();
|
2014-05-18 01:03:05 +02:00
|
|
|
FrontVector *= -Distance;
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2013-12-17 03:43:16 +01:00
|
|
|
// Don't zoom ortho in if it would cross the ortho focal plane.
|
2014-05-03 03:22:24 +02:00
|
|
|
if (IsOrtho())
|
2013-12-17 03:43:16 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((Distance > 0) && (lcDot(mPosition + FrontVector - mOrthoTarget, mPosition - mOrthoTarget) <= 0))
|
2013-12-17 03:43:16 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-05-29 01:33:22 +02:00
|
|
|
mPosition += FrontVector;
|
|
|
|
mTargetPosition += FrontVector;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::Pan(float DistanceX, float DistanceY, lcStep Step, bool AddKey)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-05-29 01:33:22 +02:00
|
|
|
lcVector3 FrontVector(mPosition - mTargetPosition);
|
|
|
|
lcVector3 SideVector = lcNormalize(lcCross(FrontVector, mUpVector));
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 MoveVec = (SideVector * DistanceX) + (mUpVector * -DistanceY);
|
2013-02-13 00:36:30 +01:00
|
|
|
mPosition += MoveVec;
|
|
|
|
mTargetPosition += MoveVec;
|
2013-12-17 03:43:16 +01:00
|
|
|
mOrthoTarget += MoveVec;
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::Orbit(float DistanceX, float DistanceY, const lcVector3& CenterPosition, lcStep Step, bool AddKey)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-05-29 01:33:22 +02:00
|
|
|
lcVector3 FrontVector(mPosition - mTargetPosition);
|
|
|
|
|
2013-01-27 02:22:37 +01:00
|
|
|
lcVector3 Z(lcNormalize(lcVector3(FrontVector[0], FrontVector[1], 0)));
|
|
|
|
if (isnan(Z[0]) || isnan(Z[1]))
|
|
|
|
Z = lcNormalize(lcVector3(mUpVector[0], mUpVector[1], 0));
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2013-01-27 02:22:37 +01:00
|
|
|
if (mUpVector[2] < 0)
|
|
|
|
{
|
|
|
|
Z[0] = -Z[0];
|
|
|
|
Z[1] = -Z[1];
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2013-01-27 02:22:37 +01:00
|
|
|
lcMatrix44 YRot(lcVector4(Z[0], Z[1], 0.0f, 0.0f), lcVector4(-Z[1], Z[0], 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
|
2014-05-18 01:03:05 +02:00
|
|
|
lcMatrix44 transform = lcMul(lcMul(lcMul(lcMatrix44AffineInverse(YRot), lcMatrix44RotationY(DistanceY)), YRot), lcMatrix44RotationZ(-DistanceX));
|
2013-01-27 02:22:37 +01:00
|
|
|
|
|
|
|
mPosition = lcMul31(mPosition - CenterPosition, transform) + CenterPosition;
|
|
|
|
mTargetPosition = lcMul31(mTargetPosition - CenterPosition, transform) + CenterPosition;
|
2013-12-17 03:43:16 +01:00
|
|
|
lcAlign(mOrthoTarget, mPosition, mTargetPosition);
|
|
|
|
|
2013-01-27 02:22:37 +01:00
|
|
|
mUpVector = lcMul31(mUpVector, transform);
|
2012-05-29 01:33:22 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
|
|
|
ChangeKey(Step, AddKey, mUpVector, LC_CK_UP);
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::Roll(float Distance, lcStep Step, bool AddKey)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-05-29 01:33:22 +02:00
|
|
|
lcVector3 FrontVector(mPosition - mTargetPosition);
|
2014-05-18 01:03:05 +02:00
|
|
|
lcMatrix44 Rotation = lcMatrix44FromAxisAngle(FrontVector, Distance);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-05-29 01:33:22 +02:00
|
|
|
mUpVector = lcMul30(mUpVector, Rotation);
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mUpVector, LC_CK_UP);
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2012-08-20 06:05:56 +02:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::Center(lcVector3& point, lcStep Step, bool AddKey)
|
2013-12-17 23:23:41 +01:00
|
|
|
{
|
|
|
|
lcAlign(mTargetPosition, mPosition, point);
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
2013-12-17 23:23:41 +01:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2013-12-17 23:23:41 +01:00
|
|
|
}
|
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::SetViewpoint(LC_VIEWPOINT Viewpoint, lcStep Step, bool AddKey)
|
2012-08-20 06:05:56 +02:00
|
|
|
{
|
|
|
|
lcVector3 Positions[] =
|
|
|
|
{
|
2014-08-30 21:48:36 +02:00
|
|
|
lcVector3( 0.0f, -1250.0f, 0.0f), // LC_VIEWPOINT_FRONT
|
|
|
|
lcVector3( 0.0f, 1250.0f, 0.0f), // LC_VIEWPOINT_BACK
|
|
|
|
lcVector3( 0.0f, 0.0f, 1250.0f), // LC_VIEWPOINT_TOP
|
|
|
|
lcVector3( 0.0f, 0.0f, -1250.0f), // LC_VIEWPOINT_BOTTOM
|
|
|
|
lcVector3( 1250.0f, 0.0f, 0.0f), // LC_VIEWPOINT_LEFT
|
|
|
|
lcVector3(-1250.0f, 0.0f, 0.0f), // LC_VIEWPOINT_RIGHT
|
|
|
|
lcVector3( -375.0f, -375.0f, 187.5f) // LC_VIEWPOINT_HOME
|
2012-08-20 06:05:56 +02:00
|
|
|
};
|
|
|
|
|
2013-01-27 02:36:11 +01:00
|
|
|
lcVector3 Ups[] =
|
|
|
|
{
|
|
|
|
lcVector3( 0.0f, 0.0f, 1.0f),
|
|
|
|
lcVector3( 0.0f, 0.0f, 1.0f),
|
|
|
|
lcVector3( 0.0f, 1.0f, 0.0f),
|
|
|
|
lcVector3( 0.0f,-1.0f, 0.0f),
|
|
|
|
lcVector3( 0.0f, 0.0f, 1.0f),
|
|
|
|
lcVector3( 0.0f, 0.0f, 1.0f),
|
|
|
|
lcVector3(-0.2357f, -0.2357f, 0.94281f)
|
|
|
|
};
|
2012-08-20 06:05:56 +02:00
|
|
|
|
|
|
|
mPosition = Positions[Viewpoint];
|
|
|
|
mTargetPosition = lcVector3(0, 0, 0);
|
2013-12-17 03:43:16 +01:00
|
|
|
mOrthoTarget = mTargetPosition;
|
2012-08-20 06:05:56 +02:00
|
|
|
mUpVector = Ups[Viewpoint];
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
|
|
|
ChangeKey(Step, AddKey, mUpVector, LC_CK_UP);
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-03 08:08:52 +02:00
|
|
|
void lcCamera::StartTiledRendering(int tw, int th, int iw, int ih, float AspectRatio)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
m_pTR = new TiledRender();
|
|
|
|
m_pTR->TileSize(tw, th, 0);
|
|
|
|
m_pTR->ImageSize(iw, ih);
|
2014-05-03 08:08:52 +02:00
|
|
|
if (IsOrtho())
|
|
|
|
{
|
|
|
|
float f = (mPosition - mOrthoTarget).Length();
|
|
|
|
float d = (m_fovy * f) * (LC_PI / 180.0f);
|
|
|
|
float r = d / 2;
|
|
|
|
|
|
|
|
float right = r * AspectRatio;
|
|
|
|
m_pTR->Ortho(-right, right, -r, r, m_zNear, m_zFar * 4);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_pTR->Perspective(m_fovy, AspectRatio, m_zNear, m_zFar);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
void lcCamera::GetTileInfo(int* row, int* col, int* width, int* height)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
if (m_pTR != NULL)
|
|
|
|
{
|
|
|
|
*row = m_pTR->m_Rows - m_pTR->m_CurrentRow - 1;
|
|
|
|
*col = m_pTR->m_CurrentColumn;
|
|
|
|
*width = m_pTR->m_CurrentTileWidth;
|
|
|
|
*height = m_pTR->m_CurrentTileHeight;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-01 20:42:11 +02:00
|
|
|
bool lcCamera::EndTile()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
if (m_pTR != NULL)
|
|
|
|
{
|
|
|
|
if (m_pTR->EndTile())
|
|
|
|
return true;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-23 20:47:37 +02:00
|
|
|
delete m_pTR;
|
|
|
|
m_pTR = NULL;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-23 20:47:37 +02:00
|
|
|
return false;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
void lcCamera::SetFocalPoint(const lcVector3& focus, lcStep Step, bool AddKey)
|
2013-12-17 03:43:16 +01:00
|
|
|
{
|
2014-05-03 03:22:24 +02:00
|
|
|
if (IsOrtho())
|
2013-12-17 03:43:16 +01:00
|
|
|
{
|
|
|
|
lcVector3 FocusVector = focus;
|
|
|
|
lcAlign(FocusVector, mPosition, mTargetPosition);
|
|
|
|
lcAlign(mOrthoTarget, mPosition, mTargetPosition);
|
|
|
|
lcVector3 TranslateVector = FocusVector - mOrthoTarget;
|
|
|
|
mPosition += TranslateVector;
|
|
|
|
mTargetPosition += TranslateVector;
|
|
|
|
mOrthoTarget = FocusVector;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mOrthoTarget = focus;
|
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (IsSimple())
|
2014-07-06 08:04:09 +02:00
|
|
|
AddKey = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
ChangeKey(Step, AddKey, mPosition, LC_CK_EYE);
|
|
|
|
ChangeKey(Step, AddKey, mTargetPosition, LC_CK_TARGET);
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-07-06 08:04:09 +02:00
|
|
|
UpdatePosition(Step);
|
2013-12-17 03:43:16 +01:00
|
|
|
}
|