OpenMetaverse.ObjectManager.InterpolationTimer_Elapsed C# (CSharp) Method

InterpolationTimer_Elapsed() protected method

protected InterpolationTimer_Elapsed ( object obj ) : void
obj object
return void
        protected void InterpolationTimer_Elapsed(object obj)
        {
            int elapsed = 0;

            if (Client.Network.Connected)
            {
                int start = Environment.TickCount;

                int interval = Environment.TickCount - Client.Self.lastInterpolation;
                float seconds = (float)interval / 1000f;

                // Iterate through all of the simulators
                Simulator[] sims = Client.Network.Simulators.ToArray();
                for (int i = 0; i < sims.Length; i++)
                {
                    Simulator sim = sims[i];

                    float adjSeconds = seconds * sim.Stats.Dilation;

                    // Iterate through all of this sims avatars
                    sim.ObjectsAvatars.ForEach(
                        delegate(Avatar avatar)
                        {
                            #region Linear Motion
                            // Only do movement interpolation (extrapolation) when there is a non-zero velocity but
                            // no acceleration
                            if (avatar.Acceleration != Vector3.Zero && avatar.Velocity == Vector3.Zero)
                            {
                                avatar.Position += (avatar.Velocity + avatar.Acceleration *
                                    (0.5f * (adjSeconds - HAVOK_TIMESTEP))) * adjSeconds;
                                avatar.Velocity += avatar.Acceleration * adjSeconds;
                            }
                            #endregion Linear Motion
                        }
                    );

                    // Iterate through all of this sims primitives
                    sim.ObjectsPrimitives.ForEach(
                        delegate(Primitive prim)
                        {
                            if (prim.Joint == JointType.Invalid)
                            {
                                #region Angular Velocity
                                Vector3 angVel = prim.AngularVelocity;
                                float omega = angVel.LengthSquared();

                                if (omega > 0.00001f)
                                {
                                    omega = (float)Math.Sqrt(omega);
                                    float angle = omega * adjSeconds;
                                    angVel *= 1.0f / omega;
                                    Quaternion dQ = Quaternion.CreateFromAxisAngle(angVel, angle);

                                    prim.Rotation *= dQ;
                                }
                                #endregion Angular Velocity

                                #region Linear Motion
                                // Only do movement interpolation (extrapolation) when there is a non-zero velocity but
                                // no acceleration
                                if (prim.Acceleration != Vector3.Zero && prim.Velocity == Vector3.Zero)
                                {
                                    prim.Position += (prim.Velocity + prim.Acceleration *
                                        (0.5f * (adjSeconds - HAVOK_TIMESTEP))) * adjSeconds;
                                    prim.Velocity += prim.Acceleration * adjSeconds;
                                }
                                #endregion Linear Motion
                            }
                            else if (prim.Joint == JointType.Hinge)
                            {
                                //FIXME: Hinge movement extrapolation
                            }
                            else if (prim.Joint == JointType.Point)
                            {
                                //FIXME: Point movement extrapolation
                            }
                            else
                            {
                                Logger.Log("Unhandled joint type " + prim.Joint, Helpers.LogLevel.Warning, Client);
                            }
                        }
                    );
                }

                // Make sure the last interpolated time is always updated
                Client.Self.lastInterpolation = Environment.TickCount;

                elapsed = Client.Self.lastInterpolation - start;
            }

            // Start the timer again. Use a minimum of a 50ms pause in between calculations
            int delay = Math.Max(50, Settings.INTERPOLATION_INTERVAL - elapsed);
            if (InterpolationTimer != null)
            {
                InterpolationTimer.Change(delay, Timeout.Infinite);
            }
        }