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); }
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); }
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); }
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))); } }
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); }
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); } }
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); }; } }
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; }
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); }
private static int FixFrame(int frame, double fps = 30) { return(AnimationUtils.SecondsToFrames(frame / fps)); }
public BlendingOption(int frames) : this(AnimationUtils.FramesToSeconds(frames)) { }