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
}\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
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
{\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
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
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
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
{\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
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
{\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
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.AttachedStateKnown = true;\r
}\r
\r
- obj.Step(lastFrameTime);\r
SortedObjects.Add(obj);\r
}\r
}\r
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
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
/// </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
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
/// </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
/// <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
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
\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