OSDN Git Service

Use notion of Interpolated position and rotation instead of sim position and location.
authorLatif Khalifa <latifer@streamgrid.net>
Thu, 21 Jul 2011 16:22:23 +0000 (16:22 +0000)
committerLatif Khalifa <latifer@streamgrid.net>
Thu, 21 Jul 2011 16:22:23 +0000 (16:22 +0000)
All interpolation is done only on local positions and rotations.

git-svn-id: https://radegast.googlecode.com/svn/trunk@997 f7a694da-4d33-11de-9ad6-1127a62b9fcd

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

index 4d43145..8c9d8a0 100644 (file)
@@ -357,7 +357,7 @@ namespace Radegast.Rendering
                 if (av.avatar.ID == e.AvatarID)\r
                 {\r
                     foreach (Animation anim in e.Animations)\r
-                    {          \r
+                    {\r
                         if (av.glavatar.skel.addplayinganimation(anim))\r
                         {\r
                             Logger.Log("Requesting new animation asset " + anim.AnimationID.ToString(), Helpers.LogLevel.Info);\r
@@ -734,7 +734,7 @@ namespace Radegast.Rendering
                             }\r
                             else if (ModifierKeys == Keys.Alt)\r
                             {\r
-                                Camera.FocalPoint = picked.SimPosition;\r
+                                Camera.FocalPoint = picked.RenderPosition;\r
                                 Cursor.Position = glControl.PointToScreen(new Point(glControl.Width / 2, glControl.Height / 2));\r
                             }\r
                         }\r
@@ -743,7 +743,7 @@ namespace Radegast.Rendering
                             RenderAvatar av = (RenderAvatar)clicked;\r
                             if (ModifierKeys == Keys.Alt)\r
                             {\r
-                                Vector3 pos = av.SimPosition;\r
+                                Vector3 pos = av.RenderPosition;\r
                                 pos.Z += 1.5f; // focus roughly on the chest area\r
                                 Camera.FocalPoint = pos;\r
                                 Cursor.Position = glControl.PointToScreen(new Point(glControl.Width / 2, glControl.Height / 2));\r
@@ -977,7 +977,7 @@ namespace Radegast.Rendering
         {\r
             Vector3 pos;\r
             Quaternion rot;\r
-            PrimPosAndRot(prim, out pos, out rot);\r
+            PrimPosAndRot(GetSceneObject(prim.LocalID), out pos, out rot);\r
             return pos;\r
         }\r
 \r
@@ -1009,12 +1009,19 @@ namespace Radegast.Rendering
             return null;\r
         }\r
 \r
-        void PrimPosAndRot(Primitive prim, out Vector3 pos, out Quaternion rot)\r
+        void PrimPosAndRot(SceneObject prim, out Vector3 pos, out Quaternion rot)\r
         {\r
-            if (prim.ParentID == 0)\r
+            if (prim == null)\r
+            {\r
+                pos = RHelp.InvalidPosition;\r
+                rot = Quaternion.Identity;\r
+                return;\r
+            }\r
+\r
+            if (prim.BasePrim.ParentID == 0)\r
             {\r
-                pos = prim.Position;\r
-                rot = prim.Rotation;\r
+                pos = prim.InterpolatedPosition;\r
+                rot = prim.InterpolatedRotation;\r
                 return;\r
             }\r
             else\r
@@ -1022,47 +1029,29 @@ namespace Radegast.Rendering
                 pos = RHelp.InvalidPosition;\r
                 rot = Quaternion.Identity;\r
 \r
-                SceneObject p = GetSceneObject(prim.ParentID);\r
+                SceneObject p = GetSceneObject(prim.BasePrim.ParentID);\r
                 if (p == null) return;\r
 \r
-                Vector3 parentPos;\r
-                Quaternion parentRot;\r
-                if (p.PositionCalculated)\r
+                if (!p.PositionCalculated)\r
                 {\r
-                    parentPos = p.SimPosition;\r
-                    parentRot = p.SimRotation;\r
-                }\r
-                else\r
-                {\r
-                    Primitive parentPrim = p.BasePrim;\r
-                    PrimPosAndRot(parentPrim, out parentPos, out parentRot);\r
-                    p.SimPosition = parentPos;\r
-                    p.SimRotation = parentRot;\r
-                    p.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, p.SimPosition);\r
+                    PrimPosAndRot(p, out p.RenderPosition, out p.RenderRotation);\r
+                    p.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, p.RenderPosition);\r
                     p.PositionCalculated = true;\r
                 }\r
 \r
-                if (p is RenderPrimitive && ((RenderPrimitive)p).Attached)\r
-                {\r
-                    parentPos = p.SimPosition;\r
-                    parentRot = p.SimRotation;\r
-                }\r
-                else\r
-                {\r
-                    parentPos = p.RenderPosition;\r
-                    parentRot = p.RenderRotation;\r
-                }\r
+                Vector3 parentPos = p.RenderPosition;\r
+                Quaternion parentRot = p.RenderRotation;\r
 \r
                 if (p is RenderPrimitive)\r
                 {\r
-                    pos = parentPos + prim.Position * parentRot;\r
-                    rot = parentRot * prim.Rotation;\r
+                    pos = parentPos + prim.InterpolatedPosition * parentRot;\r
+                    rot = parentRot * prim.InterpolatedRotation;\r
                 }\r
                 else if (p is RenderAvatar)\r
                 {\r
                     RenderAvatar parentav = (RenderAvatar)p;\r
 \r
-                    int attachment_index = (int)prim.PrimData.AttachmentPoint;\r
+                    int attachment_index = (int)prim.BasePrim.PrimData.AttachmentPoint;\r
                     // Check for invalid LL attachment point\r
                     if (attachment_index > GLAvatar.attachment_points.Count()) return;\r
 \r
@@ -1070,8 +1059,8 @@ namespace Radegast.Rendering
                     Vector3 point = parentav.glavatar.skel.getOffset(apoint.joint) + apoint.position;\r
                     Quaternion qrot = parentav.glavatar.skel.getRotation(apoint.joint) * apoint.rotation;\r
 \r
-                    pos = parentPos + point * parentRot + prim.Position * (parentRot * qrot);\r
-                    rot = qrot * parentRot * prim.Rotation;\r
+                    pos = parentPos + point * parentRot + prim.InterpolatedPosition * (parentRot * qrot);\r
+                    rot = qrot * parentRot * prim.InterpolatedRotation;\r
                 }\r
                 return;\r
             }\r
