/// <summary> /// Internal method, if this keyframe is using source property, this /// saves it's value to given instance before it's affected /// </summary> /// <param name="instance"></param> public void SavePropertyValue(AnimationInstance instance) { if (!String.IsNullOrEmpty(d_sourceProperty)) { instance.SavePropertyValue(d_sourceProperty); } }
/// <summary> /// Applies this Animation definition using information from given AnimationInstance /// <para>This is internal method, only use if you know what you're doing!</para> /// </summary> /// <param name="instance"></param> public void Apply(AnimationInstance instance) { foreach (var it in _affectors) { it.Apply(instance); } }
/// <summary> /// Internal method, causes all properties that are used by this animation /// and it's affectors to be saved /// </summary> /// <param name="instance"> /// So their values are still known after they've been affected. /// </param> public void SavePropertyValues(AnimationInstance instance) { foreach (var it in _affectors) { it.SavePropertyValues(instance); } }
/*! * \brief * Retrieves value of this for use when animating * * \par * This is an internal method! Only use if you know what you're doing! * * \par * This returns the base property value if source property is set on this * keyframe, it works the same as getValue() if source property is empty */ public string GetValueForAnimation(AnimationInstance instance) { if (!String.IsNullOrEmpty(d_sourceProperty)) { return(instance.GetSavedPropertyValue(d_sourceProperty)); } return(d_value); }
/// <summary> /// Subscribes all auto subscriptions with information from given animation instance /// <para> /// This is internal method! Only use if you know what you're doing! /// </para> /// </summary> /// <param name="instance"></param> public void AutoSubscribe(AnimationInstance instance) { var eventSender = instance.GetEventSender(); if (eventSender == null) { return; } foreach (var it in _autoSubscriptions.SelectMany(x => x.Value.Select(z => new Tuple <string, string>(x.Key, z)))) { var e = it.Item1; var a = it.Item2; BoundSlot connection; if (a == "Start") { connection = ((IEventSet)eventSender).SubscribeEvent(e, instance.HandleStart); // connection = eventSender->subscribeEvent(e, // CEGUI::Event::Subscriber(&AnimationInstance::handleStart, instance)); } // else if (a == "Stop") // { // connection = eventSender->subscribeEvent(e, // CEGUI::Event::Subscriber(&AnimationInstance::handleStop, instance)); // } // else if (a == "Pause") // { // connection = eventSender->subscribeEvent(e, // CEGUI::Event::Subscriber(&AnimationInstance::handlePause, instance)); // } // else if (a == "Unpause") // { // connection = eventSender->subscribeEvent(e, // CEGUI::Event::Subscriber(&AnimationInstance::handleUnpause, instance)); // } // else if (a == "TogglePause") // { // connection = eventSender->subscribeEvent(e, // CEGUI::Event::Subscriber(&AnimationInstance::handleTogglePause, instance)); // } // else // { // CEGUI_THROW(InvalidRequestException( // "Unable to auto subscribe! " // "'" + a + "' is not a valid action.")); // } //instance.AddAutoConnection(connection); } }
/// <summary> /// Instantiates given animation /// </summary> /// <param name="animation"></param> /// <returns></returns> /// <seealso cref="AnimationInstance"/> public AnimationInstance InstantiateAnimation(Animation animation) { if (animation == null) { throw new InvalidRequestException( "I refuse to instantiate NULL animation, please provide a valid pointer."); } var ret = new AnimationInstance(animation); d_animationInstances.Add(animation, ret); return(ret); }
/// <summary> /// Internal method, causes all properties that are used by this affector /// and it's keyframes to be saved /// </summary> /// <param name="instance"> /// So their values are still known after they've been affected. /// </param> public void SavePropertyValues(AnimationInstance instance) { switch (_applicationMethod) { case ApplicationMethod.Relative: case ApplicationMethod.RelativeMultiply: instance.SavePropertyValue(_targetProperty); break; } // now let all keyframes save their desired property values too foreach (var it in _keyFrames) { it.Value.SavePropertyValue(instance); } }
/// <summary> /// Unsubscribes all auto subscriptions with information from given animation instance /// <para> /// This is internal method! Only use if you know what you're doing! /// </para> /// </summary> /// <param name="instance"></param> public void AutoUnsubscribe(AnimationInstance instance) { // just a delegate to make things clean instance.UnsubscribeAutoConnections(); }
/// <summary> /// Applies this Affector's definition with parameters from given Animation Instance /// <para>This function is internal so unless you know what you're doing, don't touch!</para> /// </summary> /// <param name="instance"></param> /// <seealso cref="AnimationInstance"/> public void Apply(AnimationInstance instance) { var target = instance.GetTarget(); var position = instance.GetPosition(); // special case if (_keyFrames.Count == 0) { return; } if (String.IsNullOrEmpty(_targetProperty)) { System.GetSingleton().Logger.LogEvent("Affector can't be applied when target property is empty!", LoggingLevel.Warnings); return; } if (_interpolator == null) { System.GetSingleton().Logger.LogEvent("Affector can't be applied when no interpolator is set!", LoggingLevel.Warnings); return; } KeyFrame left = null; KeyFrame right = null; // find 2 neighbouring keyframes foreach (var it in _keyFrames) { var current = it.Value; if (current.GetPosition() <= position) { left = current; } if (current.GetPosition() >= position && right == null) { right = current; } } float leftDistance, rightDistance; if (left != null) { leftDistance = position - left.GetPosition(); } else { // if no keyframe is suitable for left neighbour, pick the first one left = _keyFrames.First().Value; leftDistance = 0; } if (right != null) { rightDistance = right.GetPosition() - position; } else { // if no keyframe is suitable for the right neighbour, pick the last one right = _keyFrames.Last().Value; rightDistance = 0; } // if there is just one keyframe and we are right on it if (leftDistance + rightDistance == 0f) { leftDistance = rightDistance = 0.5f; } // alter interpolation position using the right neighbours progression method var interpolationPosition = right.AlterInterpolationPosition(leftDistance / (leftDistance + rightDistance)); // absolute application method if (_applicationMethod == ApplicationMethod.Absolute) { var result = _interpolator.InterpolateAbsolute(left.GetValueForAnimation(instance), right.GetValueForAnimation(instance), interpolationPosition); target.SetProperty(_targetProperty, result); } // relative application method else if (_applicationMethod == ApplicationMethod.Relative) { var @base = instance.GetSavedPropertyValue(GetTargetProperty()); var result = _interpolator.InterpolateRelative(@base, left.GetValueForAnimation(instance), right.GetValueForAnimation(instance), interpolationPosition); target.SetProperty(_targetProperty, result); } // relative multiply application method else if (_applicationMethod == ApplicationMethod.RelativeMultiply) { var @base = instance.GetSavedPropertyValue(GetTargetProperty()); var result = _interpolator.InterpolateRelativeMultiply(@base, left.GetValueForAnimation(instance), right.GetValueForAnimation(instance), interpolationPosition); target.SetProperty(_targetProperty, result); } else { // todo: more application methods? global::System.Diagnostics.Debug.Assert(false); } }
/// <summary> /// Destroys given animation instance /// </summary> /// <param name="instance"></param> public void DestroyAnimationInstance(AnimationInstance instance) { throw new NotImplementedException(); }