/// <summary>
        /// metaObject が null のときは、root から取得する
        /// </summary>
        public VrmLib.Model ToModelFrom10(GameObject root, VRMMetaObject metaObject = null)
        {
            Model = new VrmLib.Model(VrmLib.Coordinates.Unity);

            if (metaObject is null)
            {
                var vrmMeta = root.GetComponent <VRMMeta>();
                if (vrmMeta is null || vrmMeta.Meta is null)
                {
                    throw new NullReferenceException("metaObject is null");
                }
                metaObject = vrmMeta.Meta;
            }

            ToGlbModel(root);

            // meta
            var meta = new VrmLib.Meta();

            meta.Name       = metaObject.Name;
            meta.Version    = metaObject.Version;
            meta.Copyrights = metaObject.Copyrights;
            meta.Authors.AddRange(metaObject.Authors);
            meta.ContactInformation = metaObject.ContactInformation;
            meta.Reference          = metaObject.Reference;
            meta.Thumbnail          = metaObject.Thumbnail.ToPngImage(VrmLib.ImageUsage.None);

            meta.AvatarPermission = new VrmLib.AvatarPermission
            {
                AvatarUsage           = metaObject.AllowedUser,
                IsAllowedViolentUsage = metaObject.ViolentUsage,
                IsAllowedSexualUsage  = metaObject.SexualUsage,
                CommercialUsage       = metaObject.CommercialUsage,
                IsAllowedGameUsage    = metaObject.GameUsage,
                IsAllowedPoliticalOrReligiousUsage = metaObject.PoliticalOrReligiousUsage,
                OtherPermissionUrl = metaObject.OtherPermissionUrl,
            };
            meta.RedistributionLicense = new VrmLib.RedistributionLicense
            {
                CreditNotation        = metaObject.CreditNotation,
                IsAllowRedistribution = metaObject.Redistribution,
                ModificationLicense   = metaObject.ModificationLicense,
                OtherLicenseUrl       = metaObject.OtherLicenseUrl,
            };
            Model.Vrm = new VrmLib.Vrm(meta, UniVRM10.VRMVersion.VERSION, UniVRM10.VRMSpecVersion.Version);

            // humanoid
            {
                var animator = root.GetComponent <Animator>();
                if (animator != null && animator.avatar != null)
                {
                    foreach (HumanBodyBones humanBoneType in Enum.GetValues(typeof(HumanBodyBones)))
                    {
                        if (humanBoneType == HumanBodyBones.LastBone)
                        {
                            continue;
                        }

                        var transform = animator.GetBoneTransform(humanBoneType);
                        if (transform != null && Nodes.TryGetValue(transform.gameObject, out VrmLib.Node node))
                        {
                            node.HumanoidBone = (VrmLib.HumanoidBones)Enum.Parse(typeof(VrmLib.HumanoidBones), humanBoneType.ToString(), true);
                        }
                    }
                }
            }


            // blendShape
            {
                Model.Vrm.BlendShape = new VrmLib.BlendShapeManager();
                var blendShapeProxy = root.GetComponent <UniVRM10.VRMBlendShapeProxy>();
                if (blendShapeProxy != null)
                {
                    foreach (var clip in blendShapeProxy.BlendShapeAvatar.Clips)
                    {
                        var blendShape = new VrmLib.BlendShape(clip.Preset, clip.BlendShapeName, clip.IsBinary);
                        blendShape.IgnoreBlink  = clip.IgnoreBlink;
                        blendShape.IgnoreLookAt = clip.IgnoreLookAt;
                        blendShape.IgnoreMouth  = clip.IgnoreMouth;

                        foreach (var value in clip.Values)
                        {
                            var transform = GetTransformFromRelativePath(root.transform, value.RelativePath);
                            if (transform == null)
                            {
                                continue;
                            }
                            var renderer = transform.gameObject.GetComponent <SkinnedMeshRenderer>();
                            if (renderer == null)
                            {
                                continue;
                            }
                            var mesh = renderer.sharedMesh;
                            if (mesh == null)
                            {
                                continue;
                            }

                            var names = new List <string>();
                            for (int i = 0; i < mesh.blendShapeCount; ++i)
                            {
                                names.Add(mesh.GetBlendShapeName(i));
                            }

                            var node            = Nodes[transform.gameObject];
                            var blendShapeValue = new VrmLib.BlendShapeBindValue(
                                node,
                                names[value.Index],
                                value.Weight
                                );
                            blendShape.BlendShapeValues.Add(blendShapeValue);
                        }

                        foreach (var value in clip.MaterialValues)
                        {
                            var materialPair = Materials.FirstOrDefault(x => x.Key.name == value.MaterialName);
                            if (materialPair.Equals(default(KeyValuePair <Material, VrmLib.Material>)))
                            {
                                continue;
                            }

                            var bind = new VrmLib.MaterialBindValue(
                                materialPair.Value,
                                value.ValueName,
                                value.TargetValue.ToNumericsVector4()
                                );
                            blendShape.MaterialValues.Add(bind);
                        }

                        Model.Vrm.BlendShape.BlendShapeList.Add(blendShape);
                    }
                }
            }

            // firstPerson
            {
                var firstPerson          = new VrmLib.FirstPerson();
                var firstPersonComponent = root.GetComponent <UniVRM10.VRMFirstPerson>();
                if (firstPersonComponent != null)
                {
                    foreach (var annotation in firstPersonComponent.Renderers)
                    {
                        firstPerson.Annotations.Add(
                            new VrmLib.FirstPersonMeshAnnotation(Nodes[annotation.Renderer.gameObject],
                                                                 annotation.FirstPersonFlag)
                            );
                    }
                    Model.Vrm.FirstPerson = firstPerson;
                }
            }

            // lookAt
            {
                var blendShapeProxy  = root.GetComponent <UniVRM10.VRMBlendShapeProxy>();
                var lookAt           = new VrmLib.LookAt();
                var lookAtBlendShape = blendShapeProxy;
                var lookAtBone       = blendShapeProxy;
                if (lookAtBlendShape != null)
                {
                    if (lookAtBlendShape.LookAtType == VRMBlendShapeProxy.LookAtTypes.BlendShape)
                    {
                        lookAt.HorizontalInner = new VrmLib.LookAtRangeMap();
                        lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap()
                        {
                            InputMaxValue = lookAtBlendShape.HorizontalOuter.CurveXRangeDegree,
                            OutputScaling = lookAtBlendShape.HorizontalOuter.CurveYRangeDegree
                        };
                        lookAt.VerticalUp = new VrmLib.LookAtRangeMap()
                        {
                            InputMaxValue = lookAtBlendShape.VerticalUp.CurveXRangeDegree,
                            OutputScaling = lookAtBlendShape.VerticalUp.CurveYRangeDegree,
                        };
                        lookAt.VerticalDown = new VrmLib.LookAtRangeMap()
                        {
                            InputMaxValue = lookAtBlendShape.VerticalDown.CurveXRangeDegree,
                            OutputScaling = lookAtBlendShape.VerticalDown.CurveYRangeDegree,
                        };
                    }
                    else if (lookAtBlendShape.LookAtType == VRMBlendShapeProxy.LookAtTypes.Bone)
                    {
                        lookAt.HorizontalInner = new VrmLib.LookAtRangeMap()
                        {
                            InputMaxValue = lookAtBone.HorizontalInner.CurveXRangeDegree,
                            OutputScaling = lookAtBone.HorizontalInner.CurveYRangeDegree
                        };
                        lookAt.HorizontalOuter = new VrmLib.LookAtRangeMap()
                        {
                            InputMaxValue = lookAtBone.HorizontalOuter.CurveXRangeDegree,
                            OutputScaling = lookAtBone.HorizontalOuter.CurveYRangeDegree
                        };
                        lookAt.VerticalUp = new VrmLib.LookAtRangeMap()
                        {
                            InputMaxValue = lookAtBone.VerticalUp.CurveXRangeDegree,
                            OutputScaling = lookAtBone.VerticalUp.CurveYRangeDegree,
                        };
                        lookAt.VerticalDown = new VrmLib.LookAtRangeMap()
                        {
                            InputMaxValue = lookAtBone.VerticalDown.CurveXRangeDegree,
                            OutputScaling = lookAtBone.VerticalDown.CurveYRangeDegree,
                        };
                    }
                    lookAt.OffsetFromHeadBone = blendShapeProxy.OffsetFromHead.ToNumericsVector3();
                }
                Model.Vrm.LookAt = lookAt;
            }

            // springBone
            {
                var springBoneColliderGroups = root.GetComponentsInChildren <UniVRM10.VRMSpringBoneColliderGroup>();
                if (springBoneColliderGroups != null)
                {
                    Model.Vrm.SpringBone = new VrmLib.SpringBoneManager();
                    var colliders = new Dictionary <UniVRM10.VRMSpringBoneColliderGroup, VrmLib.SpringBoneColliderGroup>();
                    foreach (var colliderGroup in springBoneColliderGroups)
                    {
                        var colliderGroups = colliderGroup.Colliders.Select(x =>
                        {
                            switch (x.ColliderTypes)
                            {
                            case SpringBoneColliderTypes.Sphere:
                                return(VrmLib.VrmSpringBoneCollider.CreateSphere(x.Offset.ToNumericsVector3(), x.Radius));

                            case SpringBoneColliderTypes.Capsule:
                                return(VrmLib.VrmSpringBoneCollider.CreateCapsule(x.Offset.ToNumericsVector3(), x.Radius, x.Tail.ToNumericsVector3()));

                            default:
                                throw new NotImplementedException();
                            }
                        });
                        var vrmColliderGroup = new VrmLib.SpringBoneColliderGroup(Nodes[colliderGroup.gameObject], colliderGroups);
                        Model.Vrm.SpringBone.Colliders.Add(vrmColliderGroup);

                        colliders.Add(colliderGroup, vrmColliderGroup);
                    }

                    var springBones = root.GetComponentsInChildren <UniVRM10.VRMSpringBone>();
                    foreach (var springBone in springBones)
                    {
                        var vrmSpringBone = new VrmLib.SpringBone()
                        {
                            Comment      = springBone.m_comment,
                            Stiffness    = springBone.m_stiffnessForce,
                            GravityPower = springBone.m_gravityPower,
                            GravityDir   = springBone.m_gravityDir.ToNumericsVector3(),
                            DragForce    = springBone.m_dragForce,
                            Origin       = (springBone.m_center != null) ? Nodes[springBone.m_center.gameObject] : null,
                            HitRadius    = springBone.m_hitRadius,
                        };

                        foreach (var rootBone in springBone.RootBones)
                        {
                            vrmSpringBone.Bones.Add(Nodes[rootBone.gameObject]);
                        }

                        foreach (var collider in springBone.ColliderGroups)
                        {
                            vrmSpringBone.Colliders.Add(colliders[collider]);
                        }

                        Model.Vrm.SpringBone.Springs.Add(vrmSpringBone);
                    }
                }
            }

            return(Model);
        }