From: Latif Khalifa Date: Mon, 4 Jul 2011 10:47:00 +0000 (+0000) Subject: Implement smooth camera focus when picking (alt+mouse click). X-Git-Tag: 2.8~416 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b35eae5adae11173384f81e1963d108a6b4b9408;p=radegast%2Fradegast.git Implement smooth camera focus when picking (alt+mouse click). git-svn-id: https://radegast.googlecode.com/svn/trunk@946 f7a694da-4d33-11de-9ad6-1127a62b9fcd --- diff --git a/Radegast/GUI/Rendering/Rendering.cs b/Radegast/GUI/Rendering/Rendering.cs index 78d7801..99a81d3 100644 --- a/Radegast/GUI/Rendering/Rendering.cs +++ b/Radegast/GUI/Rendering/Rendering.cs @@ -109,6 +109,7 @@ namespace Radegast.Rendering double lastFrameTime = 0d; double advTimerTick = 0d; float minLODFactor = 0.005f; + float timeToFocus = 0.3f; float[] lightPos = new float[] { 128f, 128f, 5000f, 0f }; float ambient = 0.26f; @@ -624,6 +625,7 @@ namespace Radegast.Rendering } else if (ModifierKeys == Keys.Alt) { + Camera.TimeToTarget = timeToFocus; Camera.FocalPoint = PrimPos(picked.Prim); Cursor.Position = glControl.PointToScreen(new Point(glControl.Width / 2, glControl.Height / 2)); } @@ -633,6 +635,7 @@ namespace Radegast.Rendering RenderAvatar av = (RenderAvatar)clicked; if (ModifierKeys == Keys.Alt) { + Camera.TimeToTarget = timeToFocus; Vector3 pos = PrimPos(av.avatar); pos.Z += 1.5f; // focus roughly on the chest area Camera.FocalPoint = pos; @@ -826,6 +829,7 @@ namespace Radegast.Rendering Camera.FocalPoint = Client.Self.SimPosition + new Vector3(5, 0, 0) * Client.Self.Movement.BodyRotation; Camera.Zoom = 1.0f; Camera.Far = 128.0f; + Camera.EndMove(); } Vector3 PrimPos(Primitive prim) @@ -1651,8 +1655,8 @@ namespace Radegast.Rendering } var mLookAt = OpenTK.Matrix4d.LookAt( - Camera.Position.X, Camera.Position.Y, Camera.Position.Z, - Camera.FocalPoint.X, Camera.FocalPoint.Y, Camera.FocalPoint.Z, + Camera.RenderPosition.X, Camera.RenderPosition.Y, Camera.RenderPosition.Z, + Camera.RenderFocalPoint.X, Camera.RenderFocalPoint.Y, Camera.RenderFocalPoint.Z, 0d, 0d, 1d); GL.MultMatrix(ref mLookAt); @@ -1671,6 +1675,11 @@ namespace Radegast.Rendering Camera.Modified = false; } + if (Camera.TimeToTarget != 0) + { + Camera.Step(lastFrameTime); + } + if (picking) { RenderObjects(RenderPass.Picking); diff --git a/Radegast/GUI/Rendering/RenderingHelpers.cs b/Radegast/GUI/Rendering/RenderingHelpers.cs index c3f95c4..10b24c0 100644 --- a/Radegast/GUI/Rendering/RenderingHelpers.cs +++ b/Radegast/GUI/Rendering/RenderingHelpers.cs @@ -92,22 +92,77 @@ namespace Radegast.Rendering /// /// Represents camera object /// - public struct Camera + public class Camera { Vector3 mPosition; Vector3 mFocalPoint; bool mModified; /// Camera position - public Vector3 Position { get { return mPosition; } set { mPosition = value; mModified = true; } } + public Vector3 Position { get { return mPosition; } set { mPosition = value; Modify(); } } /// Camera target - public Vector3 FocalPoint { get { return mFocalPoint; } set { mFocalPoint = value; mModified = true; } } + public Vector3 FocalPoint { get { return mFocalPoint; } set { mFocalPoint = value; Modify(); } } /// Zoom level public float Zoom; /// Draw distance public float Far; /// Has camera been modified public bool Modified { get { return mModified; } set { mModified = value; } } + + public double TimeToTarget = 0d; + + public Vector3 RenderPosition; + public Vector3 RenderFocalPoint; + + void Modify() + { + mModified = true; + if (TimeToTarget <= 0) + { + RenderPosition = Position; + RenderFocalPoint = FocalPoint; + } + } + + public void Step(double time) + { + TimeToTarget -= time; + if (TimeToTarget <= time) + { + EndMove(); + return; + } + + mModified = true; + + float pctElapsed = (float)(time / TimeToTarget); + + if (RenderPosition != Position) + { + float distance = Vector3.Distance(RenderPosition, Position); + RenderPosition = Vector3.Lerp(RenderPosition, Position, (float)(distance * pctElapsed)); + } + + if (RenderFocalPoint != FocalPoint) + { + RenderFocalPoint = Interpolate(RenderFocalPoint, FocalPoint, pctElapsed); + } + } + + Vector3 Interpolate(Vector3 start, Vector3 end, float fraction) + { + float distance = Vector3.Distance(start, end); + Vector3 direction = end - start; + return start + direction * fraction; + } + + public void EndMove() + { + mModified = true; + TimeToTarget = 0; + RenderPosition = Position; + RenderFocalPoint = FocalPoint; + } } public static class MeshToOBJ