@@ -1212,8 +1201,6 @@ namespace Radegast.Rendering
         {\r
             lock (Avatars)\r
             {\r
-                if (Vector3.Distance(PrimPos(av), Client.Self.SimPosition) > DrawDistance) return;\r
-\r
                 if (Avatars.ContainsKey(av.LocalID))\r
                 {\r
                     // flag we got an update??\r
@@ -2030,20 +2017,20 @@ namespace Radegast.Rendering
                 foreach (RenderPrimitive obj in Prims.Values)\r
                 {\r
                     if (obj.BasePrim.ParentID != 0) continue;\r
+                    if (!obj.Initialized) obj.Initialize();\r
+                    obj.Step(lastFrameTime);\r
 \r
                     if (!obj.PositionCalculated)\r
                     {\r
-                        PrimPosAndRot(obj.BasePrim, out obj.SimPosition, out obj.SimRotation);\r
-                        obj.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, obj.SimPosition);\r
+                        PrimPosAndRot(obj, out obj.RenderPosition, out obj.RenderRotation);\r
+                        obj.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, obj.RenderPosition);\r
                         obj.PositionCalculated = true;\r
                     }\r
 \r
-                    if (!obj.Initialized) obj.Initialize();\r
                     if (!Frustum.ObjectInFrustum(obj.RenderPosition, obj.BoundingVolume, obj.BasePrim.Scale)) continue;\r
                     if (LODFactor(obj.DistanceSquared, obj.BasePrim.Scale, obj.BoundingVolume.R) < minLODFactor) continue;\r
 \r
                     obj.Attached = false;\r
-                    obj.Step(lastFrameTime);\r
                     SortedObjects.Add(obj);\r
                 }\r
 \r
@@ -2052,15 +2039,15 @@ namespace Radegast.Rendering
                 {\r
                     foreach (RenderAvatar obj in Avatars.Values)\r
                     {\r
-                        PrimPosAndRot(obj.BasePrim, out obj.SimPosition, out obj.SimRotation);\r
-                        obj.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, obj.SimPosition);\r
-                        obj.PositionCalculated = true;\r
                         if (!obj.Initialized) obj.Initialize();\r
+                        obj.Step(lastFrameTime);\r
+                        PrimPosAndRot(obj, out obj.RenderPosition, out obj.RenderRotation);\r
+                        obj.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, obj.RenderPosition);\r
+                        obj.PositionCalculated = true;\r
 \r
                         if (!Frustum.ObjectInFrustum(obj.RenderPosition, obj.BoundingVolume, obj.BasePrim.Scale)) continue;\r
                         if (LODFactor(obj.DistanceSquared, obj.BasePrim.Scale, obj.BoundingVolume.R) < minLODFactor) continue;\r
 \r
-                        obj.Step(lastFrameTime);\r
                         VisibleAvatars.Add(obj);\r
                         // SortedObjects.Add(obj);\r
                     }\r
