public override void WriteDataXML(XElement ele, ElderScrollsPlugin master) { XElement subEle; if (EditorID != null) { ele.TryPathTo("EditorID", true, out subEle); EditorID.WriteXML(subEle, master); } if (Version != null) { ele.TryPathTo("Version", true, out subEle); Version.WriteXML(subEle, master); } if (GeneralData != null) { ele.TryPathTo("GeneralData", true, out subEle); GeneralData.WriteXML(subEle, master); } if (ActorBase != null) { ele.TryPathTo("ActorBase", true, out subEle); ActorBase.WriteXML(subEle, master); } if (BodyPartData != null) { ele.TryPathTo("BodyPartData", true, out subEle); BodyPartData.WriteXML(subEle, master); } if (FeedbackData != null) { ele.TryPathTo("FeedbackData", true, out subEle); FeedbackData.WriteXML(subEle, master); } if (DynamicBones != null) { ele.TryPathTo("DynamicBones", true, out subEle); DynamicBones.WriteXML(subEle, master); } if (PoseMatchingData != null) { ele.TryPathTo("PoseMatchingData", true, out subEle); PoseMatchingData.WriteXML(subEle, master); } if (DeathPose != null) { ele.TryPathTo("DeathPose", true, out subEle); DeathPose.WriteXML(subEle, master); } }
public override void WriteData(ESPWriter writer) { if (EditorID != null) { EditorID.WriteBinary(writer); } if (Version != null) { Version.WriteBinary(writer); } if (GeneralData != null) { GeneralData.WriteBinary(writer); } if (ActorBase != null) { ActorBase.WriteBinary(writer); } if (BodyPartData != null) { BodyPartData.WriteBinary(writer); } if (FeedbackData != null) { FeedbackData.WriteBinary(writer); } if (DynamicBones != null) { DynamicBones.WriteBinary(writer); } if (PoseMatchingData != null) { PoseMatchingData.WriteBinary(writer); } if (DeathPose != null) { DeathPose.WriteBinary(writer); } }
public override void ReadData(ESPReader reader, long dataEnd) { while (reader.BaseStream.Position < dataEnd) { string subTag = reader.PeekTag(); switch (subTag) { case "EDID": if (EditorID == null) { EditorID = new SimpleSubrecord <String>(); } EditorID.ReadBinary(reader); break; case "NVER": if (Version == null) { Version = new SimpleSubrecord <UInt32>(); } Version.ReadBinary(reader); break; case "DATA": if (GeneralData == null) { GeneralData = new RagdollData(); } GeneralData.ReadBinary(reader); break; case "XNAM": if (ActorBase == null) { ActorBase = new RecordReference(); } ActorBase.ReadBinary(reader); break; case "TNAM": if (BodyPartData == null) { BodyPartData = new RecordReference(); } BodyPartData.ReadBinary(reader); break; case "RAFD": if (FeedbackData == null) { FeedbackData = new RagdollFeedbackData(); } FeedbackData.ReadBinary(reader); break; case "RAFB": if (DynamicBones == null) { DynamicBones = new RagdollDynamicBones(); } DynamicBones.ReadBinary(reader); break; case "RAPS": if (PoseMatchingData == null) { PoseMatchingData = new RagdollPoseMatching(); } PoseMatchingData.ReadBinary(reader); break; case "ANAM": if (DeathPose == null) { DeathPose = new SimpleSubrecord <String>(); } DeathPose.ReadBinary(reader); break; default: throw new Exception(); } } }
public override void ReadDataXML(XElement ele, ElderScrollsPlugin master) { XElement subEle; if (ele.TryPathTo("EditorID", false, out subEle)) { if (EditorID == null) { EditorID = new SimpleSubrecord <String>(); } EditorID.ReadXML(subEle, master); } if (ele.TryPathTo("Version", false, out subEle)) { if (Version == null) { Version = new SimpleSubrecord <UInt32>(); } Version.ReadXML(subEle, master); } if (ele.TryPathTo("GeneralData", false, out subEle)) { if (GeneralData == null) { GeneralData = new RagdollData(); } GeneralData.ReadXML(subEle, master); } if (ele.TryPathTo("ActorBase", false, out subEle)) { if (ActorBase == null) { ActorBase = new RecordReference(); } ActorBase.ReadXML(subEle, master); } if (ele.TryPathTo("BodyPartData", false, out subEle)) { if (BodyPartData == null) { BodyPartData = new RecordReference(); } BodyPartData.ReadXML(subEle, master); } if (ele.TryPathTo("FeedbackData", false, out subEle)) { if (FeedbackData == null) { FeedbackData = new RagdollFeedbackData(); } FeedbackData.ReadXML(subEle, master); } if (ele.TryPathTo("DynamicBones", false, out subEle)) { if (DynamicBones == null) { DynamicBones = new RagdollDynamicBones(); } DynamicBones.ReadXML(subEle, master); } if (ele.TryPathTo("PoseMatchingData", false, out subEle)) { if (PoseMatchingData == null) { PoseMatchingData = new RagdollPoseMatching(); } PoseMatchingData.ReadXML(subEle, master); } if (ele.TryPathTo("DeathPose", false, out subEle)) { if (DeathPose == null) { DeathPose = new SimpleSubrecord <String>(); } DeathPose.ReadXML(subEle, master); } }
/// <summary> /// VRChatアバターインスタンスからVRMインスタンスへ変換します。 /// </summary> /// <param name="instance">ヒエラルキー上のGameObject。</param> /// <param name="presetVRChatBindingPairs">各表情への割り当て。</param> internal static void Convert( string outputPath, GameObject instance, VRMMetaObject meta, IDictionary <ExpressionPreset, VRChatExpressionBinding> presetVRChatBindingPairs ) { GameObject clone = null, normalized = null; try { var rootObjectName = instance.name; clone = Object.Instantiate(instance); // 非表示のオブジェクト・コンポーネントを削除 // TODO: アクティブ・非アクティブの切り替えをシェイプキーに変換する VRChatToVRMConverter.RemoveInactiveObjectsAndDisabledComponents(clone); // 表情とシェイプキー名の組み合わせを取得 var presetShapeKeyNameWeightPairsPairs = presetVRChatBindingPairs.ToDictionary( presetVRChatBindingPair => presetVRChatBindingPair.Key, presetVRChatBindingPair => VRChatExpressionsReplacer.ExtractShapeKeyNames(presetVRChatBindingPair.Value) ); // VRM設定1 var temporaryFolder = UnityPath.FromUnityPath(VRChatToVRMConverter.TemporaryFolderPath); temporaryFolder.EnsureFolder(); var temporaryPrefabPath = temporaryFolder.Child(VRChatToVRMConverter.TemporaryPrefabFileName).Value; VRMInitializer.Initialize(temporaryPrefabPath, clone); VRChatToVRMConverter.SetFirstPersonOffset(clone); VRChatToVRMConverter.SetLookAtBoneApplyer(clone); var sourceAndDestination = clone.GetComponent <Animator>(); if (DynamicBones.IsImported()) { DynamicBonesToVRMSpringBonesConverter.Convert( source: sourceAndDestination, destination: sourceAndDestination ); VRChatToVRMConverter.RemoveUnusedColliderGroups(clone); } // 正規化 normalized = VRMBoneNormalizer.Execute(clone, forceTPose: true); // 全メッシュ結合 var combinedRenderer = CombineMeshesAndSubMeshes.Combine( normalized, notCombineRendererObjectNames: new List <string>(), destinationObjectName: "vrm-mesh", savingAsAsset: false ); // 使用していないシェイプキーの削除 SkinnedMeshUtility.CleanUpShapeKeys(combinedRenderer.sharedMesh, presetShapeKeyNameWeightPairsPairs .SelectMany(presetShapeKeyNameWeightPairsPair => presetShapeKeyNameWeightPairsPair.Value.Keys) .Distinct()); // シェイプキーの分離 Utilities.MeshUtility.SeparationProcessing(normalized); // マテリアルの設定・アセットとして保存 VRChatToVRMConverter.ReplaceShaders(normalized, temporaryPrefabPath); // GameObject・メッシュなどをアセットとして保存 (アセットとして存在しないと正常にエクスポートできない) normalized.name = rootObjectName; var animator = normalized.GetComponent <Animator>(); animator.avatar = Duplicator.CreateObjectToFolder(animator.avatar, temporaryPrefabPath); meta.name = "Meta"; normalized.GetComponent <VRMMeta>().Meta = Duplicator.CreateObjectToFolder(meta, temporaryPrefabPath); foreach (var renderer in normalized.GetComponentsInChildren <SkinnedMeshRenderer>()) { renderer.sharedMesh.name = renderer.name; renderer.sharedMesh = Duplicator.CreateObjectToFolder(renderer.sharedMesh, temporaryPrefabPath); } // VRM設定2 VRChatToVRMConverter.SetFirstPersonRenderers(normalized); // 表情の設定 VRChatExpressionsReplacer.SetExpressions(normalized, presetShapeKeyNameWeightPairsPairs); var prefab = PrefabUtility .SaveAsPrefabAssetAndConnect(normalized, temporaryPrefabPath, InteractionMode.AutomatedAction); // エクスポート AssetDatabase.SaveAssets(); File.WriteAllBytes( outputPath, VRMEditorExporter.Export(prefab, meta: null, ScriptableObject.CreateInstance <VRMExportSettings>()) ); } catch (Exception exception) { ErrorDialog.Open(exception); throw; } finally { if (clone != null) { Object.DestroyImmediate(clone); } if (normalized != null) { Object.DestroyImmediate(normalized); } AssetDatabase.DeleteAsset("Assets/VRMConverterTemporary"); } }