コード例 #1
0
        public void Bind(IAnimable owner)
        {
            Owner = owner;
            var p = AnimationUtils.GetProperty(owner.GetType(), TargetProperty);

            IsTriggerable = p.Triggerable;
            var mi = p.Info.GetSetMethod();

            if (mi == null)
            {
                throw new Lime.Exception("Property '{0}' (class '{1}') is readonly", TargetProperty, owner.GetType());
            }
            Setter = (SetterDelegate)Delegate.CreateDelegate(typeof(SetterDelegate), owner, mi);
        }
コード例 #2
0
ファイル: AnimationEngine.cs プロジェクト: x5f3759df/Citrus
 protected static Marker FindMarkerAhead(Animation animation, double time)
 {
     if (animation.Markers.Count > 0)
     {
         var frame = AnimationUtils.SecondsToFramesCeiling(time);
         foreach (var marker in animation.Markers)
         {
             if (marker.Frame >= frame)
             {
                 return(marker);
             }
         }
     }
     return(null);
 }
コード例 #3
0
ファイル: AnimationEngine.cs プロジェクト: klenin/Citrus
        public override bool TryRunAnimation(Animation animation, string markerId, double animationTimeCorrection = 0)
        {
            var frame = 0;

            if (markerId != null)
            {
                var marker = animation.Markers.TryFind(markerId);
                if (marker == null)
                {
                    return(false);
                }
                frame = marker.Frame;
            }
            animation.Time            = AnimationUtils.FramesToSeconds(frame) + animationTimeCorrection;
            animation.RunningMarkerId = markerId;
            animation.IsRunning       = true;
            return(true);
        }
コード例 #4
0
ファイル: Model3DAttachment.cs プロジェクト: x5f3759df/Citrus
 private static void CopyKeys(IAnimator srcAnimator, IAnimator dstAnimator, int startFrame, int lastFrame)
 {
     if (!GetEffectiveKeyRange(srcAnimator, startFrame, lastFrame, out var startKeyIndex, out var lastKeyIndex))
     {
         return;
     }
     if (startFrame != srcAnimator.ReadonlyKeys[startKeyIndex].Frame)
     {
         dstAnimator.Keys.Add(startFrame, srcAnimator.CalcValue(AnimationUtils.FramesToSeconds(startFrame)));
     }
     for (var i = startKeyIndex; i <= lastKeyIndex; i++)
     {
         dstAnimator.Keys.Add(srcAnimator.ReadonlyKeys[i]);
     }
     if (startFrame != lastFrame && lastFrame != srcAnimator.ReadonlyKeys[lastKeyIndex].Frame)
     {
         dstAnimator.Keys.Add(lastFrame, srcAnimator.CalcValue(AnimationUtils.FramesToSeconds(lastFrame)));
     }
 }
コード例 #5
0
ファイル: AnimationEngine.cs プロジェクト: x5f3759df/Citrus
        public override bool TryRunAnimation(Animation animation, string markerId, double animationTimeCorrection = 0)
        {
            var frame = 0;

            if (markerId != null)
            {
                var marker = animation.Markers.TryFind(markerId);
                if (marker == null)
                {
                    return(false);
                }
                frame = marker.Frame;
            }
            // Easings may give huge animationTimeCorrection values, clamp it.
            animationTimeCorrection   = Mathf.Clamp(animationTimeCorrection, -AnimationUtils.SecondsPerFrame + AnimationUtils.Threshold, 0);
            animation.Time            = AnimationUtils.FramesToSeconds(frame) + animationTimeCorrection;
            animation.RunningMarkerId = markerId;
            animation.IsRunning       = true;
            return(true);
        }
コード例 #6
0
 public IAnimator this[string propertyPath, string animationId = null]
 {
     get
     {
         IAnimator animator;
         if (TryFind(propertyPath, out animator, animationId))
         {
             return(animator);
         }
         var(p, _, _) = AnimationUtils.GetPropertyByPath(owner, propertyPath);
         var pi = p.Info;
         if (pi == null)
         {
             throw new Lime.Exception("Unknown property {0} in {1}", propertyPath, owner.GetType().Name);
         }
         animator = AnimatorRegistry.Instance.CreateAnimator(pi.PropertyType);
         animator.TargetPropertyPath = propertyPath;
         animator.AnimationId        = animationId;
         Add(animator);
         Version++;
         return(animator);
     }
 }