@@ -2070,15 +2057,16 @@ namespace Radegast.Rendering
                 foreach (RenderPrimitive obj in Prims.Values)\r
                 {\r
                     if (obj.BasePrim.ParentID == 0) continue;\r
+                    if (!obj.Initialized) obj.Initialize();\r
+                    obj.Step(lastFrameTime);\r
 \r
                     if (!obj.PositionCalculated)\r
                     {\r
-                        PrimPosAndRot(obj.BasePrim, out obj.SimPosition, out obj.SimRotation);\r
-                        obj.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, obj.SimPosition);\r
+                        PrimPosAndRot(obj, out obj.RenderPosition, out obj.RenderRotation);\r
+                        obj.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, obj.RenderPosition);\r
                         obj.PositionCalculated = true;\r
                     }\r
 \r
-                    if (!obj.Initialized) obj.Initialize();\r
                     if (!Frustum.ObjectInFrustum(obj.RenderPosition, obj.BoundingVolume, obj.BasePrim.Scale)) continue;\r
                     if (LODFactor(obj.DistanceSquared, obj.BasePrim.Scale, obj.BoundingVolume.R) < minLODFactor) continue;\r
 \r
@@ -2088,7 +2076,6 @@ namespace Radegast.Rendering
                         obj.AttachedStateKnown = true;\r
                     }\r
 \r
-                    obj.Step(lastFrameTime);\r
                     SortedObjects.Add(obj);\r
                 }\r
             }\r
