Пример #1
0
        private void Recalculate()
        {
            long now = this.CameraMain.Plugin.Time;

            {
                long remove = now - this.MaxHistoryDuration;
                while (this.History.Count != 0)
                {
                    var n = this.History.First;
                    if (n.Value.Time <= remove)
                    {
                        this.History.RemoveFirst();
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (this.History.Count == 0)
            {
                return;
            }

            // Calculate weighted average.
            double totalWeight = 0.0;

            double[] totalPosition = new double[3];
            double   totalOffsetX  = 0.0;
            double   totalOffsetY  = 0.0;

            {
                var n = this.History.Last;
                while (n != null)
                {
                    var cur = n.Value;
                    n = n.Previous;

                    long   diff   = this.MaxHistoryDuration - (now - cur.Time);
                    double ratio  = (double)diff / (double)this.MaxHistoryDuration;
                    double weight = ratio * ratio;
                    totalWeight      += weight;
                    totalPosition[0] += cur.Position[0] * weight;
                    totalPosition[1] += cur.Position[1] * weight;
                    totalPosition[2] += cur.Position[2] * weight;
                    double ofx = cur.OffsetX;
                    double ofy = cur.OffsetY;
                    //this.ApplyIgnoreOffset(ref ofx, ref ofy);
                    totalOffsetX += ofx * weight;
                    totalOffsetY += ofy * weight;
                }
            }

            if (totalWeight <= 0.0)
            {
                return;
            }

            totalPosition[0] /= totalWeight;
            totalPosition[1] /= totalWeight;
            totalPosition[2] /= totalWeight;
            totalOffsetX     /= totalWeight;
            totalOffsetY     /= totalWeight;

            if (this.LastCalculated == null)
            {
                this.LastCalculated             = new CameraStabilizeHistoryEntry();
                this.LastCalculated.Time        = now;
                this.LastCalculated.Position    = new float[3];
                this.LastCalculated.Position[0] = (float)totalPosition[0];
                this.LastCalculated.Position[1] = (float)totalPosition[1];
                this.LastCalculated.Position[2] = (float)totalPosition[2];
                this.LastCalculated.OffsetX     = (float)totalOffsetX;
                this.LastCalculated.OffsetY     = (float)totalOffsetY;
                return;
            }

            bool changed = false;

            {
                double value  = totalPosition[0];
                double old    = this.LastCalculated.Position[0];
                double ignore = this.IgnorePositionX;
                double diff   = value - old;
                if (Math.Abs(diff) > ignore)
                {
                    if (diff >= 0.0)
                    {
                        diff -= ignore;
                    }
                    else
                    {
                        diff += ignore;
                    }
                    this.LastCalculated.Position[0] += (float)diff;
                    changed = true;
                }
            }

            {
                double value  = totalPosition[1];
                double old    = this.LastCalculated.Position[1];
                double ignore = this.IgnorePositionY;
                double diff   = value - old;
                if (Math.Abs(diff) > ignore)
                {
                    if (diff >= 0.0)
                    {
                        diff -= ignore;
                    }
                    else
                    {
                        diff += ignore;
                    }
                    this.LastCalculated.Position[1] += (float)diff;
                    changed = true;
                }
            }

            {
                double value  = totalPosition[2];
                double old    = this.LastCalculated.Position[2];
                double ignore = this.IgnorePositionZ;
                double diff   = value - old;
                if (Math.Abs(diff) > ignore)
                {
                    if (diff >= 0.0)
                    {
                        diff -= ignore;
                    }
                    else
                    {
                        diff += ignore;
                    }
                    this.LastCalculated.Position[2] += (float)diff;
                    changed = true;
                }
            }

            {
                double value  = totalOffsetX;
                double old    = this.LastCalculated.OffsetX;
                double ignore = this.IgnoreRotationX;
                double diff   = value - old;
                if (Math.Abs(diff) > ignore)
                {
                    if (diff >= 0.0)
                    {
                        diff -= ignore;
                    }
                    else
                    {
                        diff += ignore;
                    }
                    this.LastCalculated.OffsetX += (float)diff;
                    changed = true;
                }
            }

            {
                double value  = totalOffsetY;
                double old    = this.LastCalculated.OffsetY;
                double ignore = this.IgnoreRotationY;
                double diff   = value - old;
                if (Math.Abs(diff) > ignore)
                {
                    if (diff >= 0.0)
                    {
                        diff -= ignore;
                    }
                    else
                    {
                        diff += ignore;
                    }
                    this.LastCalculated.OffsetY += (float)diff;
                    changed = true;
                }
            }

            if (changed)
            {
                this.LastCalculated.Time = now;
            }
        }
Пример #2
0
        internal void Update(NiAVObject root, NiAVObject head, CameraUpdate update)
        {
            this.UpdateValues(update);

            var tpos = head.WorldTransform.Position;
            var spos = root.WorldTransform.Position;

            float x = tpos.X - spos.X;
            float y = tpos.Y - spos.Y;
            float z = tpos.Z - spos.Z;

            root.WorldTransform.Rotation.GetEulerAngles(this.TempPoint);
            float angle = this.TempPoint.Z;

            this.TempPoint.X = x;
            this.TempPoint.Y = y;
            this.TempPoint.Z = z;
            float len = this.TempPoint.Length;

            if (len > 0.0f)
            {
                this.TempPoint.Normalize(this.TempPoint);
            }

            tpos   = this.TempTransform.Position;
            tpos.X = 0.0f;
            tpos.Y = 0.0f;
            tpos.Z = 0.0f;

            this.TempTransform.LookAt(this.TempPoint);
            this.TempTransform.Rotation.RotateZ(angle, this.TempTransform.Rotation);

            this.TempPoint.X = 0.0f;
            this.TempPoint.Y = len;
            this.TempPoint.Z = 0.0f;
            this.TempTransform.Translate(this.TempPoint, this.TempPoint);

            x = this.TempPoint.X;
            y = this.TempPoint.Y;
            z = this.TempPoint.Z;

            root.WorldTransform.Rotation.GetEulerAngles(this.TempPoint);
            head.WorldTransform.Rotation.GetEulerAngles(this.TempTransform.Position);

            double ofx = Utility.ClampToPi(this.TempTransform.Position.Z - this.TempPoint.Z);
            double ofy = Utility.ClampToPi(this.TempTransform.Position.X - this.TempPoint.X);

            this.ApplyIgnoreOffset(ref ofx, ref ofy);

            long now = this.CameraMain.Plugin.Time;

            var e = new CameraStabilizeHistoryEntry();

            e.Time     = now;
            e.OffsetX  = (float)ofx;
            e.OffsetY  = (float)ofy;
            e.Position = new float[] { x, y, z };
            this.History.AddLast(e);

            this.NeedRecalculate = true;
        }
        internal void Update(NiAVObject root, NiAVObject head, CameraUpdate update)
        {
            UpdateValues(update);

            var tpos = head.WorldTransform.Position;
            var spos = root.WorldTransform.Position;

            var x = tpos.X - spos.X;
            var y = tpos.Y - spos.Y;
            var z = tpos.Z - spos.Z;

            root.WorldTransform.Rotation.GetEulerAngles(TempPoint);
            var angle = TempPoint.Z;

            TempPoint.X = x;
            TempPoint.Y = y;
            TempPoint.Z = z;
            var len = TempPoint.Length;

            if (len > 0.0f)
            {
                TempPoint.Normalize(TempPoint);
            }

            tpos   = TempTransform.Position;
            tpos.X = 0.0f;
            tpos.Y = 0.0f;
            tpos.Z = 0.0f;

            TempTransform.LookAt(TempPoint);
            TempTransform.Rotation.RotateZ(angle, TempTransform.Rotation);

            TempPoint.X = 0.0f;
            TempPoint.Y = len;
            TempPoint.Z = 0.0f;
            TempTransform.Translate(TempPoint, TempPoint);

            x = TempPoint.X;
            y = TempPoint.Y;
            z = TempPoint.Z;

            root.WorldTransform.Rotation.GetEulerAngles(TempPoint);
            head.WorldTransform.Rotation.GetEulerAngles(TempTransform.Position);

            var ofx = Utility.ClampToPi(TempTransform.Position.Z - TempPoint.Z);
            var ofy = Utility.ClampToPi(TempTransform.Position.X - TempPoint.X);

            ApplyIgnoreOffset(ref ofx, ref ofy);

            var now = CameraMain.Plugin.Time;

            var e = new CameraStabilizeHistoryEntry();

            e.Time     = now;
            e.OffsetX  = (float)ofx;
            e.OffsetY  = (float)ofy;
            e.Position = new[] { x, y, z };
            History.AddLast(e);

            NeedRecalculate = true;
        }