public static void Normalize() { var go = Selection.activeObject as GameObject; // BoneNormalizer.Execute はコピーを正規化する。UNDO無用 Selection.activeGameObject = VRMBoneNormalizer.Execute(go, true); }
private static void ExportFromMenu() { var go = Selection.activeObject as GameObject; // BoneNormalizer.Execute はコピーを正規化する。UNDO無用 Selection.activeGameObject = VRMBoneNormalizer.Execute(go, true); }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <param name="settings"></param> /// <param name="destroy">作業が終わったらDestoryするべき一時オブジェクト</param> static void Export(string path, GameObject exportRoot, VRMMetaObject meta, VRMExportSettings settings, IReadOnlyList <MeshUtility.MeshExportInfo> info, List <GameObject> destroy) { var target = exportRoot; // 常にコピーする。シーンを変化させない target = GameObject.Instantiate(target); destroy.Add(target); var metaBehaviour = target.GetComponent <VRMMeta>(); if (metaBehaviour == null) { metaBehaviour = target.AddComponent <VRMMeta>(); metaBehaviour.Meta = meta; } if (metaBehaviour.Meta == null) { // 来ないはず throw new Exception("meta required"); } { // copy元 var animator = exportRoot.GetComponent <Animator>(); var beforeTransforms = exportRoot.GetComponentsInChildren <Transform>(); // copy先 var afterTransforms = target.GetComponentsInChildren <Transform>(); // copy先のhumanoidBoneのリストを得る var bones = (HumanBodyBones[])Enum.GetValues(typeof(HumanBodyBones)); var humanTransforms = bones .Where(x => x != HumanBodyBones.LastBone) .Select(x => animator.GetBoneTransform(x)) .Where(x => x != null) .Select(x => afterTransforms[Array.IndexOf(beforeTransforms, x)]) // copy 先を得る .ToArray(); var nameCount = target.GetComponentsInChildren <Transform>() .GroupBy(x => x.name) .ToDictionary(x => x.Key, x => x.Count()); foreach (var t in target.GetComponentsInChildren <Transform>()) { if (humanTransforms.Contains(t)) { // keep original name continue; } if (nameCount[t.name] > 1) { // 重複するボーン名をリネームする ForceUniqueName(t, nameCount); } } } // 正規化 if (settings.PoseFreeze) { // BoneNormalizer.Execute は Copy を作って正規化する。UNDO無用 target = VRMBoneNormalizer.Execute(target, settings.ForceTPose, false); destroy.Add(target); } // 元のBlendShapeClipに変更を加えないように複製 var proxy = target.GetComponent <VRMBlendShapeProxy>(); if (proxy != null) { var copyBlendShapeAvatar = CopyBlendShapeAvatar(proxy.BlendShapeAvatar, settings.ReduceBlendshapeClip); proxy.BlendShapeAvatar = copyBlendShapeAvatar; // BlendShape削減 if (settings.ReduceBlendshape) { foreach (SkinnedMeshRenderer smr in target.GetComponentsInChildren <SkinnedMeshRenderer>()) { // 未使用のBlendShapeを間引く ReplaceMesh(target, smr, copyBlendShapeAvatar); } } } // 出力 var sw = System.Diagnostics.Stopwatch.StartNew(); var gltf = new UniGLTF.glTF(); using (var exporter = new VRMExporter(gltf)) { exporter.Prepare(target); exporter.Export(settings.MeshExportSettings); } var bytes = gltf.ToGlbBytes(); File.WriteAllBytes(path, bytes); Debug.LogFormat("Export elapsed {0}", sw.Elapsed); if (path.StartsWithUnityAssetPath()) { // 出力ファイルのインポートを発動 AssetDatabase.ImportAsset(path.ToUnityRelativePath()); } }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <param name="settings"></param> /// <param name="destroy">作業が終わったらDestoryするべき一時オブジェクト</param> static void Export(string path, GameObject exportRoot, VRMExportSettings settings, List <GameObject> destroy) { var target = exportRoot; // 常にコピーする。シーンを変化させない target = GameObject.Instantiate(target); destroy.Add(target); { // copy元 var animator = exportRoot.GetComponent <Animator>(); var beforeTransforms = exportRoot.GetComponentsInChildren <Transform>(); // copy先 var afterTransforms = target.GetComponentsInChildren <Transform>(); // copy先のhumanoidBoneのリストを得る var bones = (HumanBodyBones[])Enum.GetValues(typeof(HumanBodyBones)); var humanTransforms = bones .Where(x => x != HumanBodyBones.LastBone) .Select(x => animator.GetBoneTransform(x)) .Where(x => x != null) .Select(x => afterTransforms[Array.IndexOf(beforeTransforms, x)]) // copy 先を得る .ToArray(); var nameCount = target.GetComponentsInChildren <Transform>() .GroupBy(x => x.name) .ToDictionary(x => x.Key, x => x.Count()); foreach (var t in target.GetComponentsInChildren <Transform>()) { if (humanTransforms.Contains(t)) { // keep original name continue; } if (nameCount[t.name] > 1) { // 重複するボーン名をリネームする ForceUniqueName(t, nameCount); } } } // 正規化 if (settings.PoseFreeze) { // BoneNormalizer.Execute は Copy を作って正規化する。UNDO無用 target = VRMBoneNormalizer.Execute(target, settings.ForceTPose, false); destroy.Add(target); } // 元のBlendShapeClipに変更を加えないように複製 var proxy = target.GetComponent <VRMBlendShapeProxy>(); if (proxy != null) { var copyBlendShapeAvatar = CopyBlendShapeAvatar(proxy.BlendShapeAvatar, settings.ReduceBlendshapeClip); proxy.BlendShapeAvatar = copyBlendShapeAvatar; // BlendShape削減 if (settings.ReduceBlendshape) { foreach (SkinnedMeshRenderer smr in target.GetComponentsInChildren <SkinnedMeshRenderer>()) { // 未使用のBlendShapeを間引く ReplaceMesh(target, smr, copyBlendShapeAvatar); } } } // 出力 { var sw = System.Diagnostics.Stopwatch.StartNew(); var vrm = VRMExporter.Export(target, new VRMExporterConfiguration { UseSparseAccessorForBlendShape = settings.UseSparseAccessor, ExportOnlyBlendShapePosition = settings.OnlyBlendshapePosition, RemoveVertexColor = settings.RemoveVertexColor }); // vrm.extensions.VRM.meta.title = settings.Title; // vrm.extensions.VRM.meta.version = settings.Version; // vrm.extensions.VRM.meta.author = settings.Author; // vrm.extensions.VRM.meta.contactInformation = settings.ContactInformation; // vrm.extensions.VRM.meta.reference = settings.Reference; var bytes = vrm.ToGlbBytes(settings.UseExperimentalExporter ? SerializerTypes.Generated : SerializerTypes.UniJSON); File.WriteAllBytes(path, bytes); Debug.LogFormat("Export elapsed {0}", sw.Elapsed); } if (path.StartsWithUnityAssetPath()) { // 出力ファイルのインポートを発動 AssetDatabase.ImportAsset(path.ToUnityRelativePath()); } }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <param name="settings"></param> /// <param name="destroy">作業が終わったらDestoryするべき一時オブジェクト</param> static byte[] Export(GameObject exportRoot, VRMMetaObject meta, VRMExportSettings settings, List <GameObject> destroy) { var target = exportRoot; // 常にコピーする。シーンを変化させない target = GameObject.Instantiate(target); destroy.Add(target); var metaBehaviour = target.GetComponent <VRMMeta>(); if (metaBehaviour == null) { metaBehaviour = target.AddComponent <VRMMeta>(); metaBehaviour.Meta = meta; } if (metaBehaviour.Meta == null) { // 来ないはず throw new Exception("meta required"); } { // copy元 var animator = exportRoot.GetComponent <Animator>(); var beforeTransforms = exportRoot.GetComponentsInChildren <Transform>(); // copy先 var afterTransforms = target.GetComponentsInChildren <Transform>(); // copy先のhumanoidBoneのリストを得る var bones = (HumanBodyBones[])Enum.GetValues(typeof(HumanBodyBones)); var humanTransforms = bones .Where(x => x != HumanBodyBones.LastBone) .Select(x => animator.GetBoneTransform(x)) .Where(x => x != null) .Select(x => afterTransforms[Array.IndexOf(beforeTransforms, x)]) // copy 先を得る .ToArray(); var nameCount = target.GetComponentsInChildren <Transform>() .GroupBy(x => x.name) .ToDictionary(x => x.Key, x => x.Count()); foreach (var t in target.GetComponentsInChildren <Transform>()) { if (humanTransforms.Contains(t)) { // keep original name continue; } if (nameCount[t.name] > 1) { // 重複するボーン名をリネームする ForceUniqueName(t, nameCount); } } } // 正規化 if (settings.PoseFreeze) { // BoneNormalizer.Execute は Copy を作って正規化する。UNDO無用 target = VRMBoneNormalizer.Execute(target, settings.ForceTPose); destroy.Add(target); } var fp = target.GetComponent <VRMFirstPerson>(); // 元のBlendShapeClipに変更を加えないように複製 var proxy = target.GetComponent <VRMBlendShapeProxy>(); if (proxy != null) { var copyBlendShapeAvatar = CopyBlendShapeAvatar(proxy.BlendShapeAvatar, settings.ReduceBlendshapeClip); proxy.BlendShapeAvatar = copyBlendShapeAvatar; // BlendShape削減 if (settings.ReduceBlendshape) { foreach (SkinnedMeshRenderer smr in target.GetComponentsInChildren <SkinnedMeshRenderer>()) { // 未使用のBlendShapeを間引く ReplaceMesh(target, smr, copyBlendShapeAvatar); } } } // 出力 var sw = System.Diagnostics.Stopwatch.StartNew(); var data = new UniGLTF.ExportingGltfData(); var gltfExportSettings = settings.GltfExportSettings; using (var exporter = new VRMExporter(data, gltfExportSettings, settings.KeepAnimation ? new EditorAnimationExporter() : null)) { exporter.Prepare(target); exporter.Export(new EditorTextureSerializer()); } var bytes = data.ToGlbBytes(); Debug.LogFormat("Export elapsed {0}", sw.Elapsed); return(bytes); }