From 1c5c82a60945082344a186b664dbb3b9d0d1a4bd Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Wed, 25 Dec 2019 12:25:32 -0800 Subject: [PATCH] Avoid rolling the camera when using Look At. Fixes #407. --- common/camera.cpp | 37 ++++++++++++++++++++++++++++++++++--- common/camera.h | 2 +- common/lc_math.h | 8 -------- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/common/camera.cpp b/common/camera.cpp index 1480aa77..17c71744 100644 --- a/common/camera.cpp +++ b/common/camera.cpp @@ -957,15 +957,46 @@ void lcCamera::Roll(float Distance, lcStep Step, bool AddKey) UpdatePosition(Step); } -void lcCamera::Center(lcVector3& point, lcStep Step, bool AddKey) +void lcCamera::Center(const lcVector3& NewCenter, lcStep Step, bool AddKey) { - lcAlign(mTargetPosition, mPosition, point); + const lcMatrix44 Inverse = lcMatrix44AffineInverse(mWorldView); + const lcVector3 Direction = -lcVector3(Inverse[2]); + + float Yaw, Pitch, Roll; + + if (fabsf(Direction.z) < 0.9999f) + { + Yaw = atan2f(Direction.y, Direction.x); + Pitch = asinf(Direction.z); + Roll = atan2f(Inverse[0][2], Inverse[1][2]); + } + else + { + Yaw = 0.0f; + Pitch = asinf(Direction.z); + Roll = atan2f(Inverse[0][1], Inverse[1][1]); + } + + mTargetPosition = NewCenter; + + lcVector3 FrontVector(mPosition - mTargetPosition); + lcMatrix44 Rotation = lcMatrix44FromAxisAngle(FrontVector, Roll); + + lcVector3 UpVector(0, 0, 1), SideVector; + FrontVector.Normalize(); + if (fabsf(lcDot(UpVector, FrontVector)) > 0.99f) + SideVector = lcVector3(-1, 0, 0); + else + SideVector = lcCross(FrontVector, UpVector); + UpVector = lcCross(SideVector, FrontVector); + UpVector.Normalize(); + mUpVector = lcMul30(UpVector, Rotation); if (IsSimple()) AddKey = false; - ChangeKey(mPositionKeys, mPosition, Step, AddKey); ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); + ChangeKey(mUpVectorKeys, mUpVector, Step, AddKey); UpdatePosition(Step); } diff --git a/common/camera.h b/common/camera.h index fc1a988f..a3a9ae17 100644 --- a/common/camera.h +++ b/common/camera.h @@ -281,7 +281,7 @@ public: void Pan(const lcVector3& Distance, lcStep Step, bool AddKey); void Orbit(float DistanceX, float DistanceY, const lcVector3& CenterPosition, lcStep Step, bool AddKey); void Roll(float Distance, lcStep Step, bool AddKey); - void Center(lcVector3& point, lcStep Step, bool AddKey); + void Center(const lcVector3& NewCenter, lcStep Step, bool AddKey); void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance); void MoveRelative(const lcVector3& Distance, lcStep Step, bool AddKey); void SetViewpoint(lcViewpoint Viewpoint); diff --git a/common/lc_math.h b/common/lc_math.h index 8b511bc3..c83fca5b 100644 --- a/common/lc_math.h +++ b/common/lc_math.h @@ -482,14 +482,6 @@ inline lcVector3 lcNormalize(const lcVector3& a) return Ret; } -inline void lcAlign(lcVector3& t, const lcVector3& a, const lcVector3& b) -{ - lcVector3 Vector(b - a); - Vector.Normalize(); - Vector *= (t - a).Length(); - t = a + Vector; -} - inline float lcDot(const lcVector3& a, const lcVector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z;