Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AnimationClipEvaluator.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using SiliconStudio.Core.Collections;
6 using SiliconStudio.Core.Mathematics;
7 
8 namespace SiliconStudio.Paradox.DataModel
9 {
10  /// <summary>
11  /// Evaluates <see cref="AnimationClip"/> to a <see cref="AnimationClipResult"/> at a given time.
12  /// </summary>
13  public sealed class AnimationClipEvaluator
14  {
15  private AnimationClip clip;
16  internal List<AnimationBlender.Channel> BlenderChannels;
17 
21 
22  private AnimationCurveEvaluatorOptimizedFloatGroup curveEvaluatorOptimizedFloat;
23  private AnimationCurveEvaluatorOptimizedVector3Group curveEvaluatorOptimizedVector3;
24  private AnimationCurveEvaluatorOptimizedQuaternionGroup curveEvaluatorOptimizedQuaternion;
25 
26  // Temporarily exposed for MeshAnimationUpdater
27  internal FastListStruct<EvaluatorChannel> Channels = new FastListStruct<EvaluatorChannel>(4);
28 
29  public AnimationClip Clip
30  {
31  get { return clip; }
32  }
33 
34  internal AnimationClipEvaluator()
35  {
36 
37  }
38 
39  internal void Initialize(AnimationClip clip, List<AnimationBlender.Channel> channels)
40  {
41  this.BlenderChannels = channels;
42  this.clip = clip;
43  clip.Freeze();
44 
45  // If there are optimized curve data, instantiate appropriate evaluators
46  if (clip.OptimizedCurvesFloat != null)
47  {
48  if (curveEvaluatorOptimizedFloat == null)
49  curveEvaluatorOptimizedFloat = new AnimationCurveEvaluatorOptimizedFloatGroup();
50  curveEvaluatorOptimizedFloat.Initialize(clip.OptimizedCurvesFloat);
51  }
52 
53  if (clip.OptimizedCurvesVector3 != null)
54  {
55  if (curveEvaluatorOptimizedVector3 == null)
56  curveEvaluatorOptimizedVector3 = new AnimationCurveEvaluatorOptimizedVector3Group();
57  curveEvaluatorOptimizedVector3.Initialize(clip.OptimizedCurvesVector3);
58  }
59 
60  if (clip.OptimizedCurvesQuaternion != null)
61  {
62  if (curveEvaluatorOptimizedQuaternion == null)
63  curveEvaluatorOptimizedQuaternion = new AnimationCurveEvaluatorOptimizedQuaternionGroup();
64  curveEvaluatorOptimizedQuaternion.Initialize(clip.OptimizedCurvesQuaternion);
65  }
66 
67  // Add already existing channels
68  for (int index = 0; index < channels.Count; index++)
69  {
70  var channel = channels[index];
71  AddChannel(ref channel);
72  }
73  }
74 
75  internal void Cleanup()
76  {
77  if (curveEvaluatorOptimizedVector3 != null)
78  curveEvaluatorOptimizedVector3.Cleanup();
79  if (curveEvaluatorOptimizedQuaternion != null)
80  curveEvaluatorOptimizedQuaternion.Cleanup();
81 
82  Channels.Clear();
83  BlenderChannels = null;
84  clip = null;
85  }
86 
87  public unsafe void Compute(CompressedTimeSpan newTime, AnimationClipResult result)
88  {
89  fixed (byte* structures = result.Data)
90  {
91  // Update factors
92  for (int index = 0; index < Channels.Count; index++)
93  {
94  // For now, objects are not supported, so treat everything as a blittable struct.
95  var channel = Channels.Items[index];
96 
97  var structureStart = (float*)(structures + channel.Offset);
98 
99  // Write a float specifying channel factor (1 if exists, 0 if doesn't exist)
100  *structureStart = channel.Factor;
101  }
102 
103  if (curveEvaluatorOptimizedVector3 != null)
104  {
105  curveEvaluatorOptimizedVector3.Evaluate(newTime, (IntPtr)structures);
106  }
107 
108  if (curveEvaluatorOptimizedQuaternion != null)
109  {
110  curveEvaluatorOptimizedQuaternion.Evaluate(newTime, (IntPtr)structures);
111  }
112 
113  // Write interpolated data
114  curveEvaluatorFloat.Evaluate(newTime, (IntPtr)structures);
115  curveEvaluatorVector3.Evaluate(newTime, (IntPtr)structures);
116  curveEvaluatorQuaternion.Evaluate(newTime, (IntPtr)structures);
117  }
118  }
119 
120  public unsafe void AddCurveValues(CompressedTimeSpan newTime, AnimationClipResult result)
121  {
122  fixed (byte* structures = result.Data)
123  {
124  for (int index = 0; index < Channels.Count; index++)
125  {
126  var channel = Channels.Items[index];
127 
128  // For now, objects are not supported, so treat everything as a blittable struct.
129  channel.Curve.AddValue(newTime, (IntPtr)(structures + channel.Offset));
130  }
131  }
132  }
133 
134  internal void AddChannel(ref AnimationBlender.Channel channel)
135  {
136  AnimationClip.Channel clipChannel;
137  AnimationCurve curve = null;
138 
139  // Try to find curve and create evaluator
140  // (if curve doesn't exist, Evaluator will be null).
141  bool itemFound = clip.Channels.TryGetValue(channel.PropertyName, out clipChannel);
142 
143  if (itemFound)
144  {
145  if (clipChannel.CurveIndex != -1)
146  {
147  curve = clip.Curves[clipChannel.CurveIndex];
148  if (clipChannel.ElementType == typeof(Vector3))
149  curveEvaluatorVector3.AddChannel(curve, channel.Offset + sizeof(float));
150  else if (clipChannel.ElementType == typeof(Quaternion))
151  curveEvaluatorQuaternion.AddChannel(curve, channel.Offset + sizeof(float));
152  else
153  throw new NotImplementedException("Can't create evaluator with this type of curve channel.");
154  }
155  else
156  {
157  if (clipChannel.ElementType == typeof(Vector3))
158  curveEvaluatorOptimizedVector3.AddChannel(channel.PropertyName, channel.Offset + sizeof(float));
159  else if (clipChannel.ElementType == typeof(Quaternion))
160  curveEvaluatorOptimizedQuaternion.AddChannel(channel.PropertyName, channel.Offset + sizeof(float));
161  }
162  }
163 
164  Channels.Add(new EvaluatorChannel { Offset = channel.Offset, Curve = curve, Factor = itemFound ? 1.0f : 0.0f });
165  }
166 
167  internal struct EvaluatorChannel
168  {
169  public int Offset;
170  public AnimationCurve Curve;
171  public float Factor;
172  }
173  }
174 }
Represents a three dimensional mathematical vector.
Definition: Vector3.cs:42
An aggregation of AnimationCurve with their channel names.
Represents a four dimensional mathematical quaternion.
Definition: Quaternion.cs:45
unsafe void Compute(CompressedTimeSpan newTime, AnimationClipResult result)
unsafe void AddCurveValues(CompressedTimeSpan newTime, AnimationClipResult result)
Untyped base class for animation curves.
Performs animation blending. For now, all AnimationClip must target the same skeleton.
Evaluates AnimationClip to a AnimationClipResult at a given time.