/// <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); }