140 lines
5.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniGLTF
{
class AnimationCurveData
{
#if UNITY_EDITOR
public AnimationUtility.TangentMode TangentMode { get; private set; }
public glTFAnimationTarget.AnimationProperties AnimationProperty { get; private set; }
public int SamplerIndex { get; private set; }
public int ElementCount { get; private set; }
public readonly List<AnimationKeyframeData> Keyframes = new List<AnimationKeyframeData>();
[Obsolete]
public AnimationCurveData(AnimationUtility.TangentMode tangentMode, glTFAnimationTarget.AnimationPropertys property, int samplerIndex, int elementCount)
: this(tangentMode, glTFAnimationTarget.AnimationPropertysToAnimationProperties(property), samplerIndex, elementCount)
{
}
public AnimationCurveData(AnimationUtility.TangentMode tangentMode, glTFAnimationTarget.AnimationProperties property, int samplerIndex, int elementCount)
{
TangentMode = tangentMode;
AnimationProperty = property;
SamplerIndex = samplerIndex;
ElementCount = elementCount;
}
public string GetInterpolation()
{
switch (TangentMode)
{
case AnimationUtility.TangentMode.Linear:
return glTFAnimationTarget.Interpolations.LINEAR.ToString();
case AnimationUtility.TangentMode.Constant:
return glTFAnimationTarget.Interpolations.STEP.ToString();
default:
return glTFAnimationTarget.Interpolations.LINEAR.ToString();
}
}
/// <summary>
/// キーフレームのデータを入力する
/// </summary>
/// <param name="time"></param>
/// <param name="value"></param>
/// <param name="valueOffset"></param>
public void SetKeyframeData(float time, float value, int valueOffset)
{
var existKeyframe = Keyframes.FirstOrDefault(x => x.Time == time);
if (existKeyframe != null)
{
existKeyframe.SetValue(value, valueOffset);
}
else
{
var newKeyframe = GetKeyframeData(AnimationProperty, ElementCount);
newKeyframe.Time = time;
newKeyframe.SetValue(value, valueOffset);
Keyframes.Add(newKeyframe);
}
}
/// <summary>
/// キー情報がなかった要素に対して直前のキーの値を入力する
/// </summary>
public void RecountEmptyKeyframe()
{
if (Keyframes.Count == 0)
{
return;
}
Keyframes.Sort((x, y) => (x.Time < y.Time) ? -1 : 1);
for (int i = 1; i < Keyframes.Count; i++)
{
var current = Keyframes[i];
var last = Keyframes[i - 1];
for (int j = 0; j < current.EnterValues.Length; j++)
{
if (!current.EnterValues[j])
{
Keyframes[i].SetValue(last.Values[j], j);
}
}
}
}
/// <summary>
/// アニメーションプロパティに対応したキーフレームを挿入する
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
[Obsolete]
private static AnimationKeyframeData GetKeyframeData(glTFAnimationTarget.AnimationPropertys property,
int elementCount)
{
return GetKeyframeData(glTFAnimationTarget.AnimationPropertysToAnimationProperties(property), elementCount);
}
/// <summary>
/// アニメーションプロパティに対応したキーフレームを挿入する
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
private static AnimationKeyframeData GetKeyframeData(glTFAnimationTarget.AnimationProperties property, int elementCount)
{
switch (property)
{
case glTFAnimationTarget.AnimationProperties.Translation:
return new AnimationKeyframeData(elementCount, (values) =>
{
var temp = new Vector3(values[0], values[1], values[2]);
return temp.ReverseZ().ToArray();
});
case glTFAnimationTarget.AnimationProperties.Rotation:
return new AnimationKeyframeData(elementCount, (values) =>
{
var temp = new Quaternion(values[0], values[1], values[2], values[3]);
return temp.ReverseZ().ToArray();
});
case glTFAnimationTarget.AnimationProperties.Scale:
return new AnimationKeyframeData(elementCount, null);
case glTFAnimationTarget.AnimationProperties.BlendShape:
return new AnimationKeyframeData(elementCount, null);
default:
return null;
}
}
#endif
}
}