OSDN Git Service

Implement smooth camera focus when picking (alt+mouse click).
authorLatif Khalifa <latifer@streamgrid.net>
Mon, 4 Jul 2011 10:47:00 +0000 (10:47 +0000)
committerLatif Khalifa <latifer@streamgrid.net>
Mon, 4 Jul 2011 10:47:00 +0000 (10:47 +0000)
git-svn-id: https://radegast.googlecode.com/svn/trunk@946 f7a694da-4d33-11de-9ad6-1127a62b9fcd

Radegast/GUI/Rendering/Rendering.cs
Radegast/GUI/Rendering/RenderingHelpers.cs

index 78d7801..99a81d3 100644 (file)
@@ -109,6 +109,7 @@ namespace Radegast.Rendering
         double lastFrameTime = 0d;\r
         double advTimerTick = 0d;\r
         float minLODFactor = 0.005f;\r
+        float timeToFocus = 0.3f;\r
 \r
         float[] lightPos = new float[] { 128f, 128f, 5000f, 0f };\r
         float ambient = 0.26f;\r
@@ -624,6 +625,7 @@ namespace Radegast.Rendering
                             }\r
                             else if (ModifierKeys == Keys.Alt)\r
                             {\r
+                                Camera.TimeToTarget = timeToFocus;\r
                                 Camera.FocalPoint = PrimPos(picked.Prim);\r
                                 Cursor.Position = glControl.PointToScreen(new Point(glControl.Width / 2, glControl.Height / 2));\r
                             }\r
@@ -633,6 +635,7 @@ namespace Radegast.Rendering
                             RenderAvatar av = (RenderAvatar)clicked;\r
                             if (ModifierKeys == Keys.Alt)\r
                             {\r
+                                Camera.TimeToTarget = timeToFocus;\r
                                 Vector3 pos = PrimPos(av.avatar);\r
                                 pos.Z += 1.5f; // focus roughly on the chest area\r
                                 Camera.FocalPoint = pos;\r
@@ -826,6 +829,7 @@ namespace Radegast.Rendering
             Camera.FocalPoint = Client.Self.SimPosition + new Vector3(5, 0, 0) * Client.Self.Movement.BodyRotation;\r
             Camera.Zoom = 1.0f;\r
             Camera.Far = 128.0f;\r
+            Camera.EndMove();\r
         }\r
 \r
         Vector3 PrimPos(Primitive prim)\r
@@ -1651,8 +1655,8 @@ namespace Radegast.Rendering
             }\r
 \r
             var mLookAt = OpenTK.Matrix4d.LookAt(\r
-                    Camera.Position.X, Camera.Position.Y, Camera.Position.Z,\r
-                    Camera.FocalPoint.X, Camera.FocalPoint.Y, Camera.FocalPoint.Z,\r
+                    Camera.RenderPosition.X, Camera.RenderPosition.Y, Camera.RenderPosition.Z,\r
+                    Camera.RenderFocalPoint.X, Camera.RenderFocalPoint.Y, Camera.RenderFocalPoint.Z,\r
                     0d, 0d, 1d);\r
             GL.MultMatrix(ref mLookAt);\r
 \r
@@ -1671,6 +1675,11 @@ namespace Radegast.Rendering
                 Camera.Modified = false;\r
             }\r
 \r
+            if (Camera.TimeToTarget != 0)\r
+            {\r
+                Camera.Step(lastFrameTime);\r
+            }\r
+\r
             if (picking)\r
             {\r
                 RenderObjects(RenderPass.Picking);\r
index c3f95c4..10b24c0 100644 (file)
@@ -92,22 +92,77 @@ namespace Radegast.Rendering
     /// <summary>\r
     /// Represents camera object\r
     /// </summary>\r
-    public struct Camera\r
+    public class Camera\r
     {\r
         Vector3 mPosition;\r
         Vector3 mFocalPoint;\r
         bool mModified;\r
         \r
         /// <summary>Camera position</summary>\r
-        public Vector3 Position { get { return mPosition; } set { mPosition = value; mModified = true; } }\r
+        public Vector3 Position { get { return mPosition; } set { mPosition = value; Modify(); } }\r
         /// <summary>Camera target</summary>\r
-        public Vector3 FocalPoint { get { return mFocalPoint; } set { mFocalPoint = value; mModified = true; } }\r
+        public Vector3 FocalPoint { get { return mFocalPoint; } set { mFocalPoint = value; Modify(); } }\r
         /// <summary>Zoom level</summary>\r
         public float Zoom;\r
         /// <summary>Draw distance</summary>\r
         public float Far;\r
         /// <summary>Has camera been modified</summary>\r
         public bool Modified { get { return mModified; } set { mModified = value; } }\r
+\r
+        public double TimeToTarget = 0d;\r
+\r
+        public Vector3 RenderPosition;\r
+        public Vector3 RenderFocalPoint;\r
+\r
+        void Modify()\r
+        {\r
+            mModified = true;\r
+            if (TimeToTarget <= 0)\r
+            {\r
+                RenderPosition = Position;\r
+                RenderFocalPoint = FocalPoint;\r
+            }\r
+        }\r
+\r
+        public void Step(double time)\r
+        {\r
+            TimeToTarget -= time;\r
+            if (TimeToTarget <= time)\r
+            {\r
+                EndMove();\r
+                return;\r
+            }\r
+\r
+            mModified = true;\r
+\r
+            float pctElapsed = (float)(time / TimeToTarget);\r
+\r
+            if (RenderPosition != Position)\r
+            {\r
+                float distance = Vector3.Distance(RenderPosition, Position);\r
+                RenderPosition = Vector3.Lerp(RenderPosition, Position, (float)(distance * pctElapsed));\r
+            }\r
+\r
+            if (RenderFocalPoint != FocalPoint)\r
+            {\r
+                RenderFocalPoint = Interpolate(RenderFocalPoint, FocalPoint, pctElapsed);\r
+            }\r
+        }\r
+\r
+        Vector3 Interpolate(Vector3 start, Vector3 end, float fraction)\r
+        {\r
+            float distance = Vector3.Distance(start, end);\r
+            Vector3 direction = end - start;\r
+            return start + direction * fraction;\r
+        }\r
+\r
+        public void EndMove()\r
+        {\r
+            mModified = true;\r
+            TimeToTarget = 0;\r
+            RenderPosition = Position;\r
+            RenderFocalPoint = FocalPoint;\r
+        }\r
     }\r
 \r
     public static class MeshToOBJ\r