mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-03-27 21:05:04 -05:00
203 lines
7.5 KiB
C#
203 lines
7.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UniJSON;
|
|
|
|
namespace UniVRM10
|
|
{
|
|
public static class MigrationVrmSpringBone
|
|
{
|
|
static IEnumerable<UniGLTF.glTFNode> TraverseFirstChild(List<UniGLTF.glTFNode> nodes, UniGLTF.glTFNode node)
|
|
{
|
|
yield return node;
|
|
|
|
if (node.children != null && node.children.Length > 0)
|
|
{
|
|
foreach (var x in TraverseFirstChild(nodes, nodes[node.children[0]]))
|
|
{
|
|
yield return x;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void AddTail7cm(UniGLTF.glTF gltf, UniGLTF.glTFNode[] joints)
|
|
{
|
|
if (joints.Length < 2)
|
|
{
|
|
return;
|
|
}
|
|
var last = joints.Last();
|
|
var name = last.name ?? "";
|
|
var v1 = new UnityEngine.Vector3(last.translation[0], last.translation[1], last.translation[2]);
|
|
// var last2 = joints[joints.Length - 2];
|
|
// var v2 = new UnityEngine.Vector3(last2.translation[0], last2.translation[1], last2.translation[2]);
|
|
var delta = v1.normalized * 0.07f; // 7cm
|
|
var tail = new UniGLTF.glTFNode
|
|
{
|
|
name = name + "_end",
|
|
translation = new float[] {
|
|
delta.x,
|
|
delta.y,
|
|
delta.z
|
|
},
|
|
};
|
|
var tail_index = gltf.nodes.Count;
|
|
gltf.nodes.Add(tail);
|
|
if (last.children != null && last.children.Length > 0)
|
|
{
|
|
throw new System.Exception();
|
|
}
|
|
last.children = new[] { tail_index };
|
|
}
|
|
|
|
/// <summary>
|
|
/// {
|
|
/// "colliderGroups": [
|
|
/// ],
|
|
/// "boneGroups": [
|
|
/// ],
|
|
/// }
|
|
/// </summary>
|
|
/// <param name="gltf"></param>
|
|
/// <param name="sa"></param>
|
|
/// <returns></returns>
|
|
public static UniGLTF.Extensions.VRMC_springBone.VRMC_springBone Migrate(UniGLTF.glTF gltf, JsonNode sa)
|
|
{
|
|
var springBone = new UniGLTF.Extensions.VRMC_springBone.VRMC_springBone
|
|
{
|
|
Colliders = new List<UniGLTF.Extensions.VRMC_springBone.Collider>(),
|
|
ColliderGroups = new List<UniGLTF.Extensions.VRMC_springBone.ColliderGroup>(),
|
|
Springs = new List<UniGLTF.Extensions.VRMC_springBone.Spring>(),
|
|
};
|
|
|
|
foreach (var x in sa["colliderGroups"].ArrayItems())
|
|
{
|
|
// {
|
|
// "node": 14,
|
|
// "colliders": [
|
|
// {
|
|
// "offset": {
|
|
// "x": 0.025884293,
|
|
// "y": -0.120000005,
|
|
// "z": 0
|
|
// },
|
|
// "radius": 0.05
|
|
// },
|
|
// {
|
|
// "offset": {
|
|
// "x": -0.02588429,
|
|
// "y": -0.120000005,
|
|
// "z": 0
|
|
// },
|
|
// "radius": 0.05
|
|
// },
|
|
// {
|
|
// "offset": {
|
|
// "x": 0,
|
|
// "y": -0.0220816135,
|
|
// "z": 0
|
|
// },
|
|
// "radius": 0.08
|
|
// }
|
|
// ]
|
|
// },
|
|
var colliders = new List<int>();
|
|
foreach (var y in x["colliders"].ArrayItems())
|
|
{
|
|
colliders.Add(springBone.Colliders.Count);
|
|
springBone.Colliders.Add(new UniGLTF.Extensions.VRMC_springBone.Collider
|
|
{
|
|
Node = x["node"].GetInt32(),
|
|
Shape = new UniGLTF.Extensions.VRMC_springBone.ColliderShape
|
|
{
|
|
Sphere = new UniGLTF.Extensions.VRMC_springBone.ColliderShapeSphere
|
|
{
|
|
Offset = MigrateVector3.Migrate(y["offset"]),
|
|
Radius = y["radius"].GetSingle()
|
|
}
|
|
}
|
|
});
|
|
}
|
|
var colliderGroup = new UniGLTF.Extensions.VRMC_springBone.ColliderGroup()
|
|
{
|
|
Colliders = colliders.ToArray(),
|
|
};
|
|
springBone.ColliderGroups.Add(colliderGroup);
|
|
}
|
|
|
|
// https://github.com/vrm-c/vrm-specification/pull/255
|
|
// 1.0 では末端に7cmの遠さに joint を追加する動作をしなくなった。
|
|
// その差異に対応して、7cmの遠さに node を追加する。
|
|
foreach (var x in sa["boneGroups"].ArrayItems())
|
|
{
|
|
if (x.ContainsKey("bones"))
|
|
{
|
|
foreach (var y in x["bones"].ArrayItems())
|
|
{
|
|
var joints = TraverseFirstChild(gltf.nodes, gltf.nodes[y.GetInt32()]).ToArray();
|
|
AddTail7cm(gltf, joints);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var x in sa["boneGroups"].ArrayItems())
|
|
{
|
|
// {
|
|
// "comment": "",
|
|
// "stiffiness": 2,
|
|
// "gravityPower": 0,
|
|
// "gravityDir": {
|
|
// "x": 0,
|
|
// "y": -1,
|
|
// "z": 0
|
|
// },
|
|
// "dragForce": 0.7,
|
|
// "center": -1,
|
|
// "hitRadius": 0.02,
|
|
// "bones": [
|
|
// 97,
|
|
// 99,
|
|
// 101,
|
|
// 113,
|
|
// 114
|
|
// ],
|
|
// "colliderGroups": [
|
|
// 3,
|
|
// 4,
|
|
// 5
|
|
// ]
|
|
// },
|
|
if (x.ContainsKey("bones"))
|
|
{
|
|
foreach (var y in x["bones"].ArrayItems())
|
|
{
|
|
var comment = x.GetObjectValueOrDefault("comment", "");
|
|
var spring = new UniGLTF.Extensions.VRMC_springBone.Spring
|
|
{
|
|
Name = comment,
|
|
ColliderGroups = x["colliderGroups"].ArrayItems().Select(z => z.GetInt32()).ToArray(),
|
|
Joints = new List<UniGLTF.Extensions.VRMC_springBone.SpringBoneJoint>(),
|
|
};
|
|
|
|
foreach (var z in TraverseFirstChild(gltf.nodes, gltf.nodes[y.GetInt32()]))
|
|
{
|
|
spring.Joints.Add(new UniGLTF.Extensions.VRMC_springBone.SpringBoneJoint
|
|
{
|
|
Node = gltf.nodes.IndexOf(z),
|
|
DragForce = x["dragForce"].GetSingle(),
|
|
GravityDir = MigrateVector3.Migrate(x["gravityDir"]),
|
|
GravityPower = x["gravityPower"].GetSingle(),
|
|
HitRadius = x["hitRadius"].GetSingle(),
|
|
Stiffness = x["stiffiness"].GetSingle(),
|
|
});
|
|
}
|
|
|
|
springBone.Springs.Add(spring);
|
|
}
|
|
}
|
|
}
|
|
|
|
return springBone;
|
|
}
|
|
}
|
|
}
|