VRMSpringUtility.LoadSecondary 関数が throw しないように修正

fix #2023
SpringBone は不完全になるが throw しない。
This commit is contained in:
ousttrue 2023-05-15 13:07:16 +09:00
parent 46d6df7552
commit 69b952257a
4 changed files with 53 additions and 18 deletions

View File

@ -335,6 +335,16 @@ namespace UniGLTF
#region Imported
protected GameObject Root;
public List<Transform> Nodes = new List<Transform>();
public bool TryGetNode(int index, out Transform node)
{
if (index < 0 || index >= Nodes.Count)
{
node = default;
return false;
}
node = Nodes[index];
return true;
}
public List<MeshWithMaterials> Meshes = new List<MeshWithMaterials>();
#endregion

View File

@ -93,10 +93,17 @@ namespace VRM
var root = go.transform;
var nodes = root.Traverse().Skip(1).ToList();
VRMSpringUtility.LoadSecondary(root, nodes, spring);
VRMSpringUtility.LoadSecondary(root, (int index, out Transform node) =>
{
if (index < 0 || index >= nodes.Count)
{
node = default;
return false;
}
node = nodes[index];
return true;
}, spring);
}
#endregion
}
}

View File

@ -59,7 +59,7 @@ namespace VRM
using (MeasureTime("VRM LoadSecondary"))
{
VRMSpringUtility.LoadSecondary(Root.transform, Nodes,
VRMSpringUtility.LoadSecondary(Root.transform, TryGetNode,
VRM.secondaryAnimation);
}
await awaitCaller.NextFrame();

View File

@ -62,7 +62,12 @@ namespace VRM
}
}
public static void LoadSecondary(Transform root, List<Transform> nodes,
/// <summary>
/// Node getter. If not found, Never throw, return false.
/// </summary>
public delegate bool TryGetNode(int index, out Transform transform);
public static void LoadSecondary(Transform root, TryGetNode tryGetNode,
glTF_VRM_SecondaryAnimation secondaryAnimation)
{
var secondary = root.Find("secondary");
@ -108,20 +113,27 @@ namespace VRM
}
}
//var secondaryAnimation = context.VRM.extensions.VRM.secondaryAnimation;
var colliders = new List<VRMSpringBoneColliderGroup>();
foreach (var colliderGroup in secondaryAnimation.colliderGroups)
{
var vrmGroup = nodes[colliderGroup.node].gameObject.AddComponent<VRMSpringBoneColliderGroup>();
vrmGroup.Colliders = colliderGroup.colliders.Select(x =>
if (tryGetNode(colliderGroup.node, out var node))
{
return new VRMSpringBoneColliderGroup.SphereCollider
var vrmGroup = node.gameObject.AddComponent<VRMSpringBoneColliderGroup>();
vrmGroup.Colliders = colliderGroup.colliders.Select(x =>
{
Offset = x.offset,
Radius = x.radius
};
}).ToArray();
colliders.Add(vrmGroup);
return new VRMSpringBoneColliderGroup.SphereCollider
{
Offset = x.offset,
Radius = x.radius
};
}).ToArray();
colliders.Add(vrmGroup);
}
else
{
Debug.LogError("Broken collider group");
break;
}
}
if (secondaryAnimation.boneGroups.Count > 0)
@ -129,9 +141,9 @@ namespace VRM
foreach (var boneGroup in secondaryAnimation.boneGroups)
{
var vrmBoneGroup = secondary.gameObject.AddComponent<VRMSpringBone>();
if (boneGroup.center != -1)
if (tryGetNode(boneGroup.center, out var node))
{
vrmBoneGroup.m_center = nodes[boneGroup.center];
vrmBoneGroup.m_center = node;
}
vrmBoneGroup.m_comment = boneGroup.comment;
@ -147,14 +159,20 @@ namespace VRM
for (int i = 0; i < boneGroup.colliderGroups.Length; ++i)
{
var colliderGroup = boneGroup.colliderGroups[i];
vrmBoneGroup.ColliderGroups[i] = colliders[colliderGroup];
if (colliderGroup >= 0 && colliderGroup < colliders.Count)
{
vrmBoneGroup.ColliderGroups[i] = colliders[colliderGroup];
}
}
}
var boneList = new List<Transform>();
foreach (var x in boneGroup.bones)
{
boneList.Add(nodes[x]);
if (tryGetNode(x, out var boneNode))
{
boneList.Add(boneNode);
}
}
vrmBoneGroup.RootBones = boneList;