diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index 6b94a4926..272f52dfc 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -198,7 +198,20 @@ namespace UniVRM10 } } - (UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone springBone, int? thumbnailIndex) ExportVrm(GameObject root, Model model, RuntimeVrmConverter converter, VRM10MetaObject meta) + /// + /// VRMコンポーネントのエクスポート + /// + /// + /// + /// + /// + /// + /// + /// + /// + (UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, + UniGLTF.Extensions.VRMC_springBone.VRMC_springBone springBone, + int? thumbnailIndex) ExportVrm(GameObject root, Model model, RuntimeVrmConverter converter, VRM10MetaObject meta) { var vrmController = root?.GetComponent(); @@ -245,6 +258,7 @@ namespace UniVRM10 ExportFirstPerson(vrm, vrmController, model, converter); vrmSpringBone = ExportSpringBone(vrmController, model, converter); + ExportConstraints(vrmController, model, converter); } return (vrm, vrmSpringBone, thumbnailTextureIndex); @@ -339,6 +353,75 @@ namespace UniVRM10 return springBone; } + void ExportConstraints(VRM10Controller vrmController, Model model, RuntimeVrmConverter converter) + { + var constraints = vrmController.GetComponentsInChildren(); + foreach (var constraint in constraints) + { + switch (constraint) + { + case VRM10PositionConstraint positionConstraint: + ExportPostionConstraint(positionConstraint, model, converter); + break; + + case VRM10RotationConstraint rotationConstraint: + ExportRotationConstraint(rotationConstraint, model, converter); + break; + + case VRM10AimConstraint aimConstraint: + ExportAimConstraint(aimConstraint, model, converter); + break; + + default: + throw new NotImplementedException(); + } + } + } + + void ExportPostionConstraint(VRM10PositionConstraint c, Model model, RuntimeVrmConverter converter) + { + throw new NotImplementedException(); + } + + static bool[] ToArray(AxisMask mask) + { + return new bool[] + { + mask.HasFlag(AxisMask.X), + mask.HasFlag(AxisMask.Y), + mask.HasFlag(AxisMask.Z), + }; + } + + void ExportRotationConstraint(VRM10RotationConstraint c, Model model, RuntimeVrmConverter converter) + { + var vrmConstraint = new UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint + { + Constraint = new UniGLTF.Extensions.VRMC_node_constraint.Constraint + { + Rotation = new UniGLTF.Extensions.VRMC_node_constraint.RotationConstraint + { + Source = model.Nodes.IndexOf(converter.Nodes[c.Source.gameObject]), + SourceSpace = c.SourceCoordinate, + DestinationSpace = c.DestinationCoordinate, + FreezeAxes = ToArray(c.FreezeAxes), + Weight = c.Weight, + }, + }, + }; + + // serialize to gltfNode + var node = converter.Nodes[c.gameObject]; + var nodeIndex = model.Nodes.IndexOf(node); + var gltfNode = Storage.Gltf.nodes[nodeIndex]; + UniGLTF.Extensions.VRMC_node_constraint.GltfSerializer.SerializeTo(ref gltfNode.extensions, vrmConstraint); + } + + static void ExportAimConstraint(VRM10AimConstraint c, Model model, RuntimeVrmConverter converter) + { + throw new NotImplementedException(); + } + static UniGLTF.Extensions.VRMC_vrm.MeshAnnotation ExportMeshAnnotation(RendererFirstPersonFlags flags, Func getIndex) { return new UniGLTF.Extensions.VRMC_vrm.MeshAnnotation