您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

134 行
3.3 KiB

using System;
using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
namespace VrmLib
{
public enum AnimationPathType
{
Translation,
Rotation,
Scale,
Weights,
}
public class CurveSampler
{
public BufferAccessor In;
public BufferAccessor Out;
public float LastTime
{
get
{
if (In.ComponentType == AccessorValueType.FLOAT)
{
var times = In.Bytes.Reinterpret<Single>(1);
return times[times.Length - 1];
}
else
{
throw new NotImplementedException();
}
}
}
public CurveSampler()
{
}
ValueTuple<int, int, float> GetRange(float seconds)
{
var keys = In.GetSpan<float>();
if (seconds <= keys[0])
{
return (0, 0, 0);
}
else if (seconds >= keys[keys.Length - 1])
{
return (keys.Length - 1, keys.Length - 1, 0);
}
// search range
float begin = keys[0];
float end;
for (int i = 1; i < keys.Length; ++i)
{
end = keys[i];
if (seconds == end)
{
return (i, i, 0);
}
else if (seconds < end)
{
var ratio = (seconds - begin) / (end - begin);
return (i - 1, i, ratio);
}
begin = end;
}
throw new Exception("not found");
}
public Vector3 GetVector3(TimeSpan elapsed)
{
var (begin, end, ratio) = GetRange((float)elapsed.TotalSeconds);
var values = Out.GetSpan<Vector3>();
if (begin == end)
{
return values[begin];
}
else
{
// TODO: curve interpolation
return Vector3.Lerp(values[begin], values[end], ratio);
}
}
public Quaternion GetQuaternion(TimeSpan elapsed)
{
var (begin, end, ratio) = GetRange((float)elapsed.TotalSeconds);
var values = Out.GetSpan<Quaternion>();
if (begin == end)
{
return values[begin];
}
else
{
// TODO: curve interpolation
return Quaternion.Lerp(values[begin], values[end], ratio);
}
}
public void SkipFrame(int skipFrames)
{
In = In.Skip(skipFrames);
Out = Out.Skip(skipFrames);
}
}
public class NodeAnimation
{
public TimeSpan Duration
{
get
{
var lastTime = float.NegativeInfinity;
foreach (var kv in Curves)
{
if (kv.Value.LastTime > lastTime)
{
lastTime = kv.Value.LastTime;
}
}
return TimeSpan.FromSeconds(lastTime);
}
}
public Dictionary<AnimationPathType, CurveSampler> Curves = new Dictionary<AnimationPathType, CurveSampler>();
}
}