コード例 #7
0
ファイル: Animator.cs プロジェクト: aologos/Citrus
        private void Bind()
        {
            var(p, animable, index) = AnimationUtils.GetPropertyByPath(Owner, TargetPropertyPath);
            var mi = p.Info?.GetSetMethod();

            IsZombie = animable == null || mi == null || p.Info.PropertyType != typeof(T) || animable is IList list && index >= list.Count;
            if (IsZombie)
            {
                return;
            }
            Animable      = animable;
            IsTriggerable = p.Triggerable;
            if (index == -1)
            {
                setter = (SetterDelegate)Delegate.CreateDelegate(typeof(SetterDelegate), animable, mi);
            }
            else
            {
                var indexedSetter = (IndexedSetterDelegate)Delegate.CreateDelegate(typeof(IndexedSetterDelegate), animable, mi);
                setter = (v) => {
                    indexedSetter(index, v);
                };
            }
        }
コード例 #8
0
        private void CacheInterpolationParameters(double time)
        {
            int count = ReadonlyKeys.Count;

            if (count == 0)
            {
                Value2   = default(T);
                minTime  = -float.MaxValue;
                maxTime  = float.MaxValue;
                function = KeyFunction.Steep;
                return;
            }
            var i = keyIndex;

            if (i >= count)
            {
                i = count - 1;
            }
            int frame = AnimationUtils.SecondsToFrames(time);

            // find rightmost key on the left from the given frame
            while (i < count - 1 && frame > ReadonlyKeys[i].Frame)
            {
                i++;
            }
            while (i >= 0 && frame < ReadonlyKeys[i].Frame)
            {
                i--;
            }
            keyIndex = i;
            int minFrame, maxFrame;

            if (i < 0)
            {
                keyIndex = 0;
                maxFrame = ReadonlyKeys[0].Frame;
                minFrame = int.MinValue;
                Value2   = ReadonlyKeys[0].Value;
                function = KeyFunction.Steep;
            }
            else if (i == count - 1)
            {
                minFrame = ReadonlyKeys[i].Frame;
                maxFrame = int.MaxValue;
                Value2   = ReadonlyKeys[i].Value;
                function = KeyFunction.Steep;
            }
            else
            {
                var key1 = ReadonlyKeys[i];
                var key2 = ReadonlyKeys[i + 1];
                minFrame = key1.Frame;
                maxFrame = key2.Frame;
                Value2   = key1.Value;
                Value3   = key2.Value;
                function = key1.Function;
                if (function == KeyFunction.Spline)
                {
                    Value1 = ReadonlyKeys[i < 1 ? 0 : i - 1].Value;
                    Value4 = ReadonlyKeys[i + 1 >= count - 1 ? count - 1 : i + 2].Value;
                }
                else if (function == KeyFunction.ClosedSpline)
                {
                    Value1 = ReadonlyKeys[i < 1 ? count - 2 : i - 1].Value;
                    Value4 = ReadonlyKeys[i + 1 >= count - 1 ? 1 : i + 2].Value;
                }
            }
            minTime = minFrame * AnimationUtils.SecondsPerFrame;
            maxTime = maxFrame * AnimationUtils.SecondsPerFrame;
        }
