diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index f87d172c9..042e72e5a 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -314,40 +314,44 @@ namespace UniVRM10 Springs = new List(), }; - Func getIndexFromTransform = t => + Func getNodeIndexFromTransform = t => { var node = converter.Nodes[t.gameObject]; return model.Nodes.IndexOf(node); }; + var colliderGroups = vrmController.GetComponentsInChildren(); + foreach (var x in colliderGroups) + { + var colliderGroup = new UniGLTF.Extensions.VRMC_springBone.ColliderGroup + { + Colliders = new List(), + }; + springBone.ColliderGroups.Add(colliderGroup); + + foreach (var y in x.Colliders) + { + if (y == null) + { + continue; + } + colliderGroup.Colliders.Add(new UniGLTF.Extensions.VRMC_springBone.Collider + { + Node = getNodeIndexFromTransform(y.transform), + Shape = ExportShape(y), + }); + } + } + foreach (var x in vrmController.GetComponentsInChildren()) { var spring = new UniGLTF.Extensions.VRMC_springBone.Spring { Name = x.Comment, - Joints = x.Joints.Select(y => ExportJoint(y, getIndexFromTransform)).ToList(), + Joints = x.Joints.Select(y => ExportJoint(y, getNodeIndexFromTransform)).ToList(), + ColliderGroups = x.ColliderGroups.Select(y => Array.IndexOf(colliderGroups, y)).ToArray(), }; springBone.Springs.Add(spring); - - List colliders = new List(); - foreach (var y in x.ColliderGroups) - { - // node - var node = converter.Nodes[y.gameObject]; - var nodeIndex = model.Nodes.IndexOf(node); - colliders.Add(nodeIndex); - var gltfNode = Storage.Gltf.nodes[nodeIndex]; - - // // VRMC_node_collider - // var collider = new UniGLTF.Extensions.VRMC_node_collider.VRMC_node_collider - // { - // Shapes = y.Colliders.Select(ExportShape).ToList(), - // }; - - // // serialize - // UniGLTF.Extensions.VRMC_node_collider.GltfSerializer.SerializeTo(ref gltfNode.extensions, collider); - } - spring.ColliderGroups = colliders.ToArray(); } return springBone; diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 03c6b5e1d..1a8d52ba9 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -365,6 +365,47 @@ namespace UniVRM10 // springs if (gltfVrmSpringBone.Springs != null) { + var secondary = Root.transform.Find("secondary"); + if (secondary == null) + { + secondary = new GameObject("secondary").transform; + secondary.SetParent(Root.transform, false); + } + + // colliderGroup + var list = new List(); + foreach (var g in gltfVrmSpringBone.ColliderGroups) + { + var colliderGroup = secondary.gameObject.AddComponent(); + list.Add(colliderGroup); + + foreach (var c in g.Colliders) + { + var node = Nodes[c.Node.Value]; + + var collider = node.gameObject.AddComponent(); + colliderGroup.Colliders.Add(collider); + + if (c.Shape.Sphere is UniGLTF.Extensions.VRMC_springBone.ColliderShapeSphere sphere) + { + collider.ColliderType = VRM10SpringBoneColliderTypes.Sphere; + collider.Radius = sphere.Radius.Value; + collider.Offset = Vector3InvertX(sphere.Offset); + } + else if (c.Shape.Capsule is UniGLTF.Extensions.VRMC_springBone.ColliderShapeCapsule capsule) + { + collider.ColliderType = VRM10SpringBoneColliderTypes.Capsule; + collider.Radius = capsule.Radius.Value; + collider.Offset = Vector3InvertX(capsule.Offset); + collider.Tail = Vector3InvertX(capsule.Tail); + } + else + { + throw new NotImplementedException(); + } + } + } + foreach (var gltfSpring in gltfVrmSpringBone.Springs) { if (gltfSpring.Joints == null || gltfSpring.Joints.Count == 0) @@ -374,6 +415,7 @@ namespace UniVRM10 var firstJointNode = Nodes[gltfSpring.Joints.First().Node.Value]; var springBone = firstJointNode.gameObject.AddComponent(); springBone.Comment = gltfSpring.Name; + springBone.ColliderGroups = gltfSpring.ColliderGroups.Select(x => list[x]).ToList(); // joint foreach (var gltfJoint in gltfSpring.Joints) @@ -395,52 +437,6 @@ namespace UniVRM10 springBone.Joints.Add(joint); } } - - // // collider - // springBone.ColliderGroups.AddRange(gltfSpring.ColliderGroups.Select(colliderNode => - // { - // if (UniGLTF.Extensions.VRMC_node_collider.GltfDeserializer.TryGet(Parser.GLTF.nodes[colliderNode].extensions, - // out UniGLTF.Extensions.VRMC_node_collider.VRMC_node_collider extension)) - // { - // var node = Nodes[colliderNode]; - // var colliderGroup = node.gameObject.GetComponent(); - // if (colliderGroup == null) - // { - // colliderGroup = node.gameObject.AddComponent(); - // colliderGroup.Colliders.AddRange(extension.Shapes.Select(x => - // { - // if (x.Sphere != null) - // { - // return new VRM10SpringBoneCollider - // { - // ColliderType = VRM10SpringBoneColliderTypes.Sphere, - // Offset = Vector3InvertX(x.Sphere.Offset), - // Radius = x.Sphere.Radius.Value, - // }; - // } - // else if (x.Capsule != null) - // { - // return new VRM10SpringBoneCollider - // { - // ColliderType = VRM10SpringBoneColliderTypes.Capsule, - // Offset = Vector3InvertX(x.Capsule.Offset), - // Radius = x.Capsule.Radius.Value, - // Tail = Vector3InvertX(x.Capsule.Tail), - // }; - // } - // else - // { - // throw new NotImplementedException(); - // } - // })); - // } - // return colliderGroup; - // } - // else - // { - // return null; - // } - // }).Where(x => x != null)); } } } diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrmSpringBone.cs b/Assets/VRM10/Runtime/Migration/MigrationVrmSpringBone.cs index 10b91d1a6..bb8deeb59 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrmSpringBone.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrmSpringBone.cs @@ -73,6 +73,7 @@ namespace UniVRM10 { colliderGroup.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