|
@@ -27,6 +27,7 @@ namespace BansheeEngine
|
|
|
private List<SceneObjectMappingInfo> mappingInfo = new List<SceneObjectMappingInfo>();
|
|
private List<SceneObjectMappingInfo> mappingInfo = new List<SceneObjectMappingInfo>();
|
|
|
private AnimationClip primaryClip;
|
|
private AnimationClip primaryClip;
|
|
|
private Renderable animatedRenderable;
|
|
private Renderable animatedRenderable;
|
|
|
|
|
+ private State state = State.Inactive;
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Contains mapping for a suffix used by property paths used for curve identifiers, to their index and type.
|
|
/// Contains mapping for a suffix used by property paths used for curve identifiers, to their index and type.
|
|
@@ -65,8 +66,15 @@ namespace BansheeEngine
|
|
|
{
|
|
{
|
|
|
serializableData.defaultClip = value;
|
|
serializableData.defaultClip = value;
|
|
|
|
|
|
|
|
- if (value != null && _native != null)
|
|
|
|
|
- _native.Play(value);
|
|
|
|
|
|
|
+ if (value != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.Play(value);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -82,8 +90,12 @@ namespace BansheeEngine
|
|
|
{
|
|
{
|
|
|
serializableData.wrapMode = value;
|
|
serializableData.wrapMode = value;
|
|
|
|
|
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.WrapMode = value;
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.WrapMode = value;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -97,8 +109,12 @@ namespace BansheeEngine
|
|
|
{
|
|
{
|
|
|
serializableData.speed = value;
|
|
serializableData.speed = value;
|
|
|
|
|
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.Speed = value;
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.Speed = value;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -109,10 +125,13 @@ namespace BansheeEngine
|
|
|
{
|
|
{
|
|
|
get
|
|
get
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- return _native.IsPlaying();
|
|
|
|
|
-
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ return _native.IsPlaying();
|
|
|
|
|
+ default:
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -132,19 +151,21 @@ namespace BansheeEngine
|
|
|
if (animatedRenderable != null && animatedRenderable.Native != null)
|
|
if (animatedRenderable != null && animatedRenderable.Native != null)
|
|
|
animatedRenderable.Native.OverrideBounds = value;
|
|
animatedRenderable.Native.OverrideBounds = value;
|
|
|
|
|
|
|
|
- if (_native != null)
|
|
|
|
|
- {
|
|
|
|
|
- AABox bounds = serializableData.bounds;
|
|
|
|
|
|
|
+ AABox bounds = serializableData.bounds;
|
|
|
|
|
|
|
|
- Matrix4 parentTfrm;
|
|
|
|
|
- if (SceneObject.Parent != null)
|
|
|
|
|
- parentTfrm = SceneObject.Parent.WorldTransform;
|
|
|
|
|
- else
|
|
|
|
|
- parentTfrm = Matrix4.Identity;
|
|
|
|
|
|
|
+ Matrix4 parentTfrm;
|
|
|
|
|
+ if (SceneObject.Parent != null)
|
|
|
|
|
+ parentTfrm = SceneObject.Parent.WorldTransform;
|
|
|
|
|
+ else
|
|
|
|
|
+ parentTfrm = Matrix4.Identity;
|
|
|
|
|
|
|
|
- bounds.TransformAffine(parentTfrm);
|
|
|
|
|
|
|
+ bounds.TransformAffine(parentTfrm);
|
|
|
|
|
|
|
|
- _native.Bounds = bounds;
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.Bounds = bounds;
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -175,8 +196,12 @@ namespace BansheeEngine
|
|
|
{
|
|
{
|
|
|
serializableData.cull = value;
|
|
serializableData.cull = value;
|
|
|
|
|
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.Cull = value;
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.Cull = value;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -186,8 +211,12 @@ namespace BansheeEngine
|
|
|
/// <param name="clip">Clip to play.</param>
|
|
/// <param name="clip">Clip to play.</param>
|
|
|
public void Play(AnimationClip clip)
|
|
public void Play(AnimationClip clip)
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.Play(clip);
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.Play(clip);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -204,8 +233,12 @@ namespace BansheeEngine
|
|
|
/// and each layer has its own weight.</param>
|
|
/// and each layer has its own weight.</param>
|
|
|
public void BlendAdditive(AnimationClip clip, float weight, float fadeLength, int layer)
|
|
public void BlendAdditive(AnimationClip clip, float weight, float fadeLength, int layer)
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.BlendAdditive(clip, weight, fadeLength, layer);
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.BlendAdditive(clip, weight, fadeLength, layer);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -219,8 +252,12 @@ namespace BansheeEngine
|
|
|
/// influence, t = 1 means right animation has full influence.</param>
|
|
/// influence, t = 1 means right animation has full influence.</param>
|
|
|
public void Blend1D(Blend1DInfo info, float t)
|
|
public void Blend1D(Blend1DInfo info, float t)
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.Blend1D(info, t);
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.Blend1D(info, t);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -236,8 +273,12 @@ namespace BansheeEngine
|
|
|
/// </param>
|
|
/// </param>
|
|
|
public void Blend2D(Blend2DInfo info, Vector2 t)
|
|
public void Blend2D(Blend2DInfo info, Vector2 t)
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.Blend2D(info, t);
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.Blend2D(info, t);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -247,8 +288,12 @@ namespace BansheeEngine
|
|
|
/// <param name="fadeLength">Determines the time period over which the fade occurs. In seconds.</param>
|
|
/// <param name="fadeLength">Determines the time period over which the fade occurs. In seconds.</param>
|
|
|
public void CrossFade(AnimationClip clip, float fadeLength)
|
|
public void CrossFade(AnimationClip clip, float fadeLength)
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.CrossFade(clip, fadeLength);
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.CrossFade(clip, fadeLength);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -257,8 +302,12 @@ namespace BansheeEngine
|
|
|
/// <param name="layer">Layer on which to stop animations on.</param>
|
|
/// <param name="layer">Layer on which to stop animations on.</param>
|
|
|
public void Stop(int layer)
|
|
public void Stop(int layer)
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.Stop(layer);
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.Stop(layer);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -266,8 +315,12 @@ namespace BansheeEngine
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
public void StopAll()
|
|
public void StopAll()
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.StopAll();
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ _native.StopAll();
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -279,11 +332,135 @@ namespace BansheeEngine
|
|
|
/// <returns>True if the state was found (animation clip is playing), false otherwise.</returns>
|
|
/// <returns>True if the state was found (animation clip is playing), false otherwise.</returns>
|
|
|
public bool GetState(AnimationClip clip, out AnimationClipState state)
|
|
public bool GetState(AnimationClip clip, out AnimationClipState state)
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- return _native.GetState(clip, out state);
|
|
|
|
|
|
|
+ switch (this.state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ return _native.GetState(clip, out state);
|
|
|
|
|
+ default:
|
|
|
|
|
+ state = new AnimationClipState();
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- state = new AnimationClipState();
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Changes the state of a playing animation clip. If animation clip is not currently playing the state change is
|
|
|
|
|
+ /// ignored.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="clip">Clip to change the state for.</param>
|
|
|
|
|
+ /// <param name="state">New state of the animation (e.g. changing the time for seeking).</param>
|
|
|
|
|
+ public void SetState(AnimationClip clip, AnimationClipState state)
|
|
|
|
|
+ {
|
|
|
|
|
+ switch (this.state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ _native.SetState(clip, state);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Allows the caller to play an animation clip during edit mode. This form of animation playback is limited as
|
|
|
|
|
+ /// you have no control over clip properties, and features like blending, cross fade or animation events are not
|
|
|
|
|
+ /// supported.
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// Caller will need to manually call <see cref="UpdateFloatProperties"/> in order to apply evaluated animation data
|
|
|
|
|
+ /// to relevant float properties (if required).
|
|
|
|
|
+ ///
|
|
|
|
|
+ /// Caller will also need to manually call <see cref="RefreshClipMappings"/> whenever the curves internal to the
|
|
|
|
|
+ /// animation clip change. This should be called before the call to <see cref="UpdateFloatProperties"/>.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="clip">Animation clip to play.</param>
|
|
|
|
|
+ /// <param name="startTime">Time to start playing at, in seconds.</param>
|
|
|
|
|
+ /// <param name="freeze">If true, only the frame at the specified time will be shown, without advancing the
|
|
|
|
|
+ /// animation.</param>
|
|
|
|
|
+ internal void EditorPlay(AnimationClip clip, float startTime, bool freeze = false)
|
|
|
|
|
+ {
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Inactive:
|
|
|
|
|
+ SwitchState(State.EditorActive);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ AnimationClipState clipState = AnimationClipState.Create();
|
|
|
|
|
+ clipState.time = startTime;
|
|
|
|
|
+ clipState.speed = freeze ? 0.0f : 1.0f;
|
|
|
|
|
+
|
|
|
|
|
+ SetState(clip, clipState);
|
|
|
|
|
+ RefreshClipMappings();
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Stops playback of animation whose playback what started using <see cref="EditorPlay"/>.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ internal void EditorStop()
|
|
|
|
|
+ {
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ SwitchState(State.Inactive);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Returns the current time of the currently playing editor animation clip.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <returns>Time in seconds.</returns>
|
|
|
|
|
+ internal float EditorGetTime()
|
|
|
|
|
+ {
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ AnimationClip clip = _native.GetClip(0);
|
|
|
|
|
+
|
|
|
|
|
+ AnimationClipState clipState;
|
|
|
|
|
+ if (clip != null && GetState(clip, out clipState))
|
|
|
|
|
+ return clipState.time;
|
|
|
|
|
+
|
|
|
|
|
+ return 0.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 0.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Rebuilds internal curve -> property mapping about the currently playing animation clip. This mapping allows the
|
|
|
|
|
+ /// animation component to know which property to assign which values from an animation curve. This Should be called
|
|
|
|
|
+ /// whenever playback for a new clip starts, or when clip curves change.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ internal void RefreshClipMappings()
|
|
|
|
|
+ {
|
|
|
|
|
+ primaryClip = _native.GetClip(0);
|
|
|
|
|
+
|
|
|
|
|
+ RebuildFloatProperties(primaryClip);
|
|
|
|
|
+ UpdateSceneObjectMapping();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Updates generic float properties on relevant objects, based on the most recently evaluated animation curve
|
|
|
|
|
+ /// values.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ internal void UpdateFloatProperties()
|
|
|
|
|
+ {
|
|
|
|
|
+ // Apply values from generic float curves
|
|
|
|
|
+ if (floatProperties != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ foreach (var entry in floatProperties)
|
|
|
|
|
+ {
|
|
|
|
|
+ float curveValue;
|
|
|
|
|
+ if (_native.GetGenericCurveValue(entry.curveIdx, out curveValue))
|
|
|
|
|
+ entry.setter(curveValue);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -409,7 +586,7 @@ namespace BansheeEngine
|
|
|
SerializableProperty.FieldType.Vector3,
|
|
SerializableProperty.FieldType.Vector3,
|
|
|
typeof(Vector3),
|
|
typeof(Vector3),
|
|
|
() => so.LocalPosition,
|
|
() => so.LocalPosition,
|
|
|
- (x) => so.LocalPosition = (Vector3) x);
|
|
|
|
|
|
|
+ (x) => so.LocalPosition = (Vector3)x);
|
|
|
|
|
|
|
|
return property;
|
|
return property;
|
|
|
}
|
|
}
|
|
@@ -419,7 +596,7 @@ namespace BansheeEngine
|
|
|
SerializableProperty.FieldType.Vector3,
|
|
SerializableProperty.FieldType.Vector3,
|
|
|
typeof(Vector3),
|
|
typeof(Vector3),
|
|
|
() => so.LocalRotation.ToEuler(),
|
|
() => so.LocalRotation.ToEuler(),
|
|
|
- (x) => so.LocalRotation = Quaternion.FromEuler((Vector3) x));
|
|
|
|
|
|
|
+ (x) => so.LocalRotation = Quaternion.FromEuler((Vector3)x));
|
|
|
|
|
|
|
|
return property;
|
|
return property;
|
|
|
}
|
|
}
|
|
@@ -429,7 +606,7 @@ namespace BansheeEngine
|
|
|
SerializableProperty.FieldType.Vector3,
|
|
SerializableProperty.FieldType.Vector3,
|
|
|
typeof(Vector3),
|
|
typeof(Vector3),
|
|
|
() => so.LocalScale,
|
|
() => so.LocalScale,
|
|
|
- (x) => so.LocalScale = (Vector3) x);
|
|
|
|
|
|
|
+ (x) => so.LocalScale = (Vector3)x);
|
|
|
|
|
|
|
|
return property;
|
|
return property;
|
|
|
}
|
|
}
|
|
@@ -481,124 +658,138 @@ namespace BansheeEngine
|
|
|
return so;
|
|
return so;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /// <summary>
|
|
|
|
|
- /// Changes the state of a playing animation clip. If animation clip is not currently playing the state change is
|
|
|
|
|
- /// ignored.
|
|
|
|
|
- /// </summary>
|
|
|
|
|
- /// <param name="clip">Clip to change the state for.</param>
|
|
|
|
|
- /// <param name="state">New state of the animation (e.g. changing the time for seeking).</param>
|
|
|
|
|
- public void SetState(AnimationClip clip, AnimationClipState state)
|
|
|
|
|
|
|
+ private void OnInitialize()
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.SetState(clip, state);
|
|
|
|
|
|
|
+ NotifyFlags = TransformChangedFlags.Transform;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void OnUpdate()
|
|
|
|
|
|
|
+ private void OnEnable()
|
|
|
{
|
|
{
|
|
|
- if (_native == null)
|
|
|
|
|
- return;
|
|
|
|
|
-
|
|
|
|
|
- AnimationClip newPrimaryClip = _native.GetClip(0);
|
|
|
|
|
- if (newPrimaryClip != primaryClip)
|
|
|
|
|
|
|
+ switch (state)
|
|
|
{
|
|
{
|
|
|
- RebuildFloatProperties(newPrimaryClip);
|
|
|
|
|
- primaryClip = newPrimaryClip;
|
|
|
|
|
-
|
|
|
|
|
- UpdateSceneObjectMapping();
|
|
|
|
|
|
|
+ case State.Inactive:
|
|
|
|
|
+ SwitchState(State.Active);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ SwitchState(State.Inactive);
|
|
|
|
|
+ SwitchState(State.Active);
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // Apply values from generic float curves
|
|
|
|
|
- if (floatProperties != null)
|
|
|
|
|
|
|
+ private void OnDisable()
|
|
|
|
|
+ {
|
|
|
|
|
+ switch (state)
|
|
|
{
|
|
{
|
|
|
- foreach (var entry in floatProperties)
|
|
|
|
|
- {
|
|
|
|
|
- float curveValue;
|
|
|
|
|
- if (_native.GetGenericCurveValue(entry.curveIdx, out curveValue))
|
|
|
|
|
- entry.setter(curveValue);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ SwitchState(State.Inactive);
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void OnInitialize()
|
|
|
|
|
|
|
+ private void OnDestroy()
|
|
|
{
|
|
{
|
|
|
- NotifyFlags = TransformChangedFlags.Transform;
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ SwitchState(State.Inactive);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void OnEnable()
|
|
|
|
|
|
|
+ private void OnUpdate()
|
|
|
{
|
|
{
|
|
|
- RestoreNative();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ AnimationClip newPrimaryClip = _native.GetClip(0);
|
|
|
|
|
+ if (newPrimaryClip != primaryClip)
|
|
|
|
|
+ RefreshClipMappings();
|
|
|
|
|
|
|
|
- private void OnDisable()
|
|
|
|
|
- {
|
|
|
|
|
- DestroyNative();
|
|
|
|
|
|
|
+ UpdateFloatProperties();
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void OnDestroy()
|
|
|
|
|
|
|
+ private void OnTransformChanged(TransformChangedFlags flags)
|
|
|
{
|
|
{
|
|
|
- DestroyNative();
|
|
|
|
|
|
|
+ if (!SceneObject.Active)
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
|
|
+ if ((flags & (TransformChangedFlags.Transform)) != 0)
|
|
|
|
|
+ UpdateBounds(false);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
- /// Creates the internal representation of the animation and restores the values saved by the component.
|
|
|
|
|
|
|
+ /// Changes the state of the animation state machine. Doesn't check for valid transitions.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
- private void RestoreNative()
|
|
|
|
|
|
|
+ /// <param name="state">New state of the animation.</param>
|
|
|
|
|
+ private void SwitchState(State state)
|
|
|
{
|
|
{
|
|
|
- if (_native != null)
|
|
|
|
|
- _native.Destroy();
|
|
|
|
|
|
|
+ this.state = state;
|
|
|
|
|
|
|
|
- _native = new NativeAnimation();
|
|
|
|
|
- _native.OnEventTriggered += EventTriggered;
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ if (_native != null)
|
|
|
|
|
+ _native.Destroy();
|
|
|
|
|
|
|
|
- animatedRenderable = SceneObject.GetComponent<Renderable>();
|
|
|
|
|
|
|
+ _native = new NativeAnimation();
|
|
|
|
|
+ _native.OnEventTriggered += EventTriggered;
|
|
|
|
|
|
|
|
- // Restore saved values after reset
|
|
|
|
|
- _native.WrapMode = serializableData.wrapMode;
|
|
|
|
|
- _native.Speed = serializableData.speed;
|
|
|
|
|
- _native.Cull = serializableData.cull;
|
|
|
|
|
|
|
+ animatedRenderable = SceneObject.GetComponent<Renderable>();
|
|
|
|
|
|
|
|
- UpdateBounds();
|
|
|
|
|
|
|
+ // Restore saved values after reset
|
|
|
|
|
+ _native.WrapMode = serializableData.wrapMode;
|
|
|
|
|
+ _native.Speed = serializableData.speed;
|
|
|
|
|
+ _native.Cull = serializableData.cull;
|
|
|
|
|
|
|
|
- if (serializableData.defaultClip != null)
|
|
|
|
|
- _native.Play(serializableData.defaultClip);
|
|
|
|
|
|
|
+ UpdateBounds();
|
|
|
|
|
|
|
|
- primaryClip = _native.GetClip(0);
|
|
|
|
|
- if (primaryClip != null)
|
|
|
|
|
- RebuildFloatProperties(primaryClip);
|
|
|
|
|
|
|
+ if (serializableData.defaultClip != null)
|
|
|
|
|
+ _native.Play(serializableData.defaultClip);
|
|
|
|
|
|
|
|
- SetBoneMappings();
|
|
|
|
|
- UpdateSceneObjectMapping();
|
|
|
|
|
|
|
+ primaryClip = _native.GetClip(0);
|
|
|
|
|
+ if (primaryClip != null)
|
|
|
|
|
+ RebuildFloatProperties(primaryClip);
|
|
|
|
|
|
|
|
- if(animatedRenderable != null)
|
|
|
|
|
- animatedRenderable.RegisterAnimation(this);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ SetBoneMappings();
|
|
|
|
|
+ UpdateSceneObjectMapping();
|
|
|
|
|
|
|
|
- /// <summary>
|
|
|
|
|
- /// Destroys the internal animation representation.
|
|
|
|
|
- /// </summary>
|
|
|
|
|
- private void DestroyNative()
|
|
|
|
|
- {
|
|
|
|
|
- if (animatedRenderable != null)
|
|
|
|
|
- animatedRenderable.UnregisterAnimation();
|
|
|
|
|
|
|
+ if (animatedRenderable != null)
|
|
|
|
|
+ animatedRenderable.RegisterAnimation(this);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case State.EditorActive:
|
|
|
|
|
+ if (_native != null)
|
|
|
|
|
+ _native.Destroy();
|
|
|
|
|
|
|
|
- if (_native != null)
|
|
|
|
|
- {
|
|
|
|
|
- _native.Destroy();
|
|
|
|
|
- _native = null;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ _native = new NativeAnimation();
|
|
|
|
|
|
|
|
- primaryClip = null;
|
|
|
|
|
- mappingInfo.Clear();
|
|
|
|
|
- floatProperties = null;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ animatedRenderable = SceneObject.GetComponent<Renderable>();
|
|
|
|
|
|
|
|
- private void OnTransformChanged(TransformChangedFlags flags)
|
|
|
|
|
- {
|
|
|
|
|
- if (!SceneObject.Active)
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ UpdateBounds();
|
|
|
|
|
+ SetBoneMappings();
|
|
|
|
|
|
|
|
- if ((flags & (TransformChangedFlags.Transform)) != 0)
|
|
|
|
|
- UpdateBounds(false);
|
|
|
|
|
|
|
+ if (animatedRenderable != null)
|
|
|
|
|
+ animatedRenderable.RegisterAnimation(this);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case State.Inactive:
|
|
|
|
|
+ if (animatedRenderable != null)
|
|
|
|
|
+ animatedRenderable.UnregisterAnimation();
|
|
|
|
|
+
|
|
|
|
|
+ if (_native != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ _native.Destroy();
|
|
|
|
|
+ _native = null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ primaryClip = null;
|
|
|
|
|
+ mappingInfo.Clear();
|
|
|
|
|
+ floatProperties = null;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -668,18 +859,20 @@ namespace BansheeEngine
|
|
|
/// <param name="bone">Bone component to register.</param>
|
|
/// <param name="bone">Bone component to register.</param>
|
|
|
internal void AddBone(Bone bone)
|
|
internal void AddBone(Bone bone)
|
|
|
{
|
|
{
|
|
|
- if (_native == null)
|
|
|
|
|
- return;
|
|
|
|
|
-
|
|
|
|
|
- SceneObject currentSO = bone.SceneObject;
|
|
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ SceneObject currentSO = bone.SceneObject;
|
|
|
|
|
|
|
|
- SceneObjectMappingInfo newMapping = new SceneObjectMappingInfo();
|
|
|
|
|
- newMapping.sceneObject = currentSO;
|
|
|
|
|
- newMapping.isMappedToBone = true;
|
|
|
|
|
- newMapping.bone = bone;
|
|
|
|
|
|
|
+ SceneObjectMappingInfo newMapping = new SceneObjectMappingInfo();
|
|
|
|
|
+ newMapping.sceneObject = currentSO;
|
|
|
|
|
+ newMapping.isMappedToBone = true;
|
|
|
|
|
+ newMapping.bone = bone;
|
|
|
|
|
|
|
|
- mappingInfo.Add(newMapping);
|
|
|
|
|
- _native.MapCurveToSceneObject(bone.Name, newMapping.sceneObject);
|
|
|
|
|
|
|
+ mappingInfo.Add(newMapping);
|
|
|
|
|
+ _native.MapCurveToSceneObject(bone.Name, newMapping.sceneObject);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -688,17 +881,19 @@ namespace BansheeEngine
|
|
|
/// <param name="bone">Bone to unregister.</param>
|
|
/// <param name="bone">Bone to unregister.</param>
|
|
|
internal void RemoveBone(Bone bone)
|
|
internal void RemoveBone(Bone bone)
|
|
|
{
|
|
{
|
|
|
- if (_native == null)
|
|
|
|
|
- return;
|
|
|
|
|
-
|
|
|
|
|
- for (int i = 0; i < mappingInfo.Count; i++)
|
|
|
|
|
|
|
+ switch (state)
|
|
|
{
|
|
{
|
|
|
- if (mappingInfo[i].bone == bone)
|
|
|
|
|
- {
|
|
|
|
|
- _native.UnmapSceneObject(mappingInfo[i].sceneObject);
|
|
|
|
|
- mappingInfo.RemoveAt(i);
|
|
|
|
|
- i--;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ for (int i = 0; i < mappingInfo.Count; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (mappingInfo[i].bone == bone)
|
|
|
|
|
+ {
|
|
|
|
|
+ _native.UnmapSceneObject(mappingInfo[i].sceneObject);
|
|
|
|
|
+ mappingInfo.RemoveAt(i);
|
|
|
|
|
+ i--;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -708,17 +903,19 @@ namespace BansheeEngine
|
|
|
/// <param name="bone">Bone component to modify.</param>
|
|
/// <param name="bone">Bone component to modify.</param>
|
|
|
internal void NotifyBoneChanged(Bone bone)
|
|
internal void NotifyBoneChanged(Bone bone)
|
|
|
{
|
|
{
|
|
|
- if (_native == null)
|
|
|
|
|
- return;
|
|
|
|
|
-
|
|
|
|
|
- for (int i = 0; i < mappingInfo.Count; i++)
|
|
|
|
|
|
|
+ switch (state)
|
|
|
{
|
|
{
|
|
|
- if (mappingInfo[i].bone == bone)
|
|
|
|
|
- {
|
|
|
|
|
- _native.UnmapSceneObject(mappingInfo[i].sceneObject);
|
|
|
|
|
- _native.MapCurveToSceneObject(bone.Name, mappingInfo[i].sceneObject);
|
|
|
|
|
|
|
+ case State.Active:
|
|
|
|
|
+ for (int i = 0; i < mappingInfo.Count; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (mappingInfo[i].bone == bone)
|
|
|
|
|
+ {
|
|
|
|
|
+ _native.UnmapSceneObject(mappingInfo[i].sceneObject);
|
|
|
|
|
+ _native.MapCurveToSceneObject(bone.Name, mappingInfo[i].sceneObject);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
break;
|
|
break;
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -776,7 +973,6 @@ namespace BansheeEngine
|
|
|
return bones.ToArray();
|
|
return bones.ToArray();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Re-applies the bounds to the internal animation object, and the relevant renderable object if one exists.
|
|
/// Re-applies the bounds to the internal animation object, and the relevant renderable object if one exists.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -1044,6 +1240,25 @@ namespace BansheeEngine
|
|
|
public bool isMappedToBone;
|
|
public bool isMappedToBone;
|
|
|
public Bone bone;
|
|
public Bone bone;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Possible states the animation component can be in.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ private enum State
|
|
|
|
|
+ {
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Animation object isn't constructed.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ Inactive,
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Animation object is constructed and fully functional.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ Active,
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// Animation object is constructed and functional with limited funcionality for editor purposes.
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ EditorActive
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1130,13 +1345,17 @@ namespace BansheeEngine
|
|
|
public AnimWrapMode wrapMode;
|
|
public AnimWrapMode wrapMode;
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
- /// Initializes the state with default values.
|
|
|
|
|
|
|
+ /// Creates a new clip state, with default values initialized.
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
- public void InitDefault()
|
|
|
|
|
|
|
+ /// <returns>New animation clip state.</returns>
|
|
|
|
|
+ public static AnimationClipState Create()
|
|
|
{
|
|
{
|
|
|
- speed = 1.0f;
|
|
|
|
|
- weight = 1.0f;
|
|
|
|
|
- wrapMode = AnimWrapMode.Loop;
|
|
|
|
|
|
|
+ AnimationClipState state = new AnimationClipState();
|
|
|
|
|
+ state.speed = 1.0f;
|
|
|
|
|
+ state.weight = 1.0f;
|
|
|
|
|
+ state.wrapMode = AnimWrapMode.Loop;
|
|
|
|
|
+
|
|
|
|
|
+ return state;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|