コード例 #9
0
        private bool InitializeParticle(Particle p)
        {
            Color4   color;
            Matrix32 transform;

            CalcInitialColorAndTransform(out color, out transform);
            float   emitterScaleAmount = 1;
            Vector2 emitterScale       = new Vector2();

            emitterScale.X = transform.U.Length;
            emitterScale.Y = transform.V.Length;
            float crossProduct = Vector2.CrossProduct(transform.U, transform.V);

            if (crossProduct < 0.0f)
            {
                emitterScale.Y = -emitterScale.Y;
            }
            emitterScaleAmount = Mathf.Sqrt(Math.Abs(crossProduct));
            float        emitterAngle             = transform.U.Atan2Deg;
            NumericRange aspectRatioVariationPair = new NumericRange(0, Math.Max(0.0f, AspectRatio.Dispersion));
            float        zoom        = Zoom.NormalRandomNumber(Rng);
            float        aspectRatio = AspectRatio.Median *
                                       (1 + Math.Abs(aspectRatioVariationPair.NormalRandomNumber(Rng))) /
                                       (1 + Math.Abs(aspectRatioVariationPair.NormalRandomNumber(Rng)));

            p.TextureIndex        = 0.0f;
            p.Velocity            = Velocity.NormalRandomNumber(Rng) * emitterScaleAmount;
            p.ScaleInitial        = emitterScale * ApplyAspectRatio(zoom, aspectRatio);
            p.ScaleCurrent        = p.ScaleInitial;
            p.WindDirection       = WindDirection.UniformRandomNumber(Rng);
            p.WindAmount          = WindAmount.NormalRandomNumber(Rng) * emitterScaleAmount;
            p.GravityVelocity     = 0.0f;
            p.GravityAcceleration = 0.0f;
            p.GravityAmount       = GravityAmount.NormalRandomNumber(Rng) * emitterScaleAmount;
            p.GravityDirection    = GravityDirection.NormalRandomNumber(Rng);
            p.MagnetAmountInitial = MagnetAmount.NormalRandomNumber(Rng);
            p.Lifetime            = Math.Max(Lifetime.NormalRandomNumber(Rng), 0.1f);
            p.Age                 = 0.0f;
            p.AngularVelocity     = AngularVelocity.NormalRandomNumber(Rng);
            p.Angle               = Orientation.UniformRandomNumber(Rng) + emitterAngle;
            p.Spin                = Spin.NormalRandomNumber(Rng);
            p.ColorInitial        = color;
            p.ColorCurrent        = color;
            p.RandomRayDirection  = (new NumericRange(0, 360)).UniformRandomNumber(Rng);
            p.RandomSplineVertex0 = GenerateRandomMotionControlPoint(ref p.RandomRayDirection);
            p.RandomSplineVertex1 = Vector2.Zero;
            p.RandomSplineVertex2 = GenerateRandomMotionControlPoint(ref p.RandomRayDirection);
            p.RandomSplineVertex3 = GenerateRandomMotionControlPoint(ref p.RandomRayDirection);
            p.RandomMotionSpeed   = RandomMotionSpeed.NormalRandomNumber(Rng);
            p.RandomSplineOffset  = 0;
            Vector2 position;

            switch (Shape)
            {
            case EmitterShape.Point:
                position           = 0.5f * Size;
                p.RegularDirection = Direction.UniformRandomNumber(Rng) + emitterAngle - 90.0f;
                break;

            case EmitterShape.Line:
                position           = new Vector2(Rng.RandomFloat() * Size.X, Size.Y * 0.5f);
                p.RegularDirection = Direction.UniformRandomNumber(Rng) + emitterAngle - 90.0f;
                break;

            case EmitterShape.Ellipse:
                float   angle  = Rng.RandomFloat(0, 360);
                Vector2 sincos = Vector2.CosSinRough(angle * Mathf.DegToRad);
                position           = 0.5f * ((sincos + Vector2.One) * Size);
                p.RegularDirection = Direction.UniformRandomNumber(Rng) + emitterAngle - 90 + angle;
                break;

            case EmitterShape.Area:
                position.X         = Rng.RandomFloat() * Size.X;
                position.Y         = Rng.RandomFloat() * Size.Y;
                p.RegularDirection = Direction.UniformRandomNumber(Rng) + emitterAngle - 90.0f;
                break;

            case EmitterShape.Custom:
                position           = GetPointInCustomShape();
                p.RegularDirection = Direction.UniformRandomNumber(Rng) + emitterAngle - 90.0f;
                break;

            default:
                throw new Lime.Exception("Invalid particle emitter shape");
            }
            p.RegularPosition = transform.TransformVector(position);
            if (!TryGetRandomModifier(out p.Modifier))
            {
                return(false);
            }
            var animationDuration = AnimationUtils.FramesToSeconds(p.Modifier.Animators.GetOverallDuration());

            p.AgeToAnimationTime = (float)(animationDuration / p.Lifetime);
            if (EmissionType == EmissionType.Inner)
            {
                p.RegularDirection += 180;
            }
            else if ((EmissionType & EmissionType.Inner) != 0)
            {
                if (Rng.RandomInt(2) == 0)
                {
                    p.RegularDirection += 180;
                }
            }
            else if (EmissionType == 0)
            {
                return(false);
            }
            p.FullDirection = p.RegularDirection;
            p.FullPosition  = p.RegularPosition;
            return(true);
        }
コード例 #10
0
ファイル: Model3DAttachment.cs プロジェクト: klenin/Citrus
 private static int FixFrame(int frame, double fps = 30)
 {
     return(AnimationUtils.SecondsToFrames(frame / fps));
 }
コード例 #11
0
ファイル: AnimationBlender.cs プロジェクト: klenin/Citrus
 public BlendingOption(int frames) : this(AnimationUtils.FramesToSeconds(frames))
 {
 }