From 2ceba627a0bca558f53c4e50097394525abcc9d4 Mon Sep 17 00:00:00 2001 From: leo Date: Sun, 27 Jan 2013 01:22:37 +0000 Subject: [PATCH] Improved camera rotation. --- common/camera.cpp | 30 +++++++++++++++++++----------- common/defines.h | 2 ++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/common/camera.cpp b/common/camera.cpp index 1454068b..5c00d53a 100644 --- a/common/camera.cpp +++ b/common/camera.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "opengl.h" #include "globals.h" #include "lc_file.h" @@ -721,21 +722,28 @@ void Camera::DoPan(int dx, int dy, int mouse, unsigned short nTime, bool bAnimat UpdatePosition(nTime, bAnimation); } -void Camera::DoRotate(int dx, int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey, float* /*center*/) +void Camera::DoRotate(int dx, int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey, float* center) { lcVector3 FrontVector(mPosition - mTargetPosition); - lcVector3 SideVector = lcNormalize(lcCross(FrontVector, mUpVector)); + lcVector3 CenterPosition(center[0], center[1], center[2]); - // TODO: option to move eye or target - float len = FrontVector.Length(); - FrontVector += (SideVector * (2.0f * dx / (21 - mouse))) + (mUpVector * (-2.0f * dy / (21 - mouse))); - FrontVector.Normalize(); - mPosition = (FrontVector * len) + mTargetPosition; + lcVector3 Z(lcNormalize(lcVector3(FrontVector[0], FrontVector[1], 0))); + if (isnan(Z[0]) || isnan(Z[1])) + Z = lcNormalize(lcVector3(mUpVector[0], mUpVector[1], 0)); - // Calculate new up - FrontVector = mPosition - mTargetPosition; - SideVector = lcCross(FrontVector, mUpVector); - mUpVector = lcNormalize(lcCross(SideVector, FrontVector)); + if (mUpVector[2] < 0) + { + Z[0] = -Z[0]; + Z[1] = -Z[1]; + dx = -dx; + } + + 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)); + lcMatrix44 transform = lcMul(lcMul(lcMul(lcMatrix44AffineInverse(YRot), lcMatrix44RotationY(0.1f * dy / (21 - mouse))), YRot), lcMatrix44RotationZ(-0.1f * dx / (21 - mouse))); + + mPosition = lcMul31(mPosition - CenterPosition, transform) + CenterPosition; + mTargetPosition = lcMul31(mTargetPosition - CenterPosition, transform) + CenterPosition; + mUpVector = lcMul31(mUpVector, transform); if (!IsSimple()) { diff --git a/common/defines.h b/common/defines.h index 2aaf6605..a99c258c 100644 --- a/common/defines.h +++ b/common/defines.h @@ -29,6 +29,8 @@ #define KEY_NEXT VK_NEXT #define KEY_PLUS VK_ADD #define KEY_MINUS VK_SUBTRACT + +#define isnan _isnan #endif #ifdef LC_LINUX