return pos;\r
}\r
\r
+ bool IsAttached(uint parentLocalID)\r
+ {\r
+ if (parentLocalID == 0) return false;\r
+ if (Client.Network.CurrentSim.ObjectsAvatars.ContainsKey(parentLocalID))\r
+ {\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ return IsAttached(Client.Network.CurrentSim.ObjectsPrimitives[parentLocalID].ParentID);\r
+ }\r
+ }\r
+\r
SceneObject GetSceneObject(uint localID)\r
{\r
RenderPrimitive parent;\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
+\r
if (p is RenderPrimitive)\r
{\r
pos = parentPos + prim.Position * parentRot;\r
int avatarNr = 0;\r
foreach (RenderAvatar av in Avatars.Values)\r
{\r
+ // Init interpolation state\r
+ if (!av.Initialized) av.Initialize();\r
+\r
avatarNr++;\r
\r
if (av.glavatar._meshes.Count > 0)\r
// Prim roation and position\r
//GL.MultMatrix(Math3D.CreateTranslationMatrix(av.avatar.Position));\r
//GL.MultMatrix(Math3D.CreateRotationMatrix(av.avatar.Rotation));\r
- GL.MultMatrix(Math3D.CreateSRTMatrix(new Vector3(1, 1, 1), av.SimRotation, av.SimPosition));\r
+ GL.MultMatrix(Math3D.CreateSRTMatrix(new Vector3(1, 1, 1), av.RenderRotation, av.RenderPosition));\r
\r
// Special case for eyeballs we need to offset the mesh to the correct position\r
// We have manually added the eyeball offset based on the headbone when we\r
if (!mesh.Initialized) mesh.Initialize();\r
\r
// Do any position interpolation\r
- mesh.Step(lastFrameTime);\r
+ SceneObject parent = GetSceneObject(mesh.Prim.ParentID);\r
+ if (parent != null)\r
+ {\r
+ if (!mesh.AttachedStateKnown)\r
+ {\r
+ mesh.Attached = IsAttached(mesh.BasePrim.ParentID);\r
+ mesh.AttachedStateKnown = true;\r
+ }\r
+ mesh.Step(lastFrameTime);\r
+ }\r
\r
Primitive prim = mesh.Prim;\r
\r
obj.PositionCalculated = false;\r
}\r
\r
+ // First calculate positions and rotations of root objects\r
+ // Perform any position interpolation\r
+ foreach (SceneObject obj in SortedObjects)\r
+ {\r
+ if (obj.BasePrim.ParentID != 0) continue;\r
+\r
+ if (obj is RenderPrimitive)\r
+ {\r
+ ((RenderPrimitive)obj).Attached = false;\r
+ }\r
+ \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
+ obj.PositionCalculated = true;\r
+ }\r
+ }\r
+\r
+ // Calculate position and rotations of child objects\r
foreach (SceneObject obj in SortedObjects)\r
{\r
+ if (obj.BasePrim.ParentID == 0) continue;\r
+\r
if (!obj.PositionCalculated)\r
{\r
PrimPosAndRot(obj.BasePrim, out obj.SimPosition, out obj.SimRotation);\r
if (prim.Textures == null) return;\r
\r
RenderPrimitive rPrim = null;\r
- if (!Prims.TryGetValue(prim.LocalID, out rPrim))\r
+ if (Prims.TryGetValue(prim.LocalID, out rPrim))\r
+ {\r
+ rPrim.AttachedStateKnown = false;\r
+ }\r
+ else\r
{\r
rPrim = new RenderPrimitive();\r
}\r
/// </summary>\r
public virtual void Initialize()\r
{\r
+ RenderPosition = SimPosition;\r
+ RenderRotation = SimRotation;\r
+ Initialized = true;\r
}\r
\r
/// <summary>\r
{\r
public Primitive Prim;\r
public List<Face> Faces;\r
+ /// <summary>Is this object attached to an avatar</summary>\r
+ public bool Attached;\r
+ /// <summary>Do we know if object is attached</summary>\r
+ public bool AttachedStateKnown;\r
\r
public RenderPrimitive()\r
{\r
\r
public override void Initialize()\r
{\r
- RenderPosition = SimPosition;\r
- RenderRotation = SimRotation;\r
- Initialized = true;\r
+ AttachedStateKnown = false;\r
+ base.Initialize();\r
}\r
\r
public override void Step(double 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 (RenderRotation != SimRotation)\r
+ if (Prim.AngularVelocity != Vector3.Zero)\r
+ {\r
+ Vector3 angVel = Prim.AngularVelocity;\r
+ float angle = (float)time * angVel.Length();\r
+ Quaternion dQ = Quaternion.CreateFromAxisAngle(angVel, angle);\r
+ RenderRotation = dQ * RenderRotation;\r
+ }\r
+ else if (RenderRotation != SimRotation)\r
{\r
RenderRotation = SimRotation;\r
}\r
set { if (value is Avatar) avatar = (Avatar)value; }\r
}\r
\r
+ public override void Step(double 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
public GLAvatar glavatar = new GLAvatar();\r
public Avatar avatar;\r
public FaceData[] data = new FaceData[32];\r