|
|
@@ -17,24 +17,9 @@ namespace SharpGLTF.Runtime
|
|
|
{
|
|
|
#region lifecycle
|
|
|
|
|
|
- internal SceneInstance(NodeTemplate[] nodeTemplates, DrawableTemplate[] drawables, Collections.NamedList<float> tracks)
|
|
|
+ internal SceneInstance(ArmatureTemplate armature, DrawableTemplate[] drawables)
|
|
|
{
|
|
|
- _AnimationTracks = tracks;
|
|
|
-
|
|
|
- _NodeTemplates = nodeTemplates;
|
|
|
- _NodeInstances = new NodeInstance[_NodeTemplates.Length];
|
|
|
-
|
|
|
- for (var i = 0; i < _NodeInstances.Length; ++i)
|
|
|
- {
|
|
|
- var n = _NodeTemplates[i];
|
|
|
- var pidx = _NodeTemplates[i].ParentIndex;
|
|
|
-
|
|
|
- if (pidx >= i) throw new ArgumentException("invalid parent index", nameof(nodeTemplates));
|
|
|
-
|
|
|
- var p = pidx < 0 ? null : _NodeInstances[pidx];
|
|
|
-
|
|
|
- _NodeInstances[i] = new NodeInstance(n, p);
|
|
|
- }
|
|
|
+ _Armature = new ArmatureInstance(armature);
|
|
|
|
|
|
_DrawableReferences = drawables;
|
|
|
_DrawableTransforms = new IGeometryTransform[_DrawableReferences.Length];
|
|
|
@@ -49,32 +34,16 @@ namespace SharpGLTF.Runtime
|
|
|
|
|
|
#region data
|
|
|
|
|
|
- private readonly NodeTemplate[] _NodeTemplates;
|
|
|
- private readonly NodeInstance[] _NodeInstances;
|
|
|
+ private readonly ArmatureInstance _Armature;
|
|
|
|
|
|
private readonly DrawableTemplate[] _DrawableReferences;
|
|
|
private readonly IGeometryTransform[] _DrawableTransforms;
|
|
|
|
|
|
- private readonly Collections.NamedList<float> _AnimationTracks;
|
|
|
-
|
|
|
#endregion
|
|
|
|
|
|
#region properties
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Gets a list of all the <see cref="NodeInstance"/> nodes used by this <see cref="SceneInstance"/>.
|
|
|
- /// </summary>
|
|
|
- public IReadOnlyList<NodeInstance> LogicalNodes => _NodeInstances;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets all the <see cref="NodeInstance"/> roots used by this <see cref="SceneInstance"/>.
|
|
|
- /// </summary>
|
|
|
- public IEnumerable<NodeInstance> VisualNodes => _NodeInstances.Where(item => item.VisualParent == null);
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets the total number of animation tracks for this instance.
|
|
|
- /// </summary>
|
|
|
- public int AnimationTracksCount => _AnimationTracks.Count;
|
|
|
+ public ArmatureInstance Armature => _Armature;
|
|
|
|
|
|
/// <summary>
|
|
|
/// Gets the number of drawable instances.
|
|
|
@@ -99,94 +68,19 @@ namespace SharpGLTF.Runtime
|
|
|
|
|
|
#region API
|
|
|
|
|
|
- public void SetLocalMatrix(string name, XFORM localMatrix)
|
|
|
- {
|
|
|
- var n = LogicalNodes.FirstOrDefault(item => item.Name == name);
|
|
|
- if (n == null) return;
|
|
|
- n.LocalMatrix = localMatrix;
|
|
|
- }
|
|
|
-
|
|
|
- public void SetWorldMatrix(string name, XFORM worldMatrix)
|
|
|
- {
|
|
|
- var n = LogicalNodes.FirstOrDefault(item => item.Name == name);
|
|
|
- if (n == null) return;
|
|
|
- n.WorldMatrix = worldMatrix;
|
|
|
- }
|
|
|
-
|
|
|
- public void SetPoseTransforms()
|
|
|
- {
|
|
|
- foreach (var n in _NodeInstances) n.SetPoseTransform();
|
|
|
- }
|
|
|
-
|
|
|
- public string NameOfTrack(int trackIndex)
|
|
|
- {
|
|
|
- return _AnimationTracks.NameOf(trackIndex);
|
|
|
- }
|
|
|
-
|
|
|
- public int IndexOfTrack(string name)
|
|
|
- {
|
|
|
- return _AnimationTracks.IndexOf(name);
|
|
|
- }
|
|
|
-
|
|
|
- public float GetAnimationDuration(int trackLogicalIndex)
|
|
|
- {
|
|
|
- if (trackLogicalIndex < 0) return 0;
|
|
|
- if (trackLogicalIndex >= _AnimationTracks.Count) return 0;
|
|
|
-
|
|
|
- return _AnimationTracks[trackLogicalIndex];
|
|
|
- }
|
|
|
-
|
|
|
- public void SetAnimationFrame(int trackLogicalIndex, float time, bool looped = true)
|
|
|
- {
|
|
|
- if (looped)
|
|
|
- {
|
|
|
- var duration = GetAnimationDuration(trackLogicalIndex);
|
|
|
- if (duration > 0) time = time % duration;
|
|
|
- }
|
|
|
-
|
|
|
- foreach (var n in _NodeInstances) n.SetAnimationFrame(trackLogicalIndex, time);
|
|
|
- }
|
|
|
-
|
|
|
- public void SetAnimationFrame(params (int TrackIdx, float Time, float Weight)[] blended)
|
|
|
- {
|
|
|
- SetAnimationFrame(_NodeInstances, blended);
|
|
|
- }
|
|
|
-
|
|
|
- public static void SetAnimationFrame(IEnumerable<NodeInstance> nodes, params (int TrackIdx, float Time, float Weight)[] blended)
|
|
|
- {
|
|
|
- Guard.NotNull(nodes, nameof(nodes));
|
|
|
-
|
|
|
- Span<int> tracks = stackalloc int[blended.Length];
|
|
|
- Span<float> times = stackalloc float[blended.Length];
|
|
|
- Span<float> weights = stackalloc float[blended.Length];
|
|
|
-
|
|
|
- float w = blended.Sum(item => item.Weight);
|
|
|
-
|
|
|
- w = w == 0 ? 1 : 1 / w;
|
|
|
-
|
|
|
- for (int i = 0; i < blended.Length; ++i)
|
|
|
- {
|
|
|
- tracks[i] = blended[i].TrackIdx;
|
|
|
- times[i] = blended[i].Time;
|
|
|
- weights[i] = blended[i].Weight * w;
|
|
|
- }
|
|
|
-
|
|
|
- foreach (var n in nodes) n.SetAnimationFrame(tracks, times, weights);
|
|
|
- }
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// Gets a drawable reference pair, where:
|
|
|
/// - MeshIndex is the logical Index of a <see cref="Schema2.Mesh"/> in <see cref="Schema2.ModelRoot.LogicalMeshes"/>.
|
|
|
/// - Transform is an <see cref="IGeometryTransform"/> that can be used to transform the <see cref="Schema2.Mesh"/> into world space.
|
|
|
/// </summary>
|
|
|
- /// <param name="index">The index of the drawable reference, from 0 to <see cref="DrawableReferencesCount"/></param>
|
|
|
+ /// <param name="index">The index of the drawable reference, from 0 to <see cref="DrawableInstancesCount"/></param>
|
|
|
/// <returns>A drawable reference</returns>
|
|
|
[Obsolete("Use GetDrawableInstance")]
|
|
|
public (int MeshIndex, IGeometryTransform Transform) GetDrawableReference(int index)
|
|
|
{
|
|
|
var dref = _DrawableReferences[index];
|
|
|
|
|
|
- dref.UpdateGeometryTransform(_DrawableTransforms[index], _NodeInstances);
|
|
|
+ dref.UpdateGeometryTransform(_DrawableTransforms[index], _Armature.LogicalNodes);
|
|
|
|
|
|
return (dref.LogicalMeshIndex, _DrawableTransforms[index]);
|
|
|
}
|
|
|
@@ -203,7 +97,7 @@ namespace SharpGLTF.Runtime
|
|
|
{
|
|
|
var dref = _DrawableReferences[index];
|
|
|
|
|
|
- dref.UpdateGeometryTransform(_DrawableTransforms[index], _NodeInstances);
|
|
|
+ dref.UpdateGeometryTransform(_DrawableTransforms[index], _Armature.LogicalNodes);
|
|
|
|
|
|
return new DrawableInstance(dref, _DrawableTransforms[index]);
|
|
|
}
|