@@ -2110,7 +2097,7 @@ namespace Radegast.Rendering
             RenderAvatar me;\r
             if (Avatars.TryGetValue(Client.Self.LocalID, out me))\r
             {\r
-                myPos = me.SimPosition;\r
+                myPos = me.RenderPosition;\r
             }\r
             else\r
             {\r
@@ -2130,7 +2117,7 @@ namespace Radegast.Rendering
                 if (obj is RenderPrimitive)\r
                 {\r
                     // Don't render objects that are outside the draw distane\r
-                    if (Vector3.DistanceSquared(myPos, obj.SimPosition) > drawDistanceSquared) continue;\r
+                    if (Vector3.DistanceSquared(myPos, obj.RenderPosition) > drawDistanceSquared) continue;\r
 \r
                     RenderPrim((RenderPrimitive)obj, pass, ix);\r
                 }\r
index f4f8eee..1ccf59b 100644 (file)
@@ -294,10 +294,11 @@ namespace Radegast.Rendering
     /// </summary>\r
     public abstract class SceneObject : IComparable, IDisposable\r
     {\r
-        /// <summary>Actual position of the object in the region</summary>\r
-        public Vector3 SimPosition;\r
-        /// <summary>Actual rotation of the object in the region</summary>\r
-        public Quaternion SimRotation;\r
+        #region Public fields\r
+        /// <summary>Interpolated local position of the object</summary>\r
+        public Vector3 InterpolatedPosition;\r
+        /// <summary>Interpolated local rotation of the object/summary>\r
+        public Quaternion InterpolatedRotation;\r
         /// <summary>Rendered position of the object in the region</summary>\r
         public Vector3 RenderPosition;\r
         /// <summary>Rendered rotationm of the object in the region</summary>\r
@@ -314,6 +315,7 @@ namespace Radegast.Rendering
         public virtual Primitive BasePrim { get; set; }\r
         /// <summary>Were initial initialization tasks done</summary>\r
         public bool Initialized;\r
+        #endregion Public fields\r
 \r
         /// <summary>\r
         /// Cleanup resources used\r
@@ -327,12 +329,9 @@ namespace Radegast.Rendering
         /// </summary>\r
         public virtual void Initialize()\r
         {\r
-            RenderPosition = SimPosition;\r
-            RenderRotation = SimRotation;\r
-            if (SimPosition != RHelp.InvalidPosition)\r
-            {\r
-                Initialized = true;\r
-            }\r
+            RenderPosition = InterpolatedPosition = BasePrim.Position;\r
+            RenderRotation = InterpolatedRotation = BasePrim.Rotation;\r
+            Initialized = true;\r
         }\r
 \r
         /// <summary>\r
@@ -341,6 +340,31 @@ namespace Radegast.Rendering
         /// <param name="time">Time since the last call (last frame time in seconds)</param>\r
         public virtual void Step(float time)\r
         {\r
+            // Linear velocity and acceleration\r
+            if (BasePrim.Velocity != Vector3.Zero)\r
+            {\r
+                InterpolatedPosition += BasePrim.Velocity * 0.98f * time;\r
+                BasePrim.Velocity += BasePrim.Acceleration * time;\r
+            }\r
+            else if (InterpolatedPosition != BasePrim.Position)\r
+            {\r
+                InterpolatedPosition = RHelp.Smoothed1stOrder(InterpolatedPosition, BasePrim.Position, time);\r
+            }\r
+\r
+            // Angular velocity (target omega)\r
+            if (BasePrim.AngularVelocity != Vector3.Zero)\r
+            {\r
+                Vector3 angVel = BasePrim.AngularVelocity;\r
+                float angle = time * angVel.Length();\r
+                Quaternion dQ = Quaternion.CreateFromAxisAngle(angVel, angle);\r
+                InterpolatedRotation = dQ * InterpolatedRotation;\r
+            }\r
+            else if (InterpolatedRotation != BasePrim.Rotation)\r
+            {\r
+                InterpolatedRotation = Quaternion.Slerp(InterpolatedRotation, BasePrim.Rotation, time * 10f);\r
+                if (Math.Abs(1f - Quaternion.Dot(InterpolatedRotation, BasePrim.Rotation)) < 0.0001)\r
+                    InterpolatedRotation = BasePrim.Rotation;\r
+            }\r
         }\r
 \r
         /// <summary>\r
@@ -387,35 +411,6 @@ namespace Radegast.Rendering
             base.Initialize();\r
         }\r
 \r
-        public override void Step(float time)\r
-        {\r
-            // Don't interpolate positions of attached objects\r
-            if (Attached)\r
-            {\r
-                RenderPosition = SimPosition;\r
-                RenderRotation = SimRotation;\r
-                return;\r
-            }\r
-\r
-            if (RenderPosition != SimPosition)\r
-            {\r
-                RenderPosition = RHelp.Smoothed1stOrder(RenderPosition, SimPosition, time);\r
-            }\r
-            if (Prim.AngularVelocity != Vector3.Zero)\r
-            {\r
-                Vector3 angVel = Prim.AngularVelocity;\r
-                float angle = time * angVel.Length();\r
-                Quaternion dQ = Quaternion.CreateFromAxisAngle(angVel, angle);\r
-                RenderRotation = dQ * RenderRotation;\r
-            }\r
-            else if (RenderRotation != SimRotation)\r
-            {\r
-                RenderRotation = Quaternion.Slerp(RenderRotation, SimRotation, time * 10f);\r
-                if (Math.Abs(1f - Quaternion.Dot(RenderRotation, SimRotation)) < 0.0001)\r
-                    RenderRotation = SimRotation;\r
-            }\r
-        }\r
-\r
         public override string ToString()\r
         {\r
             uint id = Prim == null ? 0 : Prim.LocalID;\r
@@ -1665,11 +1660,6 @@ namespace Radegast.Rendering
 \r
         public override void Step(float time)\r
         {\r
-            if (RenderPosition != SimPosition)\r
-            {\r
-                RenderPosition = RHelp.Smoothed1stOrder(RenderPosition, SimPosition, time);\r
-            }\r
-            RenderRotation = SimRotation;\r
             base.Step(time);\r
         }\r
 \r