Compare commits
1 Commits
Decompile
...
0d54b7056c
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d54b7056c |
@@ -1,49 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!1 &7464217327116044082
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 8068461331216787135}
|
|
||||||
- component: {fileID: 6752720059844632398}
|
|
||||||
m_Layer: 0
|
|
||||||
m_Name: EdenAUtoMorpher_ProfileSaver
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!4 &8068461331216787135
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 7464217327116044082}
|
|
||||||
serializedVersion: 2
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 0}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
--- !u!114 &6752720059844632398
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 7464217327116044082}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: 2fd1a8210b48a8d49843a3f2859e67b6, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
sourceAvatar: {fileID: 0}
|
|
||||||
sourceBodyMeshes: []
|
|
||||||
profileName:
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!1 &1593401673962086623
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 1906542585506803867}
|
|
||||||
- component: {fileID: 2852885081601766632}
|
|
||||||
m_Layer: 0
|
|
||||||
m_Name: EdenAutoMorpher
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!4 &1906542585506803867
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1593401673962086623}
|
|
||||||
serializedVersion: 2
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 0}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
--- !u!114 &2852885081601766632
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1593401673962086623}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: 50552370e41d31140a52da99bcc7ab74, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
sourceAvatarObject: {fileID: 0}
|
|
||||||
sourceClothesObject: {fileID: 0}
|
|
||||||
sourceBodyMeshes: []
|
|
||||||
profileName: Milfy
|
|
||||||
targetAvatarObject: {fileID: 0}
|
|
||||||
targetClothesObject: {fileID: 0}
|
|
||||||
targetClothesObjectOriginal: {fileID: 0}
|
|
||||||
targetBodyMeshes: []
|
|
||||||
minMargin: 0.003
|
|
||||||
worldRadius: 0.1
|
|
||||||
sigma: 0.85
|
|
||||||
smoothingIteration: 1
|
|
||||||
fittingExpandIteration: 10
|
|
||||||
fittingShrinkIteration: 12
|
|
||||||
isBodyAutoSetup: 1
|
|
||||||
isReparentAccessoryBonesToTargetAvatar: 1
|
|
||||||
skipFootFitting: 0
|
|
||||||
transferWeightToAvatar: 0
|
|
||||||
addAnchorBone: 1
|
|
||||||
armatureBoneScaleCopy: 0
|
|
||||||
isRemoveAutoMorphedClothes: 1
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,
|
|
||||||
// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.
|
|
||||||
// EdenAutoMorpherEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.AutoMorpherLogCollector
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class AutoMorpherLogCollector
|
|
||||||
{
|
|
||||||
private struct LogEntry
|
|
||||||
{
|
|
||||||
public DateTime utcTime;
|
|
||||||
|
|
||||||
public LogType type;
|
|
||||||
|
|
||||||
public string condition;
|
|
||||||
|
|
||||||
public string stackTrace;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _isCapturing;
|
|
||||||
|
|
||||||
private DateTime _captureStartUtc;
|
|
||||||
|
|
||||||
private readonly List<LogEntry> _entries = new List<LogEntry>(2048);
|
|
||||||
|
|
||||||
private int entriesCapacity = 5000;
|
|
||||||
|
|
||||||
private const string logSavePath = "Assets/@Eden_Tools/Eden_AutoMorpher/Logs";
|
|
||||||
|
|
||||||
public void BeginCapture()
|
|
||||||
{
|
|
||||||
if (!this._isCapturing)
|
|
||||||
{
|
|
||||||
this._isCapturing = true;
|
|
||||||
this._entries.Clear();
|
|
||||||
this._captureStartUtc = DateTime.UtcNow;
|
|
||||||
Application.logMessageReceived += this.OnLogMessageReceived;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EndCapture()
|
|
||||||
{
|
|
||||||
if (this._isCapturing)
|
|
||||||
{
|
|
||||||
this._isCapturing = false;
|
|
||||||
Application.logMessageReceived -= this.OnLogMessageReceived;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string SaveToTextFile(string defaultFileName, bool includeWarningsAndInfo)
|
|
||||||
{
|
|
||||||
this.EnsureLogDirectoryExists();
|
|
||||||
string text = defaultFileName;
|
|
||||||
if (string.IsNullOrEmpty(text))
|
|
||||||
{
|
|
||||||
text = "EdenAutoMorpher_Report.txt";
|
|
||||||
}
|
|
||||||
if (!text.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
text += ".txt";
|
|
||||||
}
|
|
||||||
string text2 = Path.Combine("Assets/@Eden_Tools/Eden_AutoMorpher/Logs", text);
|
|
||||||
string contents = this.BuildReportText(includeWarningsAndInfo);
|
|
||||||
File.WriteAllText(text2, contents, Encoding.UTF8);
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
Debug.Log("[AutoMorpher] Log report saved: " + text2);
|
|
||||||
return text2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureLogDirectoryExists()
|
|
||||||
{
|
|
||||||
if (AssetDatabase.IsValidFolder("Assets/@Eden_Tools/Eden_AutoMorpher/Logs"))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
string[] array = "Assets/@Eden_Tools/Eden_AutoMorpher/Logs".Split('/', StringSplitOptions.None);
|
|
||||||
string text = array[0];
|
|
||||||
for (int i = 1; i < array.Length; i++)
|
|
||||||
{
|
|
||||||
string text2 = text + "/" + array[i];
|
|
||||||
if (!AssetDatabase.IsValidFolder(text2))
|
|
||||||
{
|
|
||||||
AssetDatabase.CreateFolder(text, array[i]);
|
|
||||||
}
|
|
||||||
text = text2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string BuildReportText(bool includeWarningsAndInfo)
|
|
||||||
{
|
|
||||||
StringBuilder stringBuilder = new StringBuilder(65536);
|
|
||||||
stringBuilder.AppendLine("==== EDEN AUTO MORPHER LOG REPORT ====");
|
|
||||||
stringBuilder.AppendLine($"Captured (UTC) : {this._captureStartUtc:yyyy-MM-dd HH:mm:ss} ~ {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}");
|
|
||||||
stringBuilder.AppendLine("Unity Version : " + Application.unityVersion);
|
|
||||||
stringBuilder.AppendLine($"Platform : {Application.platform}");
|
|
||||||
stringBuilder.AppendLine("Project : " + Application.productName);
|
|
||||||
stringBuilder.AppendLine();
|
|
||||||
stringBuilder.AppendLine("---- Logs ----");
|
|
||||||
for (int i = 0; i < this._entries.Count; i++)
|
|
||||||
{
|
|
||||||
LogEntry logEntry = this._entries[i];
|
|
||||||
if (includeWarningsAndInfo || logEntry.type == LogType.Error || logEntry.type == LogType.Assert || logEntry.type == LogType.Exception)
|
|
||||||
{
|
|
||||||
stringBuilder.AppendLine($"[{i:0000}] - [{logEntry.type}] | {logEntry.utcTime:HH:mm:ss.fff} UTC");
|
|
||||||
stringBuilder.AppendLine(logEntry.condition ?? string.Empty);
|
|
||||||
if (!string.IsNullOrEmpty(logEntry.stackTrace))
|
|
||||||
{
|
|
||||||
stringBuilder.AppendLine("Details:");
|
|
||||||
stringBuilder.AppendLine(logEntry.stackTrace);
|
|
||||||
}
|
|
||||||
stringBuilder.AppendLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stringBuilder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLogMessageReceived(string condition, string stackTrace, LogType type)
|
|
||||||
{
|
|
||||||
if (this._isCapturing)
|
|
||||||
{
|
|
||||||
this._entries.Add(new LogEntry
|
|
||||||
{
|
|
||||||
utcTime = DateTime.UtcNow,
|
|
||||||
type = type,
|
|
||||||
condition = condition,
|
|
||||||
stackTrace = stackTrace
|
|
||||||
});
|
|
||||||
if (this._entries.Count > this.entriesCapacity)
|
|
||||||
{
|
|
||||||
this._entries.RemoveRange(0, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 48dbd59641bef954eb938512667a41d1
|
|
||||||
@@ -1,304 +0,0 @@
|
|||||||
// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,
|
|
||||||
// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.
|
|
||||||
// EdenAutoMorpherEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.AutoMorpherValidator
|
|
||||||
using Eden.AutoMorpher;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class AutoMorpherValidator
|
|
||||||
{
|
|
||||||
public bool ValidateAutoModeObjects(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, out string errorMessage)
|
|
||||||
{
|
|
||||||
return this.ValidateAutoModeObjects_Internal(sourceAvatar, sourceClothes, targetAvatar, out errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ValidateManualMode_AutoSetup_Objects(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, out string errorMessage)
|
|
||||||
{
|
|
||||||
return this.ValidateManualMode_AutoSetup_Objects_Internal(sourceAvatar, sourceClothes, targetAvatar, out errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ValidateManualModeObjects(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, GameObject targetClothes, out string errorMessage)
|
|
||||||
{
|
|
||||||
return this.ValidateManualModeObjects_Internal(sourceAvatar, sourceClothes, targetAvatar, targetClothes, out errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ValidateProfileModeObjects(GameObject sourceClothes, GameObject targetAvatar, out string errorMessage)
|
|
||||||
{
|
|
||||||
return this.ValidateProfileModeObjects_Internal(sourceClothes, targetAvatar, out errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ValidateAutoModeObjects_Internal(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, out string errorMessage)
|
|
||||||
{
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
this.ObjectNullCheck(stringBuilder, (sourceAvatar, "- Source Avatar Object"), (sourceClothes, "- Source Clothes Object"), (targetAvatar, "- Target Avatar Object"));
|
|
||||||
if (sourceClothes != null)
|
|
||||||
{
|
|
||||||
this.ClothesChildCheck(stringBuilder, sourceAvatar, sourceClothes, LanguageManager.Get("UI.Validator.SourceClothesChildCheck"));
|
|
||||||
this.HasSMRInClothes(stringBuilder, sourceClothes, "ClothesObject - There is No SkinnedMeshRenderer");
|
|
||||||
this.HasLocalArmature(stringBuilder, sourceClothes, "Source " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck"));
|
|
||||||
}
|
|
||||||
if (sourceAvatar != null)
|
|
||||||
{
|
|
||||||
this.IsHumanoid(stringBuilder, sourceAvatar, LanguageManager.Get("UI.Validator.SourceAvatarAnimatorCheck"));
|
|
||||||
}
|
|
||||||
if (targetAvatar != null)
|
|
||||||
{
|
|
||||||
this.IsHumanoid(stringBuilder, targetAvatar, LanguageManager.Get("UI.Validator.TargetAvatarAnimatorCheck"));
|
|
||||||
}
|
|
||||||
if (stringBuilder.Length == 0)
|
|
||||||
{
|
|
||||||
errorMessage = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
errorMessage = "Auto Mode: " + LanguageManager.Get("UI.Validator.Can'tFitting") + stringBuilder.ToString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ValidateProfileModeObjects_Internal(GameObject sourceClothes, GameObject targetAvatar, out string errorMessage)
|
|
||||||
{
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
this.ObjectNullCheck(stringBuilder, (sourceClothes, "- Source Clothes Object"), (targetAvatar, "- Target Avatar Object"));
|
|
||||||
if (sourceClothes != null)
|
|
||||||
{
|
|
||||||
this.HasSMRInClothes(stringBuilder, sourceClothes, "ClothesObject - There is No SkinnedMeshRenderer");
|
|
||||||
this.HasLocalArmature(stringBuilder, sourceClothes, "Source " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck"));
|
|
||||||
}
|
|
||||||
if (targetAvatar != null)
|
|
||||||
{
|
|
||||||
this.IsHumanoid(stringBuilder, targetAvatar, LanguageManager.Get("UI.Validator.TargetAvatarAnimatorCheck"));
|
|
||||||
}
|
|
||||||
if (stringBuilder.Length == 0)
|
|
||||||
{
|
|
||||||
errorMessage = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
errorMessage = "Profile Mode: " + LanguageManager.Get("UI.Validator.Can'tFitting") + stringBuilder.ToString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ValidateManualMode_AutoSetup_Objects_Internal(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, out string errorMessage)
|
|
||||||
{
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
this.ObjectNullCheck(stringBuilder, (sourceAvatar, "- Source Avatar Object"), (sourceClothes, "- Source Clothes Object"), (targetAvatar, "- Target Avatar Object"));
|
|
||||||
if (sourceClothes != null)
|
|
||||||
{
|
|
||||||
this.ClothesChildCheck(stringBuilder, sourceAvatar, sourceClothes, LanguageManager.Get("UI.Validator.SourceClothesChildCheck"));
|
|
||||||
this.HasSMRInClothes(stringBuilder, sourceClothes, "ClothesObject - There is No SkinnedMeshRenderer");
|
|
||||||
this.HasLocalArmature(stringBuilder, sourceClothes, "Source " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck"));
|
|
||||||
}
|
|
||||||
if (sourceAvatar != null)
|
|
||||||
{
|
|
||||||
this.IsHumanoid(stringBuilder, sourceAvatar, LanguageManager.Get("UI.Validator.SourceAvatarAnimatorCheck"));
|
|
||||||
}
|
|
||||||
if (targetAvatar != null)
|
|
||||||
{
|
|
||||||
this.IsHumanoid(stringBuilder, targetAvatar, LanguageManager.Get("UI.Validator.TargetAvatarAnimatorCheck"));
|
|
||||||
}
|
|
||||||
if (stringBuilder.Length == 0)
|
|
||||||
{
|
|
||||||
errorMessage = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
errorMessage = "Manual Mode - Auto Setup: " + LanguageManager.Get("UI.Validator.Can'tFitting") + stringBuilder.ToString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ValidateManualModeObjects_Internal(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, GameObject targetClothes, out string errorMessage)
|
|
||||||
{
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
this.ObjectNullCheck(stringBuilder, (sourceAvatar, "- Source Avatar Object"), (sourceClothes, "- Source Clothes Object"), (targetAvatar, "- Target Avatar Object"), (targetClothes, "- Target Clothes Object"));
|
|
||||||
if (sourceClothes != null)
|
|
||||||
{
|
|
||||||
this.ClothesChildCheck(stringBuilder, sourceAvatar, sourceClothes, LanguageManager.Get("UI.Validator.SourceClothesChildCheck"));
|
|
||||||
this.HasSMRInClothes(stringBuilder, sourceClothes, "ClothesObject - There is No SkinnedMeshRenderer");
|
|
||||||
this.HasLocalArmature(stringBuilder, sourceClothes, "Source " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck"));
|
|
||||||
}
|
|
||||||
if (targetClothes != null)
|
|
||||||
{
|
|
||||||
this.ClothesChildCheck(stringBuilder, targetAvatar, targetClothes, LanguageManager.Get("UI.Validator.TargetClothesChildCheck"));
|
|
||||||
this.HasSMRInClothes(stringBuilder, targetClothes, "ClothesObject - There is No SkinnedMeshRenderer");
|
|
||||||
this.HasLocalArmature(stringBuilder, targetClothes, "Target " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck"));
|
|
||||||
}
|
|
||||||
if (sourceAvatar != null)
|
|
||||||
{
|
|
||||||
this.IsHumanoid(stringBuilder, sourceAvatar, LanguageManager.Get("UI.Validator.SourceAvatarAnimatorCheck"));
|
|
||||||
}
|
|
||||||
if (targetAvatar != null)
|
|
||||||
{
|
|
||||||
this.IsHumanoid(stringBuilder, targetAvatar, LanguageManager.Get("UI.Validator.TargetAvatarAnimatorCheck"));
|
|
||||||
}
|
|
||||||
if (sourceClothes != null && targetClothes != null)
|
|
||||||
{
|
|
||||||
this.AppendSmrAndVertexCheck(stringBuilder, sourceClothes, targetClothes);
|
|
||||||
}
|
|
||||||
if (stringBuilder.Length == 0)
|
|
||||||
{
|
|
||||||
errorMessage = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
errorMessage = "Manual Mode: " + LanguageManager.Get("UI.Validator.Can'tFitting") + stringBuilder.ToString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ObjectNullCheck(StringBuilder sb, params (GameObject obj, string label)[] refs)
|
|
||||||
{
|
|
||||||
bool flag = false;
|
|
||||||
for (int i = 0; i < refs.Length; i++)
|
|
||||||
{
|
|
||||||
if (refs[i].obj == null)
|
|
||||||
{
|
|
||||||
flag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!flag)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sb.AppendLine(LanguageManager.Get("UI.Validator.ReferenceCheck"));
|
|
||||||
for (int j = 0; j < refs.Length; j++)
|
|
||||||
{
|
|
||||||
if (refs[j].obj == null)
|
|
||||||
{
|
|
||||||
sb.AppendLine(refs[j].label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClothesChildCheck(StringBuilder sb, GameObject parentObject, GameObject childObject, string messageOnInvalid)
|
|
||||||
{
|
|
||||||
if (!(childObject == null) && (parentObject == null || !childObject.transform.IsChildOf(parentObject.transform)))
|
|
||||||
{
|
|
||||||
if (sb.Length > 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
sb.AppendLine(messageOnInvalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HasSMRInClothes(StringBuilder sb, GameObject clothesRoot, string messageOnInvalid)
|
|
||||||
{
|
|
||||||
if (clothesRoot == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SkinnedMeshRenderer[] componentsInChildren = clothesRoot.GetComponentsInChildren<SkinnedMeshRenderer>(includeInactive: true);
|
|
||||||
if (componentsInChildren == null || componentsInChildren.Length == 0)
|
|
||||||
{
|
|
||||||
if (sb.Length > 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
sb.AppendLine(messageOnInvalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HasLocalArmature(StringBuilder sb, GameObject clothesRoot, string messageOnInvalid)
|
|
||||||
{
|
|
||||||
if (clothesRoot == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SkinnedMeshRenderer[] componentsInChildren = clothesRoot.GetComponentsInChildren<SkinnedMeshRenderer>(includeInactive: true);
|
|
||||||
if (componentsInChildren == null || componentsInChildren.Length == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Transform transform = clothesRoot.transform;
|
|
||||||
bool flag = true;
|
|
||||||
SkinnedMeshRenderer[] array = componentsInChildren;
|
|
||||||
for (int i = 0; i < array.Length; i++)
|
|
||||||
{
|
|
||||||
Transform[] bones = array[i].bones;
|
|
||||||
if (bones == null || bones.Length == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Transform[] array2 = bones;
|
|
||||||
foreach (Transform transform2 in array2)
|
|
||||||
{
|
|
||||||
if (!(transform2 == null) && !transform2.transform.IsChildOf(transform))
|
|
||||||
{
|
|
||||||
flag = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!flag)
|
|
||||||
{
|
|
||||||
if (sb.Length > 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
sb.AppendLine(messageOnInvalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsHumanoid(StringBuilder sb, GameObject avatarObject, string messageOnInvalid)
|
|
||||||
{
|
|
||||||
if (avatarObject == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Animator component = avatarObject.GetComponent<Animator>();
|
|
||||||
if (component == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (component.avatar == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!component.avatar.isHuman)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AppendSmrAndVertexCheck(StringBuilder sb, GameObject sourceClothes, GameObject targetClothes)
|
|
||||||
{
|
|
||||||
if (sourceClothes == null || targetClothes == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SkinnedMeshRenderer[] componentsInChildren = sourceClothes.GetComponentsInChildren<SkinnedMeshRenderer>(includeInactive: true);
|
|
||||||
SkinnedMeshRenderer[] componentsInChildren2 = targetClothes.GetComponentsInChildren<SkinnedMeshRenderer>(includeInactive: true);
|
|
||||||
int num = ((componentsInChildren != null) ? componentsInChildren.Length : 0);
|
|
||||||
int num2 = ((componentsInChildren2 != null) ? componentsInChildren2.Length : 0);
|
|
||||||
if (num != num2)
|
|
||||||
{
|
|
||||||
if (sb.Length > 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
sb.AppendLine(LanguageManager.Get("UI.Validator.CheckRendererCountCheck"));
|
|
||||||
sb.AppendLine($"- Source Clothes SMR : {num}");
|
|
||||||
sb.AppendLine($"- Target Clothes SMR : {num2}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < num; i++)
|
|
||||||
{
|
|
||||||
SkinnedMeshRenderer skinnedMeshRenderer = componentsInChildren[i];
|
|
||||||
SkinnedMeshRenderer skinnedMeshRenderer2 = componentsInChildren2[i];
|
|
||||||
if (skinnedMeshRenderer == null || skinnedMeshRenderer2 == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Mesh sharedMesh = skinnedMeshRenderer.sharedMesh;
|
|
||||||
Mesh sharedMesh2 = skinnedMeshRenderer2.sharedMesh;
|
|
||||||
if (!(sharedMesh == null) && !(sharedMesh2 == null) && sharedMesh.vertexCount != sharedMesh2.vertexCount)
|
|
||||||
{
|
|
||||||
if (sb.Length > 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
sb.AppendLine(LanguageManager.Get("UI.Validator.VertexCountCheck"));
|
|
||||||
sb.AppendLine($"- Source: {skinnedMeshRenderer.name} (vertices: {sharedMesh.vertexCount})");
|
|
||||||
sb.AppendLine($"- Target: {skinnedMeshRenderer2.name} (vertices: {sharedMesh2.vertexCount})");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 367e223b416de1d4d92bdcaee21b1df7
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2a5cebf384008fb4fa1e1141a4845238
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,
|
|
||||||
// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.
|
|
||||||
// EdenAutoMorpherEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.ResultInfo
|
|
||||||
public class ResultInfo
|
|
||||||
{
|
|
||||||
public bool isComplicated;
|
|
||||||
|
|
||||||
public string processTyep = "";
|
|
||||||
|
|
||||||
public string processEndState = "";
|
|
||||||
|
|
||||||
public string processTime = "";
|
|
||||||
|
|
||||||
public string errorMessage = "";
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 45a0e5ffc6837dc48b871f340e85e7a4
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f3c01fc12e499944da78f3441a00f36a
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
{
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.AutoFitting",
|
|
||||||
"value": "Auto Fitting Mode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ManualFitting",
|
|
||||||
"value": "Manual Fitting Mode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ProfileFitting",
|
|
||||||
"value": "Profile Mode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "Error.BodyMesh.NotFound",
|
|
||||||
"value": "Failed to find Body Mesh."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "Error.KeyNotFound",
|
|
||||||
"value": "[EN] Could not find key: {0}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ManualFittingGuide",
|
|
||||||
"value": "Manual Setting Mode\n1. Assign the Objects and Meshes for the Source / Target Avatars.\n2. Adjust the target clothes object (Target Clothes Object) to match the target avatar.\n3. Press [Run Fitting] to start the fitting.\n4. Press [Run Weighting] to start weight assignment."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.AutoFittingGuide",
|
|
||||||
"value": "Auto Setting Mode\n1. Assign the Source avatar body and clothing objects to the Source Avatar.\n2. Assign the target avatar body to the Target Avatar.\n3. Press [Run Fitting] to begin fitting.\n4. Press [Run Weighting] to start weight assignment."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.MinMarginInfo",
|
|
||||||
"value": "If the clothes stick too closely to the body, increase the MinMargin value. (Default: 0.003)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SkipFootFittingInfo",
|
|
||||||
"value": "Check this option to disable foot-based shape corrections during the fitting stage."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.BodyMeshTitle",
|
|
||||||
"value": "Automatically Assign Body Mesh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.BodyMeshInfo",
|
|
||||||
"value": "If the body mesh cannot be detected automatically, \nplease manually assign the mesh corresponding to the body (excluding the head) to Body Meshes."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SigmaInfo",
|
|
||||||
"value": "Increasing this value makes a wider area of the clothing deform smoothly together. (Default: 0.85)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SmoothingInfo",
|
|
||||||
"value": "Increasing this value applies the Smooth effect more strongly, making the deformation smoother. (Default: 1)\n - Higher values will increase computation time."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.IterationInfo",
|
|
||||||
"value": "If you want more deformation for the clothes, increase the number of fitting iterations."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.ReparentAccessoryBones",
|
|
||||||
"value": "Moves and places accessory bones into the target avatar’s armature during weighting."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.ReferenceCheck",
|
|
||||||
"value": "The following items must all be assigned:"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.SourceClothesChildCheck",
|
|
||||||
"value": "The Source Clothes Object must be a child of the Source Avatar Object.\n→ Please place the clothes under the Source Avatar object."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.TargetClothesChildCheck",
|
|
||||||
"value": "The Target Clothes Object must be a child of the Target Avatar Object.\n→ Please place the clothes under the Target Avatar object."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.ClothesArmatureCheck",
|
|
||||||
"value": "Clothes Object - The Bone Armature referenced by the SkinnedMeshRenderer is not correctly included in the Clothes Object."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.SourceAvatarAnimatorCheck",
|
|
||||||
"value": "The Source Avatar Object does not have a Humanoid Avatar assigned.\n→ Please check the Animator component and Avatar settings."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.TargetAvatarAnimatorCheck",
|
|
||||||
"value": "The Target Avatar Object does not have a Humanoid Avatar assigned.\n→ Please check the Animator component and Avatar settings."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.CheckRendererCountCheck",
|
|
||||||
"value": "The number of SkinnedMeshRenderers in the Source / Target Clothes does not match."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.VertexCountCheck",
|
|
||||||
"value": "The vertex count of the corresponding SkinnedMeshRenderer meshes does not match."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.Can'tFitting",
|
|
||||||
"value": "Unable to run\n\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyProxyNull",
|
|
||||||
"value": "Body Proxy Null Error"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyProxyNull",
|
|
||||||
"value": "Failed to assign the Body Proxy.\nPlease make sure the Source Avatar is correctly assigned and the bones are properly set in the Animator."
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.SourceBodyMeshNull",
|
|
||||||
"value": "Source Body Mesh Not Found"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.SourceBodyMeshNull",
|
|
||||||
"value": "Could not find the Source Body Mesh."
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.TargetBodyMeshNull",
|
|
||||||
"value": "Target Body Mesh Not Found"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.TargetBodyMeshNull",
|
|
||||||
"value": "Could not find the Target Body Mesh."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyMeshNull",
|
|
||||||
"value": "BodyMesh Search Failed"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyMeshNull",
|
|
||||||
"value": "The BodyMesh of [{0}] could not be found."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.TargetRendererNull",
|
|
||||||
"value": "Target Renderer Null Error"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.TargetRendererNull",
|
|
||||||
"value": "targetRenderers contains one or more null elements."
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.ClothInstanceAllocateFail",
|
|
||||||
"value": "ClothInstance Allocation Failed"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.ClothInstanceAllocateFail",
|
|
||||||
"value": "No ClothInstance could be allocated.\nPlease check if the clothes have a SkinnedMeshRenderer."
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.WeightingNotReady",
|
|
||||||
"value": "Weighting Is Not Ready"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.WeightingNotReady",
|
|
||||||
"value": "Fitting has not finished before calling WeightingEnumerator, or the Target Avatar has been changed.\nPlease run Run Fitting again."
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyBVHFail",
|
|
||||||
"value": "Body BVH Creation Failed"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyBVHFail",
|
|
||||||
"value": "Failed to build BVH for {0}.\nbvhMesh is Null : {1}\nbvhMesh triangles is Null : {2}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Guide",
|
|
||||||
"value": "This section is for generating Profile data.\nPlease set the avatar Scale to 1,1,1.\nAdjust ShapeKeys so that the avatar BodyMesh is not occluded."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.ProfileName.Tooltip",
|
|
||||||
"value": "Name of the Profile to be saved"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.SourceAvatar.Tooltip",
|
|
||||||
"value": "Avatar root Transform with Humanoid Rig and Animator configured"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.SourceBodyMeshes.Tooltip",
|
|
||||||
"value": "List of body SkinnedMeshRenderers used for Profile generation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.ProfileNameEmpty",
|
|
||||||
"value": "Profile Name is empty."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceAvatarNull",
|
|
||||||
"value": "Source Avatar is not assigned."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceAvatarAnimatorMissing",
|
|
||||||
"value": "Source Avatar does not have an Animator."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceBodyMeshesEmpty",
|
|
||||||
"value": "Source Body Meshes is empty."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceBodyMeshesContainNull",
|
|
||||||
"value": "Source Body Meshes contains NULL."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.BodyMeshNotChildOfAvatar",
|
|
||||||
"value": "Source Body Meshes must be children of the Source Avatar."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.BaseDataMissing",
|
|
||||||
"value": "No Base file exists in the BaseData folder."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0aa9f12300a0596408771775b2d5148e
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
{
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.AutoFitting",
|
|
||||||
"value": "自動セットアップモード"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ManualFitting",
|
|
||||||
"value": "手動セットアップモード"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ProfileFitting",
|
|
||||||
"value": "プロファイルモード"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "Error.BodyMesh.NotFound",
|
|
||||||
"value": "Body Mesh を見つけられませんでした。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "Error.KeyNotFound",
|
|
||||||
"value": "[JP] キーが見つかりません: {0}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ManualFittingGuide",
|
|
||||||
"value": "手動セットアップモード\n1. Source / Target Avatar に対応するオブジェクトとメッシュを割り当ててください。\n2. 対応する衣装(Target Clothes Object)をターゲットアバターに合わせて調整してください。\n3. [Run Fitting] を押してフィッティングを開始してください。\n4. [Run Weighting] を押してウェイト割り当てを開始してください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.AutoFittingGuide",
|
|
||||||
"value": "自動セットアップモード\n1. Source Avatar にソースアバターのボディと衣装オブジェクトを割り当ててください。\n2. Target Avatar にターゲットアバターのボディを割り当ててください。\n3. [Run Fitting] を押してフィッティングを開始してください。\n4. [Run Weighting] を押してウェイト割り当てを開始してください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.MinMarginInfo",
|
|
||||||
"value": "衣装が体に密着しすぎる場合は、MinMarginの値を大きくしてください。(初期値: 0.003)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SkipFootFittingInfo",
|
|
||||||
"value": "Fitting工程において、足(foot)を基準とした形状補正を適用しない場合はチェックしてください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.BodyMeshTitle",
|
|
||||||
"value": "ボディメッシュを自動で割り当てる"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.BodyMeshInfo",
|
|
||||||
"value": "ボディメッシュを自動で検出できない場合は、\n(頭部を除く)ボディに該当するメッシュを Body Meshes に手動で割り当ててください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SigmaInfo",
|
|
||||||
"value": "値を上げるほど、衣装のより広い範囲が一緒に滑らかに変形します。(初期値:0.85)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SmoothingInfo",
|
|
||||||
"value": "値を上げるほど、Smooth効果がより強く適用され、変形がより滑らかになります。(初期値:1)\n - 値を上げると処理時間が長くなります。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.IterationInfo",
|
|
||||||
"value": "衣装をさらに変形させたい場合は、Fittingの反復回数を増やしてください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.ReparentAccessoryBones",
|
|
||||||
"value": "Weighting 時にアクセサリーボーンを Target アバターのアーマチュアへ移動して配置します。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.ReferenceCheck",
|
|
||||||
"value": "次の項目がすべて割り当てられている必要があります:"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.SourceClothesChildCheck",
|
|
||||||
"value": "Source Clothes Object は必ず Source Avatar Object の子オブジェクトである必要があります。\n→ Source Avatar オブジェクトの下に衣装を配置してください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.TargetClothesChildCheck",
|
|
||||||
"value": "Target Clothes Object は必ず Target Avatar Object の子オブジェクトである必要があります。\n→ Target Avatar オブジェクトの下に衣装を配置してください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.ClothesArmatureCheck",
|
|
||||||
"value": "Clothes Object - Clothes オブジェクトに、SkinnedMeshRenderer が参照するボーンアーマチュアが正しく含まれていません。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.SourceAvatarAnimatorCheck",
|
|
||||||
"value": "Source Avatar Object に Humanoid Avatar が設定されていません。\n→ Animator コンポーネントと Avatar 設定を確認してください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.TargetAvatarAnimatorCheck",
|
|
||||||
"value": "Target Avatar Object に Humanoid Avatar が設定されていません。\n→ Animator コンポーネントと Avatar 設定を確認してください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.CheckRendererCountCheck",
|
|
||||||
"value": "Source / Target Clothes の SkinnedMeshRenderer の数が一致していません。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.VertexCountCheck",
|
|
||||||
"value": "対応する SkinnedMeshRenderer の Mesh vertex 数が一致していません。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.Can'tFitting",
|
|
||||||
"value": "を実行できません\n\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyProxyNull",
|
|
||||||
"value": "Body Proxy Null エラー"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyProxyNull",
|
|
||||||
"value": "Body Proxy を割り当てることができませんでした。\nSource Avatar が正しく割り当てられているか、Animator にボーンが正しく設定されているか確認してください。"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.SourceBodyMeshNull",
|
|
||||||
"value": "Source Body Mesh の探索に失敗しました"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.SourceBodyMeshNull",
|
|
||||||
"value": "Source Body Mesh を見つけることができませんでした。"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.TargetBodyMeshNull",
|
|
||||||
"value": "Target Body Mesh の探索に失敗しました"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.TargetBodyMeshNull",
|
|
||||||
"value": "Target Body Mesh を見つけることができませんでした。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyMeshNull",
|
|
||||||
"value": "BodyMesh の探索に失敗しました"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyMeshNull",
|
|
||||||
"value": "[{0}] の BodyMesh を見つけることができません。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.TargetRendererNull",
|
|
||||||
"value": "Target Renderer Null エラー"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.TargetRendererNull",
|
|
||||||
"value": "targetRenderers に null が含まれています。"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.ClothInstanceAllocateFail",
|
|
||||||
"value": "ClothInstance の割り当てに失敗しました"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.ClothInstanceAllocateFail",
|
|
||||||
"value": "割り当て可能な ClothInstance がありません。\n衣装に SkinnedMeshRenderer が含まれているか確認してください。"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.WeightingNotReady",
|
|
||||||
"value": "Weighting の準備ができていません"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.WeightingNotReady",
|
|
||||||
"value": "WeightingEnumerator を呼び出す前に Fitting が完了していないか、Target Avatar が変更されています。\nRun Fitting を再実行してください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyBVHFail",
|
|
||||||
"value": "Body BVH の生成に失敗しました"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyBVHFail",
|
|
||||||
"value": "{0} の BVH の生成に失敗しました。\nbvhMesh is Null : {1}\nbvhMesh triangles is Null : {2}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Guide",
|
|
||||||
"value": "Profileデータ生成のための設定です。\nアバターのScaleは 1,1,1 に設定してください。\nアバターのBodyMeshが隠れないようにShapeKeyを調整してください。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.ProfileName.Tooltip",
|
|
||||||
"value": "保存されるProfileの名前"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.SourceAvatar.Tooltip",
|
|
||||||
"value": "Humanoid Rig と Animator が設定された Avatar の Root Transform"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.SourceBodyMeshes.Tooltip",
|
|
||||||
"value": "Profile生成に使用される Body SkinnedMeshRenderer の一覧"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.ProfileNameEmpty",
|
|
||||||
"value": "Profile Name が空です。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceAvatarNull",
|
|
||||||
"value": "Source Avatar が指定されていません。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceAvatarAnimatorMissing",
|
|
||||||
"value": "Source Avatar に Animator が存在しません。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceBodyMeshesEmpty",
|
|
||||||
"value": "Source Body Meshes が空です。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceBodyMeshesContainNull",
|
|
||||||
"value": "Source Body Meshes に NULL が含まれています。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.BodyMeshNotChildOfAvatar",
|
|
||||||
"value": "Source Body Meshes は必ず Source Avatar の子オブジェクトである必要があります。"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.BaseDataMissing",
|
|
||||||
"value": "BaseData フォルダに Base ファイルが存在しません。"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 07befa424eefac04e8670c57d4c2a2ec
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
{
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.AutoFitting",
|
|
||||||
"value": "자동 셋팅 모드"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ManualFitting",
|
|
||||||
"value": "직접 셋팅 모드"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ProfileFitting",
|
|
||||||
"value": "프로필 모드"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "Error.BodyMesh.NotFound",
|
|
||||||
"value": "Body Mesh를 찾지 못했습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "Error.KeyNotFound",
|
|
||||||
"value": "[KO] 해당 키를 찾을 수 없습니다: {0}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.ManualFittingGuide",
|
|
||||||
"value": "직접 셋팅 모드\n1. Source / Target Avatar에 해당하는 Object와 Mesh들을 할당해 주세요.\n2. 대응할 의상(Target Clothes Object)을 대응할 아바타에 맞춰 조정해주세요.\n3. [Run Fitting]을 눌러서 대응을 시작하세요.\n4. [Run Weighting]을 눌러서 Weight 할당을 시작하세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Mode.AutoFittingGuide",
|
|
||||||
"value": "자동 셋팅 모드\n1. Source Avatar에 Source 아바타 바디와 의상 Object를 할당해주세요.\n2. Target Avatar에 Target 아바타 바디를 할당해주세요.\n3. [Run Fitting]을 눌러 대응을 시작하세요.\n4. [Run Weighting]을 눌러서 Weight 할당을 시작하세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.MinMarginInfo",
|
|
||||||
"value": "의상이 몸에 너무 달라 붙는다면, MinMargin 값을 늘려주세요. (초기값: 0.003)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SkipFootFittingInfo",
|
|
||||||
"value": "Fitting 단계에서 발(foot) 기준의 형태 보정을 적용하지 않으려면 체크해주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.BodyMeshTitle",
|
|
||||||
"value": "Body Mesh 자동으로 할당하기."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.BodyMeshInfo",
|
|
||||||
"value": "Body Mesh를 자동으로 찾지 못 할 경우, \n(Head 제외) 바디에 해당하는 Mesh를 Body Meshes에 할당해 주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SigmaInfo",
|
|
||||||
"value": "값을 높일수록 의상의 더 넓은 부분이 함께 부드럽게 변형됩니다. (초기값: 0.85)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.SmoothingInfo",
|
|
||||||
"value": "값을 높일수록 Smooth 효과가 더 많이 적용되어 변형이 더욱 부드러워집니다. (초기값: 1)\n - 값이 높아질수록 연산 시간이 증가합니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.IterationInfo",
|
|
||||||
"value": "의상을 더 많이 변형시키고 싶다면, Fitting 반복 횟수를 늘려주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Property.ReparentAccessoryBones",
|
|
||||||
"value": "Weighting시 악세서리 본을 Target Avatar에 Armature로 옮겨 배치합니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.ReferenceCheck",
|
|
||||||
"value": "다음 항목이 모두 할당되어야 합니다:"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.SourceClothesChildCheck",
|
|
||||||
"value": "Source Clothes Object 는 반드시 Source Avatar Object 의 자식이어야 합니다.\n→ Source Avatar 오브젝트 하위에 의상을 넣어 주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.TargetClothesChildCheck",
|
|
||||||
"value": "Target Clothes Object 는 반드시 Target Avatar Object 의 자식이어야 합니다.\n→ Target Avatar 오브젝트 하위에 의상을 넣어 주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.ClothesArmatureCheck",
|
|
||||||
"value": "Clothes Object - 의상에 SkinnedMeshRenderer가 참조하는 Bone Armature가 올바르게 포함되어 있지 않습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.SourceAvatarAnimatorCheck",
|
|
||||||
"value": "Source Avatar Object 에 Humanoid Avatar 가 설정되어 있지 않습니다.\n→ Animator 컴포넌트 및 Avatar 설정을 확인해 주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.TargetAvatarAnimatorCheck",
|
|
||||||
"value": "Target Avatar Object 에 Humanoid Avatar 가 설정되어 있지 않습니다.\n→ Animator 컴포넌트 및 Avatar 설정을 확인해 주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.CheckRendererCountCheck",
|
|
||||||
"value": "Source / Target Clothes 의 SkinnedMeshRenderer 개수가 일치하지 않습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.VertexCountCheck",
|
|
||||||
"value": "대응되는 SkinnedMeshRenderer 의 Mesh vertex 수가 일치하지 않습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Validator.Can'tFitting",
|
|
||||||
"value": "실행 불가\n\n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyProxyNull",
|
|
||||||
"value": "Body Proxy Null 에러"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyProxyNull",
|
|
||||||
"value": "Body Proxy를 할당할 수 없습니다.\nSource Avatar가 제대로 할당되어 있으며, Animator에 본이 제대로 셋팅되어 있는지 확인해주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.SourceBodyMeshNull",
|
|
||||||
"value": "Source Body Mesh 탐색 실패"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.SourceBodyMeshNull",
|
|
||||||
"value": "Source Body Mesh 를 찾을 수 없습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.TargetBodyMeshNull",
|
|
||||||
"value": "Target Body Mesh 탐색 실패"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.TargetBodyMeshNull",
|
|
||||||
"value": "Target Body Mesh 를 찾을 수 없습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyMeshNull",
|
|
||||||
"value": "Body Mesh 탐색 실패"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyMeshNull",
|
|
||||||
"value": "[{0}]의 Body Mesh 를 찾을 수 없습니다."
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.TargetRendererNull",
|
|
||||||
"value": "Target Renderer Null 에러"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.TargetRendererNull",
|
|
||||||
"value": "targetRenderers 에 null 이 포함되어 있습니다."
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.ClothInstanceAllocateFail",
|
|
||||||
"value": "ClothInstance 할당 실패"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.ClothInstanceAllocateFail",
|
|
||||||
"value": "할당할 수 있는 ClothInstance가 없습니다.\n의상에 SkinnedMeshRenderer가 있는지 확인해주세요."
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.WeightingNotReady",
|
|
||||||
"value": "Weighting이 준비되지 않았습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.WeightingNotReady",
|
|
||||||
"value": "WeightingEnumerator 호출 전 Fitting이 완료되지 않았거나, Target Avatar가 변경되었습니다.\nRun Fitting을 다시 실행해 주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.title.BodyBVHFail",
|
|
||||||
"value": "Body BVH 생성 실패"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.Exception.message.BodyBVHFail",
|
|
||||||
"value": "{0} 의 BVH를 만드는데 실패하였습니다.\nbvhMesh is Null : {1}\nbvhMesh triangles is Null : {2}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Guide",
|
|
||||||
"value": "Profile 데이터 생성을 위한 설정 영역입니다.\n아바타의 Scale은 1,1,1로 맞춰주세요.\n아바타의 BodyMesh가 가려지지 않도록 ShapeKey를 조절해 주세요."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.ProfileName.Tooltip",
|
|
||||||
"value": "저장될 Profile 이름"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.SourceAvatar.Tooltip",
|
|
||||||
"value": "Humanoid Rig + Animator가 설정된 Avatar Root Transform"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.SourceBodyMeshes.Tooltip",
|
|
||||||
"value": "Profile 생성에 사용될 Body SkinnedMeshRenderer 목록"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.ProfileNameEmpty",
|
|
||||||
"value": "Profile Name이 비어 있습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceAvatarNull",
|
|
||||||
"value": "Source Avatar가 지정되지 않았습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceAvatarAnimatorMissing",
|
|
||||||
"value": "Source Avatar에 Animator가 존재하지 않습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceBodyMeshesEmpty",
|
|
||||||
"value": "Source Body Meshes가 비어 있습니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.SourceBodyMeshesContainNull",
|
|
||||||
"value": "Source Body Meshes에 NULL이 존재합니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.BodyMeshNotChildOfAvatar",
|
|
||||||
"value": "Source Body Meshes 는 반드시 Source Avatar 의 자식이어야 합니다."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "UI.ProfileSaver.Error.BaseDataMissing",
|
|
||||||
"value": "BaseData 폴더에 Base 파일이 존재하지 않습니다."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 06a08864e1cbb6740a46cbde54883c6a
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,285 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
using UnityEditor;
|
|
||||||
#endif
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Eden.AutoMorpher
|
|
||||||
{
|
|
||||||
public enum Language
|
|
||||||
{
|
|
||||||
Korean = 0,
|
|
||||||
Japanese = 1,
|
|
||||||
English = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class LocalizationEntry
|
|
||||||
{
|
|
||||||
public string key;
|
|
||||||
public string value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class LocalizationFile
|
|
||||||
{
|
|
||||||
public LocalizationEntry[] entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
[InitializeOnLoad]
|
|
||||||
#endif
|
|
||||||
public static class LanguageManager
|
|
||||||
{
|
|
||||||
private const string PREF_KEY_LANG = "EdenAutoMorpher_Language";
|
|
||||||
|
|
||||||
private const string PATH_KO = "Language/Language_ko";
|
|
||||||
private const string PATH_JA = "Language/Language_ja";
|
|
||||||
private const string PATH_EN = "Language/Language_en";
|
|
||||||
|
|
||||||
private static Language _currentLanguage = Language.Korean;
|
|
||||||
|
|
||||||
private static Dictionary<string, string> _koTable;
|
|
||||||
private static Dictionary<string, string> _jaTable;
|
|
||||||
private static Dictionary<string, string> _enTable;
|
|
||||||
|
|
||||||
public static Language CurrentLanguage
|
|
||||||
{
|
|
||||||
get => _currentLanguage;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_currentLanguage == value) return;
|
|
||||||
_currentLanguage = value;
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
EditorPrefs.SetInt(PREF_KEY_LANG, (int)_currentLanguage);
|
|
||||||
#else
|
|
||||||
PlayerPrefs.SetInt(PREF_KEY_LANG, (int)_currentLanguage);
|
|
||||||
PlayerPrefs.Save();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static LanguageManager()
|
|
||||||
{
|
|
||||||
// Editor 시작 시 언어 로드
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
int saved = EditorPrefs.GetInt(PREF_KEY_LANG, (int)Language.Korean);
|
|
||||||
#else
|
|
||||||
int saved = PlayerPrefs.GetInt(PREF_KEY_LANG, (int)Language.Korean);
|
|
||||||
#endif
|
|
||||||
_currentLanguage = (Language)Mathf.Clamp(saved, 0, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 현재 언어에서 문자열 가져오기.
|
|
||||||
/// key 없으면 fallback → 다른 언어 → 최종적으로 key 자체 반환.
|
|
||||||
/// </summary>
|
|
||||||
public static string Get(string key)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(key))
|
|
||||||
return string.Empty;
|
|
||||||
|
|
||||||
// 현재 언어 테이블에서 먼저 검색
|
|
||||||
if (TryGetFromCurrentLanguage(key, out string value))
|
|
||||||
return value;
|
|
||||||
|
|
||||||
return FormatKeyNotFound(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 언어별로 다른 키를 쓰고 싶을 때 (번호 기반 등)도 가능하도록
|
|
||||||
/// 번호를 바로 key 문자열로 변환해서 사용하는 버전.
|
|
||||||
/// </summary>
|
|
||||||
public static string GetById(int id)
|
|
||||||
{
|
|
||||||
// 예: "ID.1001" 이런 식으로 통일하면 관리가 편함
|
|
||||||
string key = $"ID.{id}";
|
|
||||||
return Get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetLanguage(Language lang)
|
|
||||||
{
|
|
||||||
CurrentLanguage = lang;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================== 내부 구현 ==================
|
|
||||||
|
|
||||||
private static bool TryGetFromCurrentLanguage(string key, out string value)
|
|
||||||
{
|
|
||||||
var table = GetTable(_currentLanguage);
|
|
||||||
if (table != null && table.TryGetValue(key, out value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
value = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool TryGetFromOtherLanguages(string key, out string value)
|
|
||||||
{
|
|
||||||
// 현재 언어 제외한 나머지 순회
|
|
||||||
foreach (Language lang in System.Enum.GetValues(typeof(Language)))
|
|
||||||
{
|
|
||||||
if (lang == _currentLanguage)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var table = GetTable(lang);
|
|
||||||
if (table != null && table.TryGetValue(key, out value))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Dictionary<string, string> GetTable(Language lang)
|
|
||||||
{
|
|
||||||
switch (lang)
|
|
||||||
{
|
|
||||||
case Language.Korean:
|
|
||||||
if (_koTable == null)
|
|
||||||
_koTable = LoadTable(PATH_KO);
|
|
||||||
return _koTable;
|
|
||||||
|
|
||||||
case Language.Japanese:
|
|
||||||
if (_jaTable == null)
|
|
||||||
_jaTable = LoadTable(PATH_JA);
|
|
||||||
return _jaTable;
|
|
||||||
|
|
||||||
case Language.English:
|
|
||||||
if (_enTable == null)
|
|
||||||
_enTable = LoadTable(PATH_EN);
|
|
||||||
return _enTable;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fileName: "lang_ko", "lang_ja", "lang_en" 처럼 사용
|
|
||||||
private static Dictionary<string, string> LoadTable(string fileName)
|
|
||||||
{
|
|
||||||
var dict = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
// 스크립트 기준 Language 폴더 아래의 json 경로
|
|
||||||
string assetPath = GetLanguageJsonAssetPath(fileName);
|
|
||||||
// Assets/... 형식 경로를 실제 디스크 경로로 변환
|
|
||||||
string fullPath = Path.GetFullPath(assetPath);
|
|
||||||
|
|
||||||
if (!File.Exists(fullPath))
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"[AutoMorpherLanguage] Localization file not found: {fullPath}");
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
string jsonText;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// ✅ 강제로 UTF-8 로 읽기 (BOM 유무 상관 없음)
|
|
||||||
jsonText = File.ReadAllText(fullPath, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogError($"[AutoMorpherLanguage] Failed to read localization file: {fullPath}\n{ex}");
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var file = JsonUtility.FromJson<LocalizationFile>(jsonText);
|
|
||||||
if (file?.entries != null)
|
|
||||||
{
|
|
||||||
foreach (var entry in file.entries)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(entry.key))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dict[entry.key] = entry.value ?? string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogError($"[AutoMorpherLanguage] Failed to parse localization file: {fullPath}\n{ex}");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// 런타임 빌드에서 쓸 계획이 없으면 비워둬도 됨
|
|
||||||
#endif
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
private static string FormatKeyNotFound(string key)
|
|
||||||
{
|
|
||||||
// 먼저 현재 언어의 "Error.KeyNotFound" 가져오기
|
|
||||||
if (TryGetFromCurrentLanguage("Error.KeyNotFound", out string template))
|
|
||||||
return template.Replace("{0}", key);
|
|
||||||
|
|
||||||
// JSON 자체가 없어서 템플릿도 없는 경우 (최후 fallback)
|
|
||||||
switch (CurrentLanguage)
|
|
||||||
{
|
|
||||||
case Language.Korean:
|
|
||||||
return $"[KO] 해당 키를 찾을 수 없습니다: {key}";
|
|
||||||
case Language.Japanese:
|
|
||||||
return $"[JP] キーが見つかりません: {key}";
|
|
||||||
default:
|
|
||||||
return $"[EN] Could not find key: {key}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static string GetLanguageFolderPath()
|
|
||||||
{
|
|
||||||
string scriptDir = "Assets\\@Eden_Tools\\Eden_AutoMorpher\\LanguageManager\\Language";
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
// AutoMorpherLanguage 스크립트의 GUID 찾기
|
|
||||||
string[] guids = AssetDatabase.FindAssets("LanguageManager t:MonoScript");
|
|
||||||
if (guids == null || guids.Length == 0)
|
|
||||||
{
|
|
||||||
Debug.LogError("[LanguageManager] Could not find LanguageManager.cs script.");
|
|
||||||
return "Assets"; // 최소 fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
string scriptPath = AssetDatabase.GUIDToAssetPath(guids[0]); // 예: Assets/@Eden_Tools/.../AutoMorpherLanguage.cs
|
|
||||||
scriptDir = Path.GetDirectoryName(scriptPath); // 그 폴더
|
|
||||||
|
|
||||||
|
|
||||||
// 폴더가 없으면 에디터에서 자동 생성
|
|
||||||
if (!Directory.Exists(scriptDir))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(scriptDir);
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// Unity Asset 경로 포맷으로 정리
|
|
||||||
scriptDir = scriptDir.Replace("\\", "/");
|
|
||||||
return scriptDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetLanguageJsonAssetPath(string fileNameWithoutExt)
|
|
||||||
{
|
|
||||||
string folder = GetLanguageFolderPath();
|
|
||||||
string path = Path.Combine(folder, fileNameWithoutExt + ".json");
|
|
||||||
return path.Replace("\\", "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetFormat(string key, params object[] args)
|
|
||||||
{
|
|
||||||
string raw = Get(key);
|
|
||||||
if (string.IsNullOrEmpty(raw))
|
|
||||||
return string.Empty;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return string.Format(raw, args);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogError($"[LanguageManager] Format failed for key: {key}\n{ex}");
|
|
||||||
return raw; // 최소한 원문이라도 보여주기
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b4990eee90808bc488656e484f9ea0d8
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 3f15b8b51b341c647a98a34a47707efb
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 42ffaa733fd3b8f4bb16b48ac9321699
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 9edd784ea5aea9d419070655b91a1ade
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,
|
|
||||||
// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.
|
|
||||||
// EdenAutoMorpher_ProfileSaver_Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// EdenAutoMorpher_ProfileSaverEditor
|
|
||||||
using Eden.AutoMorpher;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
[CustomEditor(typeof(EdenAutoMorpher_ProfileSaver))]
|
|
||||||
public class EdenAutoMorpher_ProfileSaverEditor : Editor
|
|
||||||
{
|
|
||||||
private EdenAutoMorpher_ProfileSaver saver;
|
|
||||||
|
|
||||||
private ProfileUtils profileUtils;
|
|
||||||
|
|
||||||
private string errorMessage;
|
|
||||||
|
|
||||||
private bool hasError;
|
|
||||||
|
|
||||||
private void OnEnable()
|
|
||||||
{
|
|
||||||
this.saver = (EdenAutoMorpher_ProfileSaver)base.target;
|
|
||||||
this.profileUtils = new ProfileUtils();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnInspectorGUI()
|
|
||||||
{
|
|
||||||
base.serializedObject.Update();
|
|
||||||
this.DrawProfileVersion();
|
|
||||||
EditorGUILayout.Space(8f);
|
|
||||||
this.DrawGuideMessage();
|
|
||||||
EditorGUILayout.Space(10f);
|
|
||||||
this.DrawRequiredInputFields();
|
|
||||||
EditorGUILayout.Space(10f);
|
|
||||||
this.DrawSavePath();
|
|
||||||
EditorGUILayout.Space(8f);
|
|
||||||
this.ValidateInputs();
|
|
||||||
this.DrawErrorMessage();
|
|
||||||
EditorGUILayout.Space(12f);
|
|
||||||
this.DrawSaveButton();
|
|
||||||
base.serializedObject.ApplyModifiedProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawProfileVersion()
|
|
||||||
{
|
|
||||||
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
|
|
||||||
int profileVersion = this.profileUtils.GetProfileVersion();
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
|
||||||
EditorGUILayout.LabelField("EDEN Auto Morpher - Profile Saver", EditorStyles.boldLabel);
|
|
||||||
GUILayout.FlexibleSpace();
|
|
||||||
Language currentLanguage = LanguageManager.CurrentLanguage;
|
|
||||||
Language val = currentLanguage;
|
|
||||||
val = (Language)(object)EditorGUILayout.EnumPopup((Enum)(object)currentLanguage, GUILayout.Width(80f));
|
|
||||||
if (val != currentLanguage)
|
|
||||||
{
|
|
||||||
LanguageManager.SetLanguage(val);
|
|
||||||
GUI.FocusControl(null);
|
|
||||||
}
|
|
||||||
EditorGUILayout.EndHorizontal();
|
|
||||||
EditorGUILayout.LabelField($"Profile Version : {profileVersion}", EditorStyles.boldLabel);
|
|
||||||
EditorGUILayout.Space(6f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawGuideMessage()
|
|
||||||
{
|
|
||||||
EditorGUILayout.HelpBox("\n" + LanguageManager.Get("UI.ProfileSaver.Guide") + "\n", MessageType.Info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawRequiredInputFields()
|
|
||||||
{
|
|
||||||
EditorGUILayout.LabelField("Required Input Fields", EditorStyles.boldLabel);
|
|
||||||
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
|
||||||
{
|
|
||||||
EditorGUI.indentLevel++;
|
|
||||||
EditorGUILayout.Space(4f);
|
|
||||||
EditorGUILayout.PropertyField(base.serializedObject.FindProperty("profileName"), new GUIContent("Profile Name", LanguageManager.Get("UI.ProfileSaver.ProfileName.Tooltip")));
|
|
||||||
EditorGUILayout.Space(6f);
|
|
||||||
EditorGUILayout.PropertyField(base.serializedObject.FindProperty("sourceAvatar"), new GUIContent("Source Avatar", LanguageManager.Get("UI.ProfileSaver.SourceAvatar.Tooltip")));
|
|
||||||
EditorGUILayout.Space(6f);
|
|
||||||
EditorGUI.indentLevel++;
|
|
||||||
EditorGUILayout.PropertyField(base.serializedObject.FindProperty("sourceBodyMeshes"), new GUIContent("Source Body Meshes", LanguageManager.Get("UI.ProfileSaver.SourceBodyMeshes.Tooltip")), true);
|
|
||||||
EditorGUILayout.Space(4f);
|
|
||||||
EditorGUI.indentLevel--;
|
|
||||||
EditorGUI.indentLevel--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawSavePath()
|
|
||||||
{
|
|
||||||
EditorGUILayout.LabelField("Save Path", EditorStyles.boldLabel);
|
|
||||||
string text = Path.Combine(this.profileUtils.GetProfileBasePath(), this.saver.profileName ?? string.Empty);
|
|
||||||
using (new EditorGUI.DisabledScope(disabled: true))
|
|
||||||
{
|
|
||||||
EditorGUILayout.TextField(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ValidateInputs()
|
|
||||||
{
|
|
||||||
this.errorMessage = "\n";
|
|
||||||
this.hasError = false;
|
|
||||||
if (string.IsNullOrEmpty(this.saver.profileName))
|
|
||||||
{
|
|
||||||
this.errorMessage = this.errorMessage + LanguageManager.Get("UI.ProfileSaver.Error.ProfileNameEmpty") + "\n";
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
if (this.saver.sourceAvatar == null)
|
|
||||||
{
|
|
||||||
this.errorMessage = this.errorMessage + LanguageManager.Get("UI.ProfileSaver.Error.SourceAvatarNull") + "\n";
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else if (this.saver.sourceAvatar.GetComponent<Animator>() == null)
|
|
||||||
{
|
|
||||||
this.errorMessage = this.errorMessage + LanguageManager.Get("UI.ProfileSaver.Error.SourceAvatarAnimatorMissing") + "\n";
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
if (this.saver.sourceBodyMeshes == null || this.saver.sourceBodyMeshes.Count == 0)
|
|
||||||
{
|
|
||||||
this.errorMessage = this.errorMessage + LanguageManager.Get("UI.ProfileSaver.Error.SourceBodyMeshesEmpty") + "\n";
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (this.IsBodyMeshesContainNull())
|
|
||||||
{
|
|
||||||
this.errorMessage = this.errorMessage + LanguageManager.Get("UI.ProfileSaver.Error.SourceBodyMeshesContainNull") + "\n";
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
if (this.saver.sourceAvatar != null && this.IsBodyMeshNotChildOfAvatar())
|
|
||||||
{
|
|
||||||
this.errorMessage = this.errorMessage + LanguageManager.Get("UI.ProfileSaver.Error.BodyMeshNotChildOfAvatar") + "\n";
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!this.saver.IsExistBaseData())
|
|
||||||
{
|
|
||||||
this.errorMessage = this.errorMessage + LanguageManager.Get("UI.ProfileSaver.Error.BaseDataMissing") + "\n";
|
|
||||||
this.hasError = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsBodyMeshesContainNull()
|
|
||||||
{
|
|
||||||
foreach (SkinnedMeshRenderer sourceBodyMesh in this.saver.sourceBodyMeshes)
|
|
||||||
{
|
|
||||||
if (sourceBodyMesh == null)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsBodyMeshNotChildOfAvatar()
|
|
||||||
{
|
|
||||||
foreach (SkinnedMeshRenderer sourceBodyMesh in this.saver.sourceBodyMeshes)
|
|
||||||
{
|
|
||||||
if (sourceBodyMesh != null && !sourceBodyMesh.transform.IsChildOf(this.saver.sourceAvatar.transform))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawErrorMessage()
|
|
||||||
{
|
|
||||||
if (this.hasError)
|
|
||||||
{
|
|
||||||
EditorGUILayout.HelpBox(this.errorMessage, MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawSaveButton()
|
|
||||||
{
|
|
||||||
using (new EditorGUI.DisabledScope(this.hasError))
|
|
||||||
{
|
|
||||||
if (GUILayout.Button("Save Profile", GUILayout.Height(34f)))
|
|
||||||
{
|
|
||||||
this.saver.SaveProfile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 06e603c0e6910f74e8ae69f4b1025e99
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0a87e8255c6175649ab3d14c5d7390a0
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.BaseKey3
|
|
||||||
public struct BaseKey3
|
|
||||||
{
|
|
||||||
public uint x;
|
|
||||||
|
|
||||||
public uint y;
|
|
||||||
|
|
||||||
public uint z;
|
|
||||||
|
|
||||||
public BaseKey3(uint x, uint y, uint z)
|
|
||||||
{
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 33819e87e935234448269d35d6e155b5
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.BoneData
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class BoneData
|
|
||||||
{
|
|
||||||
public int id;
|
|
||||||
|
|
||||||
public string boneName;
|
|
||||||
|
|
||||||
public string parentName;
|
|
||||||
|
|
||||||
public string hierarchyPath;
|
|
||||||
|
|
||||||
public HumanBodyBones hBone;
|
|
||||||
|
|
||||||
public int parentId;
|
|
||||||
|
|
||||||
public List<int> childrenIds;
|
|
||||||
|
|
||||||
public Vector3 rootLocalPosition;
|
|
||||||
|
|
||||||
public Quaternion rootLocalRotation;
|
|
||||||
|
|
||||||
public Vector3 rootLocalScale;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8d3573fd768baee41b6e2b78d647bf04
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.BoneSpatialData
|
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class BoneSpatialData
|
|
||||||
{
|
|
||||||
public HumanBodyBones refBone;
|
|
||||||
|
|
||||||
public PCAData pcaData;
|
|
||||||
|
|
||||||
public VolumeData volumeData;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 48d80c2519b3d8b4a97a8d6d5cd7b159
|
|
||||||
@@ -1,326 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.EdenAutoMorpher_ProfileSaver
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class EdenAutoMorpher_ProfileSaver : MonoBehaviour
|
|
||||||
{
|
|
||||||
public Transform sourceAvatar;
|
|
||||||
|
|
||||||
public List<SkinnedMeshRenderer> sourceBodyMeshes = new List<SkinnedMeshRenderer>();
|
|
||||||
|
|
||||||
public string profileName;
|
|
||||||
|
|
||||||
private const float adjustHigh = 1.5f;
|
|
||||||
|
|
||||||
[ContextMenu("SaveProfile")]
|
|
||||||
public void SaveProfile()
|
|
||||||
{
|
|
||||||
Vector3 position = this.sourceAvatar.position;
|
|
||||||
Quaternion rotation = this.sourceAvatar.rotation;
|
|
||||||
Vector3 localScale = this.sourceAvatar.localScale;
|
|
||||||
Transform parent = this.sourceAvatar.parent;
|
|
||||||
this.sourceAvatar.SetParent(null);
|
|
||||||
this.sourceAvatar.position = Vector3.zero;
|
|
||||||
this.sourceAvatar.rotation = Quaternion.identity;
|
|
||||||
this.sourceAvatar.localScale = Vector3.one;
|
|
||||||
ProfileData newProfileData = new ProfileData();
|
|
||||||
ProfileUtils profileUtils = new ProfileUtils();
|
|
||||||
newProfileData.version = profileUtils.GetProfileVersion();
|
|
||||||
Animator component = this.sourceAvatar.GetComponent<Animator>();
|
|
||||||
if (component == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[EdenAutoMorpher_ProfileSaver] Source Avatar Has No Animator\nSet Animator to Source Avatar " + this.sourceAvatar.name);
|
|
||||||
}
|
|
||||||
Dictionary<HumanBodyBones, HashSet<Transform>> humanoidMeshBoneMap = profileUtils.GetHumanoidMeshBoneMap(component, this.sourceBodyMeshes);
|
|
||||||
List<ProfileBakedBodyMesh> list = new List<ProfileBakedBodyMesh>();
|
|
||||||
foreach (SkinnedMeshRenderer sourceBodyMesh in this.sourceBodyMeshes)
|
|
||||||
{
|
|
||||||
list.Add(new ProfileBakedBodyMesh(sourceBodyMesh));
|
|
||||||
}
|
|
||||||
this.SaveBoneData(ref newProfileData, this.sourceAvatar, humanoidMeshBoneMap, list);
|
|
||||||
ProfileUtils_BVHUtil profileUtils_BVHUtil = new ProfileUtils_BVHUtil();
|
|
||||||
ProfileBVH bVHData = profileUtils_BVHUtil.GetBVHData(this.sourceAvatar, list);
|
|
||||||
profileUtils_BVHUtil.SaveProfileBVH(bVHData, Path.Combine(profileUtils.GetProfileBasePath(), this.profileName), this.profileName);
|
|
||||||
newProfileData.neckTargetHeight = 1.5f;
|
|
||||||
this.AdjustAvatarHigh(this.sourceAvatar, humanoidMeshBoneMap, 1.5f);
|
|
||||||
foreach (ProfileBakedBodyMesh item in list)
|
|
||||||
{
|
|
||||||
item.ReBakeMesh();
|
|
||||||
}
|
|
||||||
this.SaveSpatialData(ref newProfileData, humanoidMeshBoneMap, list);
|
|
||||||
this.SaveProfileToJson(newProfileData, Path.Combine(profileUtils.GetProfileBasePath(), this.profileName), this.profileName);
|
|
||||||
this.sourceAvatar.SetParent(parent);
|
|
||||||
this.sourceAvatar.position = position;
|
|
||||||
this.sourceAvatar.rotation = rotation;
|
|
||||||
this.sourceAvatar.localScale = localScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveSpatialData(ref ProfileData newProfileData, Dictionary<HumanBodyBones, HashSet<Transform>> sourceBoneMap, List<ProfileBakedBodyMesh> sourceBodyBakedMeshes)
|
|
||||||
{
|
|
||||||
ProfileUtils profileUtils = new ProfileUtils();
|
|
||||||
HumanBodyBones[] influencedBones = new HumanBodyBones[1] { HumanBodyBones.Neck };
|
|
||||||
newProfileData.NeckSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.Neck, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.LeftUpperArm,
|
|
||||||
HumanBodyBones.LeftLowerArm,
|
|
||||||
HumanBodyBones.LeftHand
|
|
||||||
};
|
|
||||||
newProfileData.LeftUpperArmSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftUpperArm, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.RightUpperArm,
|
|
||||||
HumanBodyBones.RightLowerArm,
|
|
||||||
HumanBodyBones.RightHand
|
|
||||||
};
|
|
||||||
newProfileData.RightUpperArmSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightUpperArm, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftLowerArm };
|
|
||||||
newProfileData.LeftLowerArmSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftLowerArm, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightLowerArm };
|
|
||||||
newProfileData.RightLowerArmSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightLowerArm, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftHand };
|
|
||||||
newProfileData.LeftLowerArm_HandSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftLowerArm, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightHand };
|
|
||||||
newProfileData.RightLowerArm_HandSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightLowerArm, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[2]
|
|
||||||
{
|
|
||||||
HumanBodyBones.LeftUpperLeg,
|
|
||||||
HumanBodyBones.LeftLowerLeg
|
|
||||||
};
|
|
||||||
newProfileData.LeftUpperLegSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftUpperLeg, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[2]
|
|
||||||
{
|
|
||||||
HumanBodyBones.RightUpperLeg,
|
|
||||||
HumanBodyBones.RightLowerLeg
|
|
||||||
};
|
|
||||||
newProfileData.RightUpperLegSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightUpperLeg, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftFoot };
|
|
||||||
newProfileData.LeftFootSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftFoot, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightFoot };
|
|
||||||
newProfileData.RightFootSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightFoot, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.Chest };
|
|
||||||
newProfileData.ChestSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.Chest, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.UpperChest };
|
|
||||||
newProfileData.UpperChestSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.UpperChest, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[2]
|
|
||||||
{
|
|
||||||
HumanBodyBones.Chest,
|
|
||||||
HumanBodyBones.UpperChest
|
|
||||||
};
|
|
||||||
newProfileData.IntegratedChestSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.Chest, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.Spine };
|
|
||||||
newProfileData.SpineSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.Spine, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftHand };
|
|
||||||
newProfileData.LeftHandSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftHand, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.LeftThumbProximal,
|
|
||||||
HumanBodyBones.LeftThumbIntermediate,
|
|
||||||
HumanBodyBones.LeftThumbDistal
|
|
||||||
};
|
|
||||||
newProfileData.LeftHandThumbSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftThumbProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftThumbProximal };
|
|
||||||
newProfileData.LeftHandThumbProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftThumbProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftThumbIntermediate };
|
|
||||||
newProfileData.LeftHandThumbIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftThumbIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftThumbDistal };
|
|
||||||
newProfileData.LeftHandThumbDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftThumbDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.LeftIndexProximal,
|
|
||||||
HumanBodyBones.LeftIndexIntermediate,
|
|
||||||
HumanBodyBones.LeftIndexDistal
|
|
||||||
};
|
|
||||||
newProfileData.LeftHandIndexSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftIndexProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftIndexProximal };
|
|
||||||
newProfileData.LeftHandIndexProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftIndexProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftIndexIntermediate };
|
|
||||||
newProfileData.LeftHandIndexIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftIndexIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftIndexDistal };
|
|
||||||
newProfileData.LeftHandIndexDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftIndexDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.LeftMiddleProximal,
|
|
||||||
HumanBodyBones.LeftMiddleIntermediate,
|
|
||||||
HumanBodyBones.LeftMiddleDistal
|
|
||||||
};
|
|
||||||
newProfileData.LeftHandMiddleSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftMiddleProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftMiddleProximal };
|
|
||||||
newProfileData.LeftHandMiddleProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftMiddleProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftMiddleIntermediate };
|
|
||||||
newProfileData.LeftHandMiddleIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftMiddleIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftMiddleDistal };
|
|
||||||
newProfileData.LeftHandMiddleDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftMiddleDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.LeftRingProximal,
|
|
||||||
HumanBodyBones.LeftRingIntermediate,
|
|
||||||
HumanBodyBones.LeftRingDistal
|
|
||||||
};
|
|
||||||
newProfileData.LeftHandRingSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftRingProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftRingProximal };
|
|
||||||
newProfileData.LeftHandRingProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftRingProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftRingIntermediate };
|
|
||||||
newProfileData.LeftHandRingIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftRingIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftRingDistal };
|
|
||||||
newProfileData.LeftHandRingDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftRingDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.LeftLittleProximal,
|
|
||||||
HumanBodyBones.LeftLittleIntermediate,
|
|
||||||
HumanBodyBones.LeftLittleDistal
|
|
||||||
};
|
|
||||||
newProfileData.LeftHandLittleSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftLittleProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftLittleProximal };
|
|
||||||
newProfileData.LeftHandLittleProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftLittleProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftLittleIntermediate };
|
|
||||||
newProfileData.LeftHandLittleIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftLittleIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.LeftLittleDistal };
|
|
||||||
newProfileData.LeftHandLittleDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.LeftLittleDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightHand };
|
|
||||||
newProfileData.RightHandSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightHand, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.RightThumbProximal,
|
|
||||||
HumanBodyBones.RightThumbIntermediate,
|
|
||||||
HumanBodyBones.RightThumbDistal
|
|
||||||
};
|
|
||||||
newProfileData.RightHandThumbSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightThumbProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightThumbProximal };
|
|
||||||
newProfileData.RightHandThumbProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightThumbProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightThumbIntermediate };
|
|
||||||
newProfileData.RightHandThumbIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightThumbIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightThumbDistal };
|
|
||||||
newProfileData.RightHandThumbDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightThumbDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.RightIndexProximal,
|
|
||||||
HumanBodyBones.RightIndexIntermediate,
|
|
||||||
HumanBodyBones.RightIndexDistal
|
|
||||||
};
|
|
||||||
newProfileData.RightHandIndexSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightIndexProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightIndexProximal };
|
|
||||||
newProfileData.RightHandIndexProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightIndexProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightIndexIntermediate };
|
|
||||||
newProfileData.RightHandIndexIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightIndexIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightIndexDistal };
|
|
||||||
newProfileData.RightHandIndexDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightIndexDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.RightMiddleProximal,
|
|
||||||
HumanBodyBones.RightMiddleIntermediate,
|
|
||||||
HumanBodyBones.RightMiddleDistal
|
|
||||||
};
|
|
||||||
newProfileData.RightHandMiddleSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightMiddleProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightMiddleProximal };
|
|
||||||
newProfileData.RightHandMiddleProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightMiddleProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightMiddleIntermediate };
|
|
||||||
newProfileData.RightHandMiddleIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightMiddleIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightMiddleDistal };
|
|
||||||
newProfileData.RightHandMiddleDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightMiddleDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.RightRingProximal,
|
|
||||||
HumanBodyBones.RightRingIntermediate,
|
|
||||||
HumanBodyBones.RightRingDistal
|
|
||||||
};
|
|
||||||
newProfileData.RightHandRingSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightRingProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightRingProximal };
|
|
||||||
newProfileData.RightHandRingProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightRingProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightRingIntermediate };
|
|
||||||
newProfileData.RightHandRingIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightRingIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightRingDistal };
|
|
||||||
newProfileData.RightHandRingDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightRingDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[3]
|
|
||||||
{
|
|
||||||
HumanBodyBones.RightLittleProximal,
|
|
||||||
HumanBodyBones.RightLittleIntermediate,
|
|
||||||
HumanBodyBones.RightLittleDistal
|
|
||||||
};
|
|
||||||
newProfileData.RightHandLittleSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightLittleProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes, addChildBones: true);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightLittleProximal };
|
|
||||||
newProfileData.RightHandLittleProximalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightLittleProximal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightLittleIntermediate };
|
|
||||||
newProfileData.RightHandLittleIntermediateSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightLittleIntermediate, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
influencedBones = new HumanBodyBones[1] { HumanBodyBones.RightLittleDistal };
|
|
||||||
newProfileData.RightHandLittleDistalSpatialData = profileUtils.GetBoneSpatialData(HumanBodyBones.RightLittleDistal, influencedBones, sourceBoneMap, sourceBodyBakedMeshes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveBoneData(ref ProfileData newProfileData, Transform sourceAvatar, Dictionary<HumanBodyBones, HashSet<Transform>> sourceBoneMap, List<ProfileBakedBodyMesh> sourceBodyBakedMeshes)
|
|
||||||
{
|
|
||||||
ProfileUtils profileUtils = new ProfileUtils();
|
|
||||||
HashSet<Transform> hashSet = new HashSet<Transform>();
|
|
||||||
foreach (ProfileBakedBodyMesh sourceBodyBakedMesh in sourceBodyBakedMeshes)
|
|
||||||
{
|
|
||||||
foreach (Transform bodyMeshBone in profileUtils.GetBodyMeshBones(sourceBodyBakedMesh.smr))
|
|
||||||
{
|
|
||||||
hashSet.Add(bodyMeshBone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hashSet.Count == 0)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[EdenAutoMorpher_ProfileSaver] SaveBoneData - avatarBones is empty.");
|
|
||||||
newProfileData.boneRootId = -1;
|
|
||||||
newProfileData.bones = new List<BoneData>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newProfileData.boneRootId = 0;
|
|
||||||
newProfileData.bones = profileUtils.GetBoneDatas(sourceAvatar, hashSet, sourceBoneMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AdjustAvatarHigh(Transform sourceRoot, Dictionary<HumanBodyBones, HashSet<Transform>> sourceBoneMap, float targetHeight)
|
|
||||||
{
|
|
||||||
if (!sourceBoneMap.TryGetValue(HumanBodyBones.Neck, out var value) || value.Count == 0)
|
|
||||||
{
|
|
||||||
Debug.LogError("[EdenAutoMorpher_ProfileSaver] Can't Find Neck Bones");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
float num = value.FirstOrDefault().position.y - sourceRoot.position.y;
|
|
||||||
if (Mathf.Approximately(num, 0f))
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"[EdenAutoMorpher_ProfileSaver] {sourceRoot.name} Neck Y가 0에 가까워 스케일 계산을 건너뜁니다. (neckY = {num})");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
float num2 = targetHeight / num;
|
|
||||||
Vector3 localScale = sourceRoot.localScale;
|
|
||||||
localScale *= num2;
|
|
||||||
sourceRoot.localScale = localScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveProfileToJson(ProfileData profileData, string savePath, string profileName)
|
|
||||||
{
|
|
||||||
if (profileData == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[EdenAutoMorpher_ProfileSaver] ProfileData is null. Abort save.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(profileName))
|
|
||||||
{
|
|
||||||
Debug.LogError("[EdenAutoMorpher_ProfileSaver] profileName is empty.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
string path = (profileName.EndsWith(".json") ? profileName : (profileName + ".json"));
|
|
||||||
string text = Path.Combine(Application.dataPath, savePath ?? string.Empty);
|
|
||||||
if (!Directory.Exists(text))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(text);
|
|
||||||
}
|
|
||||||
string text2 = Path.Combine(text, path);
|
|
||||||
string contents = JsonUtility.ToJson(profileData, prettyPrint: true);
|
|
||||||
File.WriteAllText(text2, contents);
|
|
||||||
Debug.Log("[EdenAutoMorpher_ProfileSaver] Profile saved successfully.\nPath: " + text2);
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsExistBaseData()
|
|
||||||
{
|
|
||||||
ProfileUtils profileUtils = new ProfileUtils();
|
|
||||||
return File.Exists(Path.Combine(Application.dataPath, profileUtils.GetBaseDataPath()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2fd1a8210b48a8d49843a3f2859e67b6
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.PCAData
|
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class PCAData
|
|
||||||
{
|
|
||||||
public Vector3 pcaCenter;
|
|
||||||
|
|
||||||
public Vector3 pcaPrincipalAxis;
|
|
||||||
|
|
||||||
public float pcaLength;
|
|
||||||
|
|
||||||
public float pcaAvgRadius;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ba923ad66ccb9824aa21217281bc8f03
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileBVH
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileBVH
|
|
||||||
{
|
|
||||||
public List<Vector3> vertices;
|
|
||||||
|
|
||||||
public profileBVHData[] datas;
|
|
||||||
|
|
||||||
public profileBVHNode[] nodes;
|
|
||||||
|
|
||||||
public int[] dataIndices;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ca85c008bacb4c04fab51354ef3d6365
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileBakedBodyMesh
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileBakedBodyMesh
|
|
||||||
{
|
|
||||||
public SkinnedMeshRenderer smr;
|
|
||||||
|
|
||||||
public Mesh bakedMesh;
|
|
||||||
|
|
||||||
public Vector3[] worldVertices;
|
|
||||||
|
|
||||||
public BoneWeight[] boneWeights
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!(this.smr != null))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this.smr.sharedMesh.boneWeights;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transform[] bones
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!(this.smr != null))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this.smr.bones;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileBakedBodyMesh(SkinnedMeshRenderer _smr)
|
|
||||||
{
|
|
||||||
if (_smr == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil - ProfileBakedBodyMesh] BakeBodyMesh Init : SkinnedMeshRenderer " + _smr.gameObject.name + " is null");
|
|
||||||
}
|
|
||||||
this.smr = _smr;
|
|
||||||
if (_smr.sharedMesh == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil - ProfileBakedBodyMesh] BakeBodyMesh Init : SkinnedMeshRenderer " + _smr.gameObject.name + " has null sharedMesh.");
|
|
||||||
}
|
|
||||||
this.bakedMesh = new Mesh();
|
|
||||||
this.smr.BakeMesh(this.bakedMesh);
|
|
||||||
this.worldVertices = this.CalculateWorldVertices(this.smr, this.bakedMesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ReBakeMesh()
|
|
||||||
{
|
|
||||||
this.smr.BakeMesh(this.bakedMesh);
|
|
||||||
this.worldVertices = this.CalculateWorldVertices(this.smr, this.bakedMesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
~ProfileBakedBodyMesh()
|
|
||||||
{
|
|
||||||
this.smr = null;
|
|
||||||
this.bakedMesh = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector3[] CalculateWorldVertices(SkinnedMeshRenderer smr, Mesh bakedMesh)
|
|
||||||
{
|
|
||||||
if (smr == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil - ProfileBakedBodyMesh] CalculateWorldVertices: smr " + smr.gameObject.name + " == null");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (bakedMesh == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Transform transform = smr.transform;
|
|
||||||
Vector3 lossyScale = transform.lossyScale;
|
|
||||||
Vector3 vector = new Vector3(1f / Mathf.Max(lossyScale.x, 1E-08f), 1f / Mathf.Max(lossyScale.y, 1E-08f), 1f / Mathf.Max(lossyScale.z, 1E-08f));
|
|
||||||
Matrix4x4 matrix4x = transform.localToWorldMatrix * Matrix4x4.Scale(vector);
|
|
||||||
Vector3[] vertices = bakedMesh.vertices;
|
|
||||||
int num = vertices.Length;
|
|
||||||
Vector3[] array = new Vector3[num];
|
|
||||||
for (int i = 0; i < num; i++)
|
|
||||||
{
|
|
||||||
array[i] = matrix4x.MultiplyPoint3x4(vertices[i]);
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1b9accce356c005478e76fd0fa193f3a
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileData
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class ProfileData
|
|
||||||
{
|
|
||||||
public int version = 1;
|
|
||||||
|
|
||||||
public float neckTargetHeight = 1.5f;
|
|
||||||
|
|
||||||
public BoneSpatialData NeckSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftUpperArmSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightUpperArmSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftLowerArmSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightLowerArmSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftLowerArm_HandSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightLowerArm_HandSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftUpperLegSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightUpperLegSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftFootSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightFootSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData ChestSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData UpperChestSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData IntegratedChestSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData SpineSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandThumbSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandThumbProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandThumbIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandThumbDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandIndexSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandIndexProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandIndexIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandIndexDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandMiddleSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandMiddleProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandMiddleIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandMiddleDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandRingSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandRingProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandRingIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandRingDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandLittleSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandLittleProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandLittleIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData LeftHandLittleDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandThumbSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandThumbProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandThumbIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandThumbDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandIndexSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandIndexProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandIndexIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandIndexDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandMiddleSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandMiddleProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandMiddleIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandMiddleDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandRingSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandRingProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandRingIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandRingDistalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandLittleSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandLittleProximalSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandLittleIntermediateSpatialData;
|
|
||||||
|
|
||||||
public BoneSpatialData RightHandLittleDistalSpatialData;
|
|
||||||
|
|
||||||
public int boneRootId;
|
|
||||||
|
|
||||||
public List<BoneData> bones;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: d62ebbd77f472fd4bb8abf3546d9d12a
|
|
||||||
@@ -1,264 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileUtil_IndexUtil
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileUtil_IndexUtil
|
|
||||||
{
|
|
||||||
public class BlockPermutations
|
|
||||||
{
|
|
||||||
private struct XorShift32
|
|
||||||
{
|
|
||||||
private uint _state;
|
|
||||||
|
|
||||||
public XorShift32(uint seed)
|
|
||||||
{
|
|
||||||
this._state = ((seed != 0) ? seed : 1831565813u);
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint NextUInt()
|
|
||||||
{
|
|
||||||
uint state = this._state;
|
|
||||||
state ^= state << 13;
|
|
||||||
state ^= state >> 17;
|
|
||||||
return this._state = state ^ (state << 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NextInt(int maxExclusive)
|
|
||||||
{
|
|
||||||
return (int)(this.NextUInt() % (uint)maxExclusive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly int _blockSize;
|
|
||||||
|
|
||||||
private int[] _px;
|
|
||||||
|
|
||||||
private int[] _py;
|
|
||||||
|
|
||||||
private int[] _pz;
|
|
||||||
|
|
||||||
private int[] _pall;
|
|
||||||
|
|
||||||
private uint _checksum;
|
|
||||||
|
|
||||||
private int _cachedLen = -1;
|
|
||||||
|
|
||||||
private int[] _pxLen;
|
|
||||||
|
|
||||||
private int[] _pyLen;
|
|
||||||
|
|
||||||
private int[] _pzLen;
|
|
||||||
|
|
||||||
private int[] _pallLen;
|
|
||||||
|
|
||||||
public BlockPermutations(int blockSize)
|
|
||||||
{
|
|
||||||
this._blockSize = blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Build(int seed)
|
|
||||||
{
|
|
||||||
if (this._blockSize <= 1)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_IndexUtil] BlockPermutations.Build - invalid blockSize");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
XorShift32 rng = new XorShift32((uint)(seed ^ -1556008596));
|
|
||||||
XorShift32 rng2 = new XorShift32((uint)(seed ^ -939442524));
|
|
||||||
XorShift32 rng3 = new XorShift32((uint)(seed ^ -1383041155));
|
|
||||||
XorShift32 rng4 = new XorShift32((uint)(seed ^ 0x7E95761E));
|
|
||||||
this._px = this.MakePermutation(this._blockSize, ref rng);
|
|
||||||
this._py = this.MakePermutation(this._blockSize, ref rng2);
|
|
||||||
this._pz = this.MakePermutation(this._blockSize, ref rng3);
|
|
||||||
this._pall = this.MakePermutation(this._blockSize, ref rng4);
|
|
||||||
this._checksum = this.ComputeChecksum(this._px, this._py, this._pz, this._pall);
|
|
||||||
this._cachedLen = -1;
|
|
||||||
this._pxLen = (this._pyLen = (this._pzLen = (this._pallLen = null)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ValidateRebuild(int seed)
|
|
||||||
{
|
|
||||||
uint checksum = this._checksum;
|
|
||||||
BlockPermutations blockPermutations = new BlockPermutations(this._blockSize);
|
|
||||||
blockPermutations.Build(seed);
|
|
||||||
return blockPermutations._checksum == checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetPermutationsForLen(int len, out int[] pxUse, out int[] pyUse, out int[] pzUse, out int[] pallUse)
|
|
||||||
{
|
|
||||||
if (len == this._blockSize)
|
|
||||||
{
|
|
||||||
pxUse = this._px;
|
|
||||||
pyUse = this._py;
|
|
||||||
pzUse = this._pz;
|
|
||||||
pallUse = this._pall;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this._cachedLen != len)
|
|
||||||
{
|
|
||||||
this._cachedLen = len;
|
|
||||||
this._pxLen = this.MakeSubPermutation(this._px, len);
|
|
||||||
this._pyLen = this.MakeSubPermutation(this._py, len);
|
|
||||||
this._pzLen = this.MakeSubPermutation(this._pz, len);
|
|
||||||
this._pallLen = this.MakeSubPermutation(this._pall, len);
|
|
||||||
}
|
|
||||||
pxUse = this._pxLen;
|
|
||||||
pyUse = this._pyLen;
|
|
||||||
pzUse = this._pzLen;
|
|
||||||
pallUse = this._pallLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int[] MakeSubPermutation(int[] fullPerm, int len)
|
|
||||||
{
|
|
||||||
int[] array = new int[len];
|
|
||||||
int num = 0;
|
|
||||||
for (int i = 0; i < fullPerm.Length; i++)
|
|
||||||
{
|
|
||||||
if (num >= len)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int num2 = fullPerm[i];
|
|
||||||
if (num2 < len)
|
|
||||||
{
|
|
||||||
array[num++] = num2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int[] MakePermutation(int n, ref XorShift32 rng)
|
|
||||||
{
|
|
||||||
int[] array = new int[n];
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
array[i] = i;
|
|
||||||
}
|
|
||||||
for (int num = n - 1; num > 0; num--)
|
|
||||||
{
|
|
||||||
int num2 = rng.NextInt(num + 1);
|
|
||||||
ref int reference = ref array[num];
|
|
||||||
ref int reference2 = ref array[num2];
|
|
||||||
int num3 = array[num2];
|
|
||||||
int num4 = array[num];
|
|
||||||
reference = num3;
|
|
||||||
reference2 = num4;
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
private uint ComputeChecksum(int[] a, int[] b, int[] c, int[] d)
|
|
||||||
{
|
|
||||||
uint h = 2166136261u;
|
|
||||||
this.MixArray(ref h, a);
|
|
||||||
this.MixArray(ref h, b);
|
|
||||||
this.MixArray(ref h, c);
|
|
||||||
this.MixArray(ref h, d);
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MixArray(ref uint h, int[] arr)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < arr.Length; i++)
|
|
||||||
{
|
|
||||||
uint num = (uint)arr[i];
|
|
||||||
h ^= num;
|
|
||||||
h *= 16777619u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly int blockSize = 9783;
|
|
||||||
|
|
||||||
private readonly BlockPermutations _perm;
|
|
||||||
|
|
||||||
private float[] _xTmp;
|
|
||||||
|
|
||||||
private float[] _yTmp;
|
|
||||||
|
|
||||||
private float[] _zTmp;
|
|
||||||
|
|
||||||
public ProfileUtil_IndexUtil(int blockSize = 9783)
|
|
||||||
{
|
|
||||||
this.blockSize = blockSize;
|
|
||||||
this._perm = new BlockPermutations(blockSize);
|
|
||||||
this._xTmp = new float[blockSize];
|
|
||||||
this._yTmp = new float[blockSize];
|
|
||||||
this._zTmp = new float[blockSize];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Build(int seed)
|
|
||||||
{
|
|
||||||
this._perm.Build(seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EncodeInto(Vector3[] input, Vector3[] output)
|
|
||||||
{
|
|
||||||
if (input == null || output == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_IndexUtil] EncodeInto - null args");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (output.Length < input.Length)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_IndexUtil] EncodeInto - output too small");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int num = input.Length;
|
|
||||||
int num2 = this.blockSize;
|
|
||||||
int num3 = (num + num2 - 1) / num2;
|
|
||||||
for (int i = 0; i < num3; i++)
|
|
||||||
{
|
|
||||||
int num4 = i * num2;
|
|
||||||
int num5 = Mathf.Min(num2, num - num4);
|
|
||||||
this._perm.GetPermutationsForLen(num5, out var pxUse, out var pyUse, out var pzUse, out var pallUse);
|
|
||||||
for (int j = 0; j < num5; j++)
|
|
||||||
{
|
|
||||||
Vector3 vector = input[num4 + j];
|
|
||||||
this._xTmp[pxUse[j]] = vector.x;
|
|
||||||
this._yTmp[pyUse[j]] = vector.y;
|
|
||||||
this._zTmp[pzUse[j]] = vector.z;
|
|
||||||
}
|
|
||||||
for (int k = 0; k < num5; k++)
|
|
||||||
{
|
|
||||||
int num6 = pallUse[k];
|
|
||||||
output[num4 + num6] = new Vector3(this._xTmp[k], this._yTmp[k], this._zTmp[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DecodeInto(Vector3[] encoded, Vector3[] output)
|
|
||||||
{
|
|
||||||
if (encoded == null || output == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_IndexUtil] DecodeInto - null args");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (output.Length < encoded.Length)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_IndexUtil] DecodeInto - output too small");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int num = encoded.Length;
|
|
||||||
int num2 = this.blockSize;
|
|
||||||
int num3 = (num + num2 - 1) / num2;
|
|
||||||
for (int i = 0; i < num3; i++)
|
|
||||||
{
|
|
||||||
int num4 = i * num2;
|
|
||||||
int num5 = Mathf.Min(num2, num - num4);
|
|
||||||
this._perm.GetPermutationsForLen(num5, out var pxUse, out var pyUse, out var pzUse, out var pallUse);
|
|
||||||
for (int j = 0; j < num5; j++)
|
|
||||||
{
|
|
||||||
int num6 = pallUse[j];
|
|
||||||
Vector3 vector = encoded[num4 + num6];
|
|
||||||
this._xTmp[j] = vector.x;
|
|
||||||
this._yTmp[j] = vector.y;
|
|
||||||
this._zTmp[j] = vector.z;
|
|
||||||
}
|
|
||||||
for (int k = 0; k < num5; k++)
|
|
||||||
{
|
|
||||||
output[num4 + k] = new Vector3(this._xTmp[pxUse[k]], this._yTmp[pyUse[k]], this._zTmp[pzUse[k]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 08f2754ac23e3bd419413380289a1d1f
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileUtils
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileUtils
|
|
||||||
{
|
|
||||||
private ProfileUtils_BoneUtil boneUtil;
|
|
||||||
|
|
||||||
private ProfileUtils_PoseUtil poseUtil;
|
|
||||||
|
|
||||||
private string profileBasePath = "@Eden_Tools\\Eden_AutoMorpher\\Profiles";
|
|
||||||
|
|
||||||
private string baseDataPath = "@Eden_Tools\\Eden_AutoMorpher\\ProfileSaver\\BaseData\\base.vb";
|
|
||||||
|
|
||||||
private int profileVersion = 1;
|
|
||||||
|
|
||||||
private string profileMagic = "PBVH";
|
|
||||||
|
|
||||||
private string baseMagic = "PVTB";
|
|
||||||
|
|
||||||
public ProfileUtils()
|
|
||||||
{
|
|
||||||
this.boneUtil = new ProfileUtils_BoneUtil();
|
|
||||||
this.poseUtil = new ProfileUtils_PoseUtil();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetProfileBasePath()
|
|
||||||
{
|
|
||||||
return this.profileBasePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetBaseDataPath()
|
|
||||||
{
|
|
||||||
return this.baseDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetProfileVersion()
|
|
||||||
{
|
|
||||||
return this.profileVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetProfileMagic()
|
|
||||||
{
|
|
||||||
return this.profileMagic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetBaseMagic()
|
|
||||||
{
|
|
||||||
return this.baseMagic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<HumanBodyBones, HashSet<Transform>> GetHumanoidMeshBoneMap(Animator animator, IReadOnlyList<SkinnedMeshRenderer> bodyMeshes, float posTolerance = 0.0001f, float weightThreshold = 0.0001f)
|
|
||||||
{
|
|
||||||
return this.boneUtil.GetHumanoidMeshBoneMap(animator, bodyMeshes, posTolerance, weightThreshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BoneSpatialData GetBoneSpatialData(HumanBodyBones refBone, HumanBodyBones[] influencedBones, Dictionary<HumanBodyBones, HashSet<Transform>> boneMap, List<ProfileBakedBodyMesh> sourceBodyBakedMeshes, bool addChildBones = false)
|
|
||||||
{
|
|
||||||
return this.poseUtil.GetBoneSpatialData(refBone, influencedBones, boneMap, sourceBodyBakedMeshes, addChildBones);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashSet<Transform> GetBodyMeshBones(SkinnedMeshRenderer smr, float weightThreshold = 0.0001f)
|
|
||||||
{
|
|
||||||
return this.boneUtil.GetBodyMeshBones(smr, weightThreshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BoneData> GetBoneDatas(Transform rootTransform, HashSet<Transform> avatarBones, Dictionary<HumanBodyBones, HashSet<Transform>> sourceBoneMap)
|
|
||||||
{
|
|
||||||
return this.boneUtil.GetBoneDatas(rootTransform, avatarBones, sourceBoneMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0575b5a00bd94c64d96d49da0465ee70
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileUtils_BVHUtil
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileUtils_BVHUtil
|
|
||||||
{
|
|
||||||
private const int LeafMaxTriangles = 4;
|
|
||||||
|
|
||||||
public ProfileBVH GetBVHData(Transform rootTransform, List<ProfileBakedBodyMesh> bakedBodyMeshes)
|
|
||||||
{
|
|
||||||
return this.BuildFromSkinnedMeshes(rootTransform, bakedBodyMeshes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileBVH BuildFromSkinnedMeshes(Transform rootTransform, List<ProfileBakedBodyMesh> bakedBodyMeshes)
|
|
||||||
{
|
|
||||||
ProfileBVH profileBVH = new ProfileBVH
|
|
||||||
{
|
|
||||||
vertices = new List<Vector3>(1024)
|
|
||||||
};
|
|
||||||
int num = 0;
|
|
||||||
foreach (ProfileBakedBodyMesh bakedBodyMesh in bakedBodyMeshes)
|
|
||||||
{
|
|
||||||
if (bakedBodyMesh != null && !(bakedBodyMesh.smr == null) && !(bakedBodyMesh.smr.sharedMesh == null))
|
|
||||||
{
|
|
||||||
num += bakedBodyMesh.smr.sharedMesh.triangles.Length / 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
profileBVH.datas = new profileBVHData[num];
|
|
||||||
Matrix4x4 worldToLocalMatrix = rootTransform.worldToLocalMatrix;
|
|
||||||
int num2 = 0;
|
|
||||||
foreach (ProfileBakedBodyMesh bakedBodyMesh2 in bakedBodyMeshes)
|
|
||||||
{
|
|
||||||
if (bakedBodyMesh2 != null && !(bakedBodyMesh2.smr == null) && !(bakedBodyMesh2.smr.sharedMesh == null))
|
|
||||||
{
|
|
||||||
int count = profileBVH.vertices.Count;
|
|
||||||
for (int i = 0; i < bakedBodyMesh2.worldVertices.Length; i++)
|
|
||||||
{
|
|
||||||
Vector3 item = worldToLocalMatrix.MultiplyPoint3x4(bakedBodyMesh2.worldVertices[i]);
|
|
||||||
profileBVH.vertices.Add(item);
|
|
||||||
}
|
|
||||||
int[] triangles = bakedBodyMesh2.smr.sharedMesh.triangles;
|
|
||||||
int num3 = triangles.Length / 3;
|
|
||||||
for (int j = 0; j < num3; j++)
|
|
||||||
{
|
|
||||||
int num4 = triangles[j * 3];
|
|
||||||
int num5 = triangles[j * 3 + 1];
|
|
||||||
int num6 = triangles[j * 3 + 2];
|
|
||||||
profileBVH.datas[num2++] = new profileBVHData
|
|
||||||
{
|
|
||||||
verA = count + num4,
|
|
||||||
verB = count + num5,
|
|
||||||
verC = count + num6
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int num7 = num;
|
|
||||||
int[] array = new int[num7];
|
|
||||||
for (int k = 0; k < num7; k++)
|
|
||||||
{
|
|
||||||
array[k] = k;
|
|
||||||
}
|
|
||||||
profileBVH.dataIndices = array;
|
|
||||||
List<profileBVHNode> list = new List<profileBVHNode>();
|
|
||||||
this.BuildRecursive(profileBVH, array, 0, num7, list);
|
|
||||||
profileBVH.nodes = list.ToArray();
|
|
||||||
return profileBVH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int BuildRecursive(ProfileBVH bvh, int[] triIndices, int start, int count, List<profileBVHNode> outNodes)
|
|
||||||
{
|
|
||||||
int count2 = outNodes.Count;
|
|
||||||
profileBVHNode profileBVHNode2 = new profileBVHNode();
|
|
||||||
Bounds bounds = default(Bounds);
|
|
||||||
bool flag = true;
|
|
||||||
for (int i = start; i < start + count; i++)
|
|
||||||
{
|
|
||||||
profileBVHData profileBVHData2 = bvh.datas[triIndices[i]];
|
|
||||||
Vector3 vector = bvh.vertices[profileBVHData2.verA];
|
|
||||||
Vector3 point = bvh.vertices[profileBVHData2.verB];
|
|
||||||
Vector3 point2 = bvh.vertices[profileBVHData2.verC];
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
bounds = new Bounds(vector, Vector3.zero);
|
|
||||||
bounds.Encapsulate(point);
|
|
||||||
bounds.Encapsulate(point2);
|
|
||||||
flag = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bounds.Encapsulate(vector);
|
|
||||||
bounds.Encapsulate(point);
|
|
||||||
bounds.Encapsulate(point2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
profileBVHNode2.bounds = bounds;
|
|
||||||
if (count <= 4)
|
|
||||||
{
|
|
||||||
profileBVHNode2.isLeaf = true;
|
|
||||||
profileBVHNode2.start = start;
|
|
||||||
profileBVHNode2.count = count;
|
|
||||||
profileBVHNode2.leftChild = -1;
|
|
||||||
profileBVHNode2.rightChild = -1;
|
|
||||||
outNodes.Add(profileBVHNode2);
|
|
||||||
return count2;
|
|
||||||
}
|
|
||||||
Vector3 size = bounds.size;
|
|
||||||
int num = 0;
|
|
||||||
if (size.y > size.x && size.y > size.z)
|
|
||||||
{
|
|
||||||
num = 1;
|
|
||||||
}
|
|
||||||
else if (size.z > size.x && size.z > size.y)
|
|
||||||
{
|
|
||||||
num = 2;
|
|
||||||
}
|
|
||||||
float num2 = 0f;
|
|
||||||
for (int j = start; j < start + count; j++)
|
|
||||||
{
|
|
||||||
profileBVHData profileBVHData3 = bvh.datas[triIndices[j]];
|
|
||||||
Vector3 vector2 = bvh.vertices[profileBVHData3.verA];
|
|
||||||
Vector3 vector3 = bvh.vertices[profileBVHData3.verB];
|
|
||||||
Vector3 vector4 = bvh.vertices[profileBVHData3.verC];
|
|
||||||
num2 += ((vector2 + vector3 + vector4) / 3f)[num];
|
|
||||||
}
|
|
||||||
num2 /= (float)count;
|
|
||||||
int num3 = this.Partition(bvh, triIndices, start, count, num, num2);
|
|
||||||
if (num3 == start || num3 == start + count)
|
|
||||||
{
|
|
||||||
num3 = start + count / 2;
|
|
||||||
}
|
|
||||||
profileBVHNode2.isLeaf = false;
|
|
||||||
profileBVHNode2.start = -1;
|
|
||||||
profileBVHNode2.count = 0;
|
|
||||||
outNodes.Add(profileBVHNode2);
|
|
||||||
int leftChild = this.BuildRecursive(bvh, triIndices, start, num3 - start, outNodes);
|
|
||||||
int rightChild = this.BuildRecursive(bvh, triIndices, num3, start + count - num3, outNodes);
|
|
||||||
profileBVHNode2.leftChild = leftChild;
|
|
||||||
profileBVHNode2.rightChild = rightChild;
|
|
||||||
outNodes[count2] = profileBVHNode2;
|
|
||||||
return count2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int Partition(ProfileBVH bvh, int[] triIndices, int start, int count, int axis, float splitPos)
|
|
||||||
{
|
|
||||||
int num = start;
|
|
||||||
int num2 = start + count - 1;
|
|
||||||
while (num <= num2)
|
|
||||||
{
|
|
||||||
profileBVHData profileBVHData2 = bvh.datas[triIndices[num]];
|
|
||||||
profileBVHData profileBVHData3 = bvh.datas[triIndices[num2]];
|
|
||||||
Vector3 vector = bvh.vertices[profileBVHData2.verA];
|
|
||||||
Vector3 vector2 = bvh.vertices[profileBVHData2.verB];
|
|
||||||
Vector3 vector3 = bvh.vertices[profileBVHData2.verC];
|
|
||||||
Vector3 vector4 = bvh.vertices[profileBVHData3.verA];
|
|
||||||
Vector3 vector5 = bvh.vertices[profileBVHData3.verB];
|
|
||||||
Vector3 vector6 = bvh.vertices[profileBVHData3.verC];
|
|
||||||
float num3 = (vector[axis] + vector2[axis] + vector3[axis]) / 3f;
|
|
||||||
_ = (vector4[axis] + vector5[axis] + vector6[axis]) / 3f;
|
|
||||||
if (num3 < splitPos)
|
|
||||||
{
|
|
||||||
num++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ref int reference = ref triIndices[num];
|
|
||||||
ref int reference2 = ref triIndices[num2];
|
|
||||||
int num4 = triIndices[num2];
|
|
||||||
int num5 = triIndices[num];
|
|
||||||
reference = num4;
|
|
||||||
reference2 = num5;
|
|
||||||
num2--;
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveProfileBVH(ProfileBVH bvh, string savePath, string profileName)
|
|
||||||
{
|
|
||||||
if (bvh == null || bvh.vertices == null || bvh.datas == null || bvh.nodes == null || bvh.dataIndices == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtils_BVHUtil] SaveProfileBVH - bvh or fields are null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ProfileUtils profileUtils = new ProfileUtils();
|
|
||||||
int num = new System.Random().Next(int.MinValue, int.MaxValue);
|
|
||||||
int count = bvh.vertices.Count;
|
|
||||||
int version;
|
|
||||||
int countInFile;
|
|
||||||
BaseKey3[] array = new ProfileUtils_VertexUtil().LoadTable(profileUtils.GetBaseDataPath(), out version, out countInFile);
|
|
||||||
if (array == null || array.Length == 0)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtils_BVHUtil] SaveProfileBVH - failed to load base vertex table");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Vector3[] array2 = bvh.vertices.ToArray();
|
|
||||||
for (int i = 0; i < array2.Length; i++)
|
|
||||||
{
|
|
||||||
array2[i] = this.TransformVec3(array2[i], array[i % array.Length]);
|
|
||||||
}
|
|
||||||
ProfileUtil_IndexUtil profileUtil_IndexUtil = new ProfileUtil_IndexUtil();
|
|
||||||
profileUtil_IndexUtil.Build(num);
|
|
||||||
Vector3[] array3 = new Vector3[array2.Length];
|
|
||||||
profileUtil_IndexUtil.EncodeInto(array2, array3);
|
|
||||||
StringBuilder stringBuilder = new StringBuilder(1024);
|
|
||||||
stringBuilder.Append(profileUtils.GetProfileMagic());
|
|
||||||
this.AppendHexInt(stringBuilder, profileUtils.GetProfileVersion());
|
|
||||||
this.AppendHexInt(stringBuilder, num);
|
|
||||||
this.AppendHexInt(stringBuilder, count);
|
|
||||||
this.AppendHexInt(stringBuilder, bvh.datas.Length);
|
|
||||||
this.AppendHexInt(stringBuilder, bvh.nodes.Length);
|
|
||||||
this.AppendHexInt(stringBuilder, bvh.dataIndices.Length);
|
|
||||||
for (int j = 0; j < array3.Length; j++)
|
|
||||||
{
|
|
||||||
this.AppendHexVec3(stringBuilder, array3[j]);
|
|
||||||
}
|
|
||||||
for (int k = 0; k < bvh.datas.Length; k++)
|
|
||||||
{
|
|
||||||
profileBVHData profileBVHData2 = bvh.datas[k];
|
|
||||||
this.AppendHexInt(stringBuilder, profileBVHData2.verA);
|
|
||||||
this.AppendHexInt(stringBuilder, profileBVHData2.verB);
|
|
||||||
this.AppendHexInt(stringBuilder, profileBVHData2.verC);
|
|
||||||
}
|
|
||||||
for (int l = 0; l < bvh.nodes.Length; l++)
|
|
||||||
{
|
|
||||||
profileBVHNode profileBVHNode2 = bvh.nodes[l];
|
|
||||||
this.AppendHexVec3(stringBuilder, profileBVHNode2.bounds.center);
|
|
||||||
this.AppendHexVec3(stringBuilder, profileBVHNode2.bounds.extents);
|
|
||||||
this.AppendHexInt(stringBuilder, profileBVHNode2.leftChild);
|
|
||||||
this.AppendHexInt(stringBuilder, profileBVHNode2.rightChild);
|
|
||||||
this.AppendHexInt(stringBuilder, profileBVHNode2.start);
|
|
||||||
this.AppendHexInt(stringBuilder, profileBVHNode2.count);
|
|
||||||
stringBuilder.Append(profileBVHNode2.isLeaf ? '1' : '0');
|
|
||||||
}
|
|
||||||
for (int m = 0; m < bvh.dataIndices.Length; m++)
|
|
||||||
{
|
|
||||||
this.AppendHexInt(stringBuilder, bvh.dataIndices[m]);
|
|
||||||
}
|
|
||||||
string path = (profileName.EndsWith(".eb") ? profileName : (profileName + ".eb"));
|
|
||||||
string text = Path.Combine(Application.dataPath, savePath ?? string.Empty);
|
|
||||||
if (!Directory.Exists(text))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(text);
|
|
||||||
}
|
|
||||||
File.WriteAllText(Path.Combine(text, path), stringBuilder.ToString(), Encoding.UTF8);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AppendHexVec3(StringBuilder sb, Vector3 v)
|
|
||||||
{
|
|
||||||
this.AppendHexFloat(sb, v.x);
|
|
||||||
this.AppendHexFloat(sb, v.y);
|
|
||||||
this.AppendHexFloat(sb, v.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AppendHexFloat(StringBuilder sb, float v)
|
|
||||||
{
|
|
||||||
int num = BitConverter.SingleToInt32Bits(v);
|
|
||||||
uint num2 = (uint)num;
|
|
||||||
sb.Append(num2.ToString("X8"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AppendHexInt(StringBuilder sb, int v)
|
|
||||||
{
|
|
||||||
uint num = (uint)v;
|
|
||||||
sb.Append(num.ToString("X8"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector3 TransformVec3(Vector3 v, BaseKey3 k)
|
|
||||||
{
|
|
||||||
return new Vector3(this.TransformFloatBits(v.x, k.x), this.TransformFloatBits(v.y, k.y), this.TransformFloatBits(v.z, k.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
private float TransformFloatBits(float a, uint keyBits)
|
|
||||||
{
|
|
||||||
return BitConverter.Int32BitsToSingle(BitConverter.SingleToInt32Bits(a) ^ (int)keyBits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: c2016668835db4f418cb2b3ef14bd00e
|
|
||||||
@@ -1,344 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileUtils_BoneUtil
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileUtils_BoneUtil
|
|
||||||
{
|
|
||||||
public HashSet<Transform> GetBodyMeshBones(SkinnedMeshRenderer smr, float weightThreshold = 0.0001f)
|
|
||||||
{
|
|
||||||
Mesh sharedMesh = smr.sharedMesh;
|
|
||||||
if (sharedMesh == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtils_BoneUtil] SkinnedMeshRenderer에 연결된 Mesh가 없습니다.");
|
|
||||||
return new HashSet<Transform>();
|
|
||||||
}
|
|
||||||
Transform[] bones = smr.bones;
|
|
||||||
BoneWeight[] boneWeights = sharedMesh.boneWeights;
|
|
||||||
HashSet<int> hashSet = new HashSet<int>();
|
|
||||||
BoneWeight[] array = boneWeights;
|
|
||||||
for (int i = 0; i < array.Length; i++)
|
|
||||||
{
|
|
||||||
BoneWeight boneWeight = array[i];
|
|
||||||
if (boneWeight.weight0 > weightThreshold)
|
|
||||||
{
|
|
||||||
hashSet.Add(boneWeight.boneIndex0);
|
|
||||||
}
|
|
||||||
if (boneWeight.weight1 > weightThreshold)
|
|
||||||
{
|
|
||||||
hashSet.Add(boneWeight.boneIndex1);
|
|
||||||
}
|
|
||||||
if (boneWeight.weight2 > weightThreshold)
|
|
||||||
{
|
|
||||||
hashSet.Add(boneWeight.boneIndex2);
|
|
||||||
}
|
|
||||||
if (boneWeight.weight3 > weightThreshold)
|
|
||||||
{
|
|
||||||
hashSet.Add(boneWeight.boneIndex3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HashSet<Transform> hashSet2 = new HashSet<Transform>();
|
|
||||||
foreach (int item in hashSet)
|
|
||||||
{
|
|
||||||
if (item >= 0 && item < bones.Length)
|
|
||||||
{
|
|
||||||
hashSet2.Add(bones[item]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hashSet2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<HumanBodyBones, HashSet<Transform>> GetHumanoidMeshBoneMap(Animator animator, IReadOnlyList<SkinnedMeshRenderer> bodyMeshes, float posTolerance = 0.0001f, float weightThreshold = 0.0001f)
|
|
||||||
{
|
|
||||||
Dictionary<HumanBodyBones, HashSet<Transform>> dictionary = new Dictionary<HumanBodyBones, HashSet<Transform>>();
|
|
||||||
if (animator == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[MeshHumanoidBoneMatcher] Animator is Empty");
|
|
||||||
return dictionary;
|
|
||||||
}
|
|
||||||
HashSet<Transform> hashSet = new HashSet<Transform>();
|
|
||||||
if (bodyMeshes != null)
|
|
||||||
{
|
|
||||||
foreach (SkinnedMeshRenderer bodyMesh in bodyMeshes)
|
|
||||||
{
|
|
||||||
if (bodyMesh == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach (Transform activeBone in this.GetActiveBones(bodyMesh, weightThreshold))
|
|
||||||
{
|
|
||||||
if (activeBone != null)
|
|
||||||
{
|
|
||||||
hashSet.Add(activeBone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 55; i++)
|
|
||||||
{
|
|
||||||
HumanBodyBones humanBodyBones = (HumanBodyBones)i;
|
|
||||||
Transform boneTransform = animator.GetBoneTransform(humanBodyBones);
|
|
||||||
if (boneTransform == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
HashSet<Transform> hashSet2 = new HashSet<Transform>();
|
|
||||||
hashSet2.Add(boneTransform);
|
|
||||||
foreach (Transform item in this.FindBonesByPosition(boneTransform, hashSet, posTolerance))
|
|
||||||
{
|
|
||||||
hashSet2.Add(item);
|
|
||||||
}
|
|
||||||
dictionary[humanBodyBones] = hashSet2;
|
|
||||||
}
|
|
||||||
return dictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashSet<Transform> GetActiveBones(SkinnedMeshRenderer smr, float weightThreshold = 0.0001f)
|
|
||||||
{
|
|
||||||
Mesh sharedMesh = smr.sharedMesh;
|
|
||||||
if (sharedMesh == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("SkinnedMeshRenderer에 연결된 Mesh가 없습니다.");
|
|
||||||
return new HashSet<Transform>();
|
|
||||||
}
|
|
||||||
Transform[] bones = smr.bones;
|
|
||||||
BoneWeight[] boneWeights = sharedMesh.boneWeights;
|
|
||||||
HashSet<int> hashSet = new HashSet<int>();
|
|
||||||
BoneWeight[] array = boneWeights;
|
|
||||||
for (int i = 0; i < array.Length; i++)
|
|
||||||
{
|
|
||||||
BoneWeight boneWeight = array[i];
|
|
||||||
if (boneWeight.weight0 > weightThreshold)
|
|
||||||
{
|
|
||||||
hashSet.Add(boneWeight.boneIndex0);
|
|
||||||
}
|
|
||||||
if (boneWeight.weight1 > weightThreshold)
|
|
||||||
{
|
|
||||||
hashSet.Add(boneWeight.boneIndex1);
|
|
||||||
}
|
|
||||||
if (boneWeight.weight2 > weightThreshold)
|
|
||||||
{
|
|
||||||
hashSet.Add(boneWeight.boneIndex2);
|
|
||||||
}
|
|
||||||
if (boneWeight.weight3 > weightThreshold)
|
|
||||||
{
|
|
||||||
hashSet.Add(boneWeight.boneIndex3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HashSet<Transform> hashSet2 = new HashSet<Transform>();
|
|
||||||
foreach (int item in hashSet)
|
|
||||||
{
|
|
||||||
if (item >= 0 && item < bones.Length)
|
|
||||||
{
|
|
||||||
hashSet2.Add(bones[item]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hashSet2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Transform> FindBonesByPosition(Transform boneToCheck, HashSet<Transform> smrBoneSet, float posTolerance = 0.0001f)
|
|
||||||
{
|
|
||||||
List<Transform> list = new List<Transform>();
|
|
||||||
if (boneToCheck == null)
|
|
||||||
{
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
float num = posTolerance * posTolerance;
|
|
||||||
Vector3 position = boneToCheck.position;
|
|
||||||
foreach (Transform item in smrBoneSet)
|
|
||||||
{
|
|
||||||
if (!(item == null) && !(item == boneToCheck) && this.NameMatches(item.gameObject.name, boneToCheck.gameObject.name) && (item.position - position).sqrMagnitude <= num)
|
|
||||||
{
|
|
||||||
list.Add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string[] TokenizeBoneName(string name)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
|
||||||
{
|
|
||||||
return Array.Empty<string>();
|
|
||||||
}
|
|
||||||
char[] separator = new char[5] { '-', '_', ':', '.', '|' };
|
|
||||||
name = name.Trim();
|
|
||||||
return name.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool NameMatches(string boneToCheckName, string candidateName)
|
|
||||||
{
|
|
||||||
string[] array = this.TokenizeBoneName(boneToCheckName);
|
|
||||||
string[] array2 = this.TokenizeBoneName(candidateName);
|
|
||||||
if (array.Length == 0 || array2.Length == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!array[0].Equals(array2[0], StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (array.Length > 1 && array2.Length > 1 && !array[1].Equals(array2[1], StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BoneData> GetBoneDatas(Transform rootTransform, HashSet<Transform> avatarBones, Dictionary<HumanBodyBones, HashSet<Transform>> sourceBoneMap)
|
|
||||||
{
|
|
||||||
Dictionary<Transform, HumanBodyBones> dictionary = new Dictionary<Transform, HumanBodyBones>();
|
|
||||||
foreach (KeyValuePair<HumanBodyBones, HashSet<Transform>> item2 in sourceBoneMap)
|
|
||||||
{
|
|
||||||
HumanBodyBones key = item2.Key;
|
|
||||||
HashSet<Transform> value = item2.Value;
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach (Transform item3 in value)
|
|
||||||
{
|
|
||||||
if (!(item3 == null) && !dictionary.ContainsKey(item3))
|
|
||||||
{
|
|
||||||
dictionary[item3] = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<BoneData> list = new List<BoneData>();
|
|
||||||
BoneData item = new BoneData
|
|
||||||
{
|
|
||||||
id = 0,
|
|
||||||
boneName = ((rootTransform != null) ? rootTransform.name : "Root"),
|
|
||||||
parentName = null,
|
|
||||||
hierarchyPath = "",
|
|
||||||
hBone = HumanBodyBones.LastBone,
|
|
||||||
parentId = -1,
|
|
||||||
childrenIds = new List<int>(),
|
|
||||||
rootLocalPosition = Vector3.zero,
|
|
||||||
rootLocalRotation = Quaternion.identity,
|
|
||||||
rootLocalScale = Vector3.one
|
|
||||||
};
|
|
||||||
list.Add(item);
|
|
||||||
List<Transform> list2 = (from t in avatarBones
|
|
||||||
where t != null
|
|
||||||
orderby this.GetDepthFromSkeletonRoot(rootTransform, t), this.GetHierarchyPath(rootTransform, t)
|
|
||||||
select t).ToList();
|
|
||||||
Dictionary<Transform, int> dictionary2 = new Dictionary<Transform, int>(list2.Count);
|
|
||||||
int num = 1;
|
|
||||||
foreach (Transform item4 in list2)
|
|
||||||
{
|
|
||||||
dictionary2[item4] = num++;
|
|
||||||
string hierarchyPath = this.GetHierarchyPath(rootTransform, item4);
|
|
||||||
HumanBodyBones value2;
|
|
||||||
HumanBodyBones hBone = (dictionary.TryGetValue(item4, out value2) ? value2 : HumanBodyBones.LastBone);
|
|
||||||
Vector3 rootLocalPosition = ((rootTransform != null) ? rootTransform.InverseTransformPoint(item4.position) : item4.position);
|
|
||||||
Quaternion rootLocalRotation = ((rootTransform != null) ? (Quaternion.Inverse(rootTransform.rotation) * item4.rotation) : item4.rotation);
|
|
||||||
Vector3 rootLocalScale = item4.lossyScale;
|
|
||||||
if (rootTransform != null)
|
|
||||||
{
|
|
||||||
Vector3 lossyScale = rootTransform.lossyScale;
|
|
||||||
rootLocalScale = new Vector3(this.SafeDiv(rootLocalScale.x, lossyScale.x), this.SafeDiv(rootLocalScale.y, lossyScale.y), this.SafeDiv(rootLocalScale.z, lossyScale.z));
|
|
||||||
}
|
|
||||||
list.Add(new BoneData
|
|
||||||
{
|
|
||||||
id = dictionary2[item4],
|
|
||||||
boneName = item4.name,
|
|
||||||
parentName = ((item4.parent != null) ? item4.parent.name : ""),
|
|
||||||
hierarchyPath = hierarchyPath,
|
|
||||||
hBone = hBone,
|
|
||||||
parentId = -1,
|
|
||||||
childrenIds = new List<int>(),
|
|
||||||
rootLocalPosition = rootLocalPosition,
|
|
||||||
rootLocalRotation = rootLocalRotation,
|
|
||||||
rootLocalScale = rootLocalScale
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Dictionary<int, List<int>> dictionary3 = new Dictionary<int, List<int>>();
|
|
||||||
foreach (BoneData item5 in list)
|
|
||||||
{
|
|
||||||
dictionary3[item5.id] = new List<int>();
|
|
||||||
}
|
|
||||||
foreach (BoneData node in list.Where((BoneData n) => n.id != 0))
|
|
||||||
{
|
|
||||||
Transform key2 = dictionary2.FirstOrDefault((KeyValuePair<Transform, int> kv) => kv.Value == node.id).Key;
|
|
||||||
int num2 = 0;
|
|
||||||
if (key2 != null)
|
|
||||||
{
|
|
||||||
Transform parent = key2.parent;
|
|
||||||
while (parent != null)
|
|
||||||
{
|
|
||||||
if (dictionary2.TryGetValue(parent, out var value3))
|
|
||||||
{
|
|
||||||
num2 = value3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (parent == rootTransform)
|
|
||||||
{
|
|
||||||
num2 = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
parent = parent.parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node.parentId = num2;
|
|
||||||
dictionary3[num2].Add(node.id);
|
|
||||||
}
|
|
||||||
foreach (BoneData item6 in list)
|
|
||||||
{
|
|
||||||
item6.childrenIds = dictionary3[item6.id];
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private float SafeDiv(float a, float b)
|
|
||||||
{
|
|
||||||
if (!(Mathf.Abs(b) < 1E-08f))
|
|
||||||
{
|
|
||||||
return a / b;
|
|
||||||
}
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int GetDepthFromSkeletonRoot(Transform root, Transform t)
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
Transform transform = t;
|
|
||||||
while (transform != null && transform != root)
|
|
||||||
{
|
|
||||||
num++;
|
|
||||||
transform = transform.parent;
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetHierarchyPath(Transform root, Transform t)
|
|
||||||
{
|
|
||||||
if (t == null)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (root == null)
|
|
||||||
{
|
|
||||||
return t.name;
|
|
||||||
}
|
|
||||||
if (!t.IsChildOf(root) && t != root)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtils_BoneUtil] GetHierarchyPath - bone " + t.name + " is not child of root " + root.name);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (t == root)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
Stack<string> stack = new Stack<string>();
|
|
||||||
Transform transform = t;
|
|
||||||
while (transform != null && transform != root)
|
|
||||||
{
|
|
||||||
stack.Push(transform.name);
|
|
||||||
transform = transform.parent;
|
|
||||||
}
|
|
||||||
return string.Join("/", stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b987b9b34807b3b48b843afcb2aefa28
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileUtils_PCAUtil
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileUtils_PCAUtil
|
|
||||||
{
|
|
||||||
public PCAData ComputeRegionStats(IList<Vector3> points)
|
|
||||||
{
|
|
||||||
PCAData pCAData = new PCAData();
|
|
||||||
if (points == null || points.Count == 0)
|
|
||||||
{
|
|
||||||
return pCAData;
|
|
||||||
}
|
|
||||||
int count = points.Count;
|
|
||||||
Vector3 zero = Vector3.zero;
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
zero += points[i];
|
|
||||||
}
|
|
||||||
zero /= (float)count;
|
|
||||||
float num = 0f;
|
|
||||||
float num2 = 0f;
|
|
||||||
float num3 = 0f;
|
|
||||||
float num4 = 0f;
|
|
||||||
float num5 = 0f;
|
|
||||||
float num6 = 0f;
|
|
||||||
for (int j = 0; j < count; j++)
|
|
||||||
{
|
|
||||||
Vector3 vector = points[j] - zero;
|
|
||||||
num += vector.x * vector.x;
|
|
||||||
num2 += vector.x * vector.y;
|
|
||||||
num3 += vector.x * vector.z;
|
|
||||||
num4 += vector.y * vector.y;
|
|
||||||
num5 += vector.y * vector.z;
|
|
||||||
num6 += vector.z * vector.z;
|
|
||||||
}
|
|
||||||
float num7 = 1f / (float)count;
|
|
||||||
num *= num7;
|
|
||||||
num2 *= num7;
|
|
||||||
num3 *= num7;
|
|
||||||
num4 *= num7;
|
|
||||||
num5 *= num7;
|
|
||||||
num6 *= num7;
|
|
||||||
this.JacobiEigenDecomposition3x3(num, num2, num3, num4, num5, num6, out var eigenValues, out var eigenVectors);
|
|
||||||
int num8 = 0;
|
|
||||||
if (eigenValues[1] > eigenValues[num8])
|
|
||||||
{
|
|
||||||
num8 = 1;
|
|
||||||
}
|
|
||||||
if (eigenValues[2] > eigenValues[num8])
|
|
||||||
{
|
|
||||||
num8 = 2;
|
|
||||||
}
|
|
||||||
Vector3 normalized = eigenVectors[num8].normalized;
|
|
||||||
float num9 = float.PositiveInfinity;
|
|
||||||
float num10 = float.NegativeInfinity;
|
|
||||||
float num11 = 0f;
|
|
||||||
for (int k = 0; k < count; k++)
|
|
||||||
{
|
|
||||||
float num12 = Vector3.Dot(points[k] - zero, normalized);
|
|
||||||
if (num12 < num9)
|
|
||||||
{
|
|
||||||
num9 = num12;
|
|
||||||
}
|
|
||||||
if (num12 > num10)
|
|
||||||
{
|
|
||||||
num10 = num12;
|
|
||||||
}
|
|
||||||
Vector3 vector2 = zero + normalized * num12;
|
|
||||||
float magnitude = (points[k] - vector2).magnitude;
|
|
||||||
num11 += magnitude;
|
|
||||||
}
|
|
||||||
pCAData.pcaCenter = zero;
|
|
||||||
pCAData.pcaPrincipalAxis = normalized;
|
|
||||||
pCAData.pcaLength = num10 - num9;
|
|
||||||
pCAData.pcaAvgRadius = num11 / (float)count;
|
|
||||||
return pCAData;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void JacobiEigenDecomposition3x3(float c00, float c01, float c02, float c11, float c12, float c22, out float[] eigenValues, out Vector3[] eigenVectors)
|
|
||||||
{
|
|
||||||
float[,] array = new float[3, 3]
|
|
||||||
{
|
|
||||||
{ c00, c01, c02 },
|
|
||||||
{ c01, c11, c12 },
|
|
||||||
{ c02, c12, c22 }
|
|
||||||
};
|
|
||||||
float[,] array2 = new float[3, 3]
|
|
||||||
{
|
|
||||||
{ 1f, 0f, 0f },
|
|
||||||
{ 0f, 1f, 0f },
|
|
||||||
{ 0f, 0f, 1f }
|
|
||||||
};
|
|
||||||
for (int i = 0; i < 32; i++)
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
int num2 = 1;
|
|
||||||
float num3 = Mathf.Abs(array[0, 1]);
|
|
||||||
float num4 = Mathf.Abs(array[0, 2]);
|
|
||||||
if (num4 > num3)
|
|
||||||
{
|
|
||||||
num3 = num4;
|
|
||||||
num = 0;
|
|
||||||
num2 = 2;
|
|
||||||
}
|
|
||||||
float num5 = Mathf.Abs(array[1, 2]);
|
|
||||||
if (num5 > num3)
|
|
||||||
{
|
|
||||||
num3 = num5;
|
|
||||||
num = 1;
|
|
||||||
num2 = 2;
|
|
||||||
}
|
|
||||||
if (num3 < 1E-10f)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
float num6 = array[num, num];
|
|
||||||
float num7 = array[num2, num2];
|
|
||||||
float num8 = array[num, num2];
|
|
||||||
float f = 0.5f * Mathf.Atan2(2f * num8, num7 - num6);
|
|
||||||
float num9 = Mathf.Cos(f);
|
|
||||||
float num10 = Mathf.Sin(f);
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
if (j != num && j != num2)
|
|
||||||
{
|
|
||||||
float num11 = array[j, num];
|
|
||||||
float num12 = array[j, num2];
|
|
||||||
array[j, num] = num9 * num11 - num10 * num12;
|
|
||||||
array[num, j] = array[j, num];
|
|
||||||
array[j, num2] = num10 * num11 + num9 * num12;
|
|
||||||
array[num2, j] = array[j, num2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float num13 = num9 * num9 * num6 - 2f * num10 * num9 * num8 + num10 * num10 * num7;
|
|
||||||
float num14 = num10 * num10 * num6 + 2f * num10 * num9 * num8 + num9 * num9 * num7;
|
|
||||||
array[num, num] = num13;
|
|
||||||
array[num2, num2] = num14;
|
|
||||||
array[num, num2] = 0f;
|
|
||||||
array[num2, num] = 0f;
|
|
||||||
for (int k = 0; k < 3; k++)
|
|
||||||
{
|
|
||||||
float num15 = array2[k, num];
|
|
||||||
float num16 = array2[k, num2];
|
|
||||||
array2[k, num] = num9 * num15 - num10 * num16;
|
|
||||||
array2[k, num2] = num10 * num15 + num9 * num16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eigenValues = new float[3];
|
|
||||||
eigenVectors = new Vector3[3];
|
|
||||||
eigenValues[0] = array[0, 0];
|
|
||||||
eigenValues[1] = array[1, 1];
|
|
||||||
eigenValues[2] = array[2, 2];
|
|
||||||
eigenVectors[0] = new Vector3(array2[0, 0], array2[1, 0], array2[2, 0]);
|
|
||||||
eigenVectors[1] = new Vector3(array2[0, 1], array2[1, 1], array2[2, 1]);
|
|
||||||
eigenVectors[2] = new Vector3(array2[0, 2], array2[1, 2], array2[2, 2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 404cff939caffe44bbb6cfbb33580445
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileUtils_PoseUtil
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileUtils_PoseUtil
|
|
||||||
{
|
|
||||||
public BoneSpatialData GetBoneSpatialData(HumanBodyBones refBone, HumanBodyBones[] influencedBones, Dictionary<HumanBodyBones, HashSet<Transform>> boneMap, List<ProfileBakedBodyMesh> sourceBodyBakedMeshes, bool addChildBones = false)
|
|
||||||
{
|
|
||||||
BoneSpatialData boneSpatialData = new BoneSpatialData();
|
|
||||||
boneSpatialData.refBone = refBone;
|
|
||||||
Transform baseBoneFromBoneMap = this.GetBaseBoneFromBoneMap(boneMap, refBone);
|
|
||||||
if (baseBoneFromBoneMap == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
List<Vector3> refVertices = this.GetRefVertices(influencedBones, boneMap, sourceBodyBakedMeshes, addChildBones);
|
|
||||||
boneSpatialData.pcaData = this.GetPCAData(baseBoneFromBoneMap, refVertices);
|
|
||||||
Transform baseBoneFromBoneMap2 = this.GetBaseBoneFromBoneMap(boneMap, HumanBodyBones.Hips);
|
|
||||||
boneSpatialData.volumeData = this.GetVolumeData(baseBoneFromBoneMap, baseBoneFromBoneMap2, refVertices);
|
|
||||||
return boneSpatialData;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Vector3> GetRefVertices(HumanBodyBones[] influencedBones, Dictionary<HumanBodyBones, HashSet<Transform>> boneMap, List<ProfileBakedBodyMesh> sourceBodyBakedMeshes, bool addChildBones = false, float weightThreshold = 0.15f, int sampleStep = 1)
|
|
||||||
{
|
|
||||||
List<Vector3> list = new List<Vector3>();
|
|
||||||
HashSet<Transform> targetBoneSet = new HashSet<Transform>();
|
|
||||||
foreach (HumanBodyBones key in influencedBones)
|
|
||||||
{
|
|
||||||
if (!boneMap.TryGetValue(key, out var value) || value == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach (Transform item in value)
|
|
||||||
{
|
|
||||||
if (item != null)
|
|
||||||
{
|
|
||||||
targetBoneSet.Add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (targetBoneSet.Count == 0)
|
|
||||||
{
|
|
||||||
string text = string.Join(", ", influencedBones.Select((HumanBodyBones b) => b.ToString()));
|
|
||||||
Debug.LogError("[ProfileSaver_PoseUtil] CollectBodyPartVerticesWorld: targetBoneSet is empty.\nMissing Humanoid Set : " + text);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
if (addChildBones)
|
|
||||||
{
|
|
||||||
Transform[] array = targetBoneSet.ToArray();
|
|
||||||
targetBoneSet.Clear();
|
|
||||||
Transform[] array2 = array;
|
|
||||||
for (int i = 0; i < array2.Length; i++)
|
|
||||||
{
|
|
||||||
AddDescendants(array2[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (ProfileBakedBodyMesh sourceBodyBakedMesh in sourceBodyBakedMeshes)
|
|
||||||
{
|
|
||||||
BoneWeight[] boneWeights = sourceBodyBakedMesh.boneWeights;
|
|
||||||
Transform[] bones = sourceBodyBakedMesh.bones;
|
|
||||||
if (boneWeights == null || boneWeights.Length == 0 || bones == null || bones.Length == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Vector3[] worldVertices = sourceBodyBakedMesh.worldVertices;
|
|
||||||
if (worldVertices == null || worldVertices.Length == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int num = Mathf.Min(worldVertices.Length, boneWeights.Length);
|
|
||||||
for (int num2 = 0; num2 < num; num2 += sampleStep)
|
|
||||||
{
|
|
||||||
BoneWeight boneWeight = boneWeights[num2];
|
|
||||||
float wSum = 0f;
|
|
||||||
Acc(boneWeight.boneIndex0, boneWeight.weight0);
|
|
||||||
Acc(boneWeight.boneIndex1, boneWeight.weight1);
|
|
||||||
Acc(boneWeight.boneIndex2, boneWeight.weight2);
|
|
||||||
Acc(boneWeight.boneIndex3, boneWeight.weight3);
|
|
||||||
if (!(wSum < weightThreshold))
|
|
||||||
{
|
|
||||||
list.Add(worldVertices[num2]);
|
|
||||||
}
|
|
||||||
void Acc(int index, float w)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < bones.Length && !(w <= 0f))
|
|
||||||
{
|
|
||||||
Transform transform = bones[index];
|
|
||||||
if (transform != null && targetBoneSet.Contains(transform))
|
|
||||||
{
|
|
||||||
wSum += w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
void AddDescendants(Transform t)
|
|
||||||
{
|
|
||||||
if (!(t == null) && targetBoneSet.Add(t))
|
|
||||||
{
|
|
||||||
for (int j = 0; j < t.childCount; j++)
|
|
||||||
{
|
|
||||||
AddDescendants(t.GetChild(j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private PCAData GetPCAData(Transform originTransform, List<Vector3> points)
|
|
||||||
{
|
|
||||||
PCAData pCAData = new ProfileUtils_PCAUtil().ComputeRegionStats(points);
|
|
||||||
if (originTransform == null)
|
|
||||||
{
|
|
||||||
return pCAData;
|
|
||||||
}
|
|
||||||
PCAData result = new PCAData
|
|
||||||
{
|
|
||||||
pcaCenter = originTransform.InverseTransformPoint(pCAData.pcaCenter),
|
|
||||||
pcaPrincipalAxis = originTransform.InverseTransformDirection(pCAData.pcaPrincipalAxis).normalized,
|
|
||||||
pcaLength = pCAData.pcaLength,
|
|
||||||
pcaAvgRadius = pCAData.pcaAvgRadius
|
|
||||||
};
|
|
||||||
if (Mathf.Abs(pCAData.pcaLength) < 0.0001f)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[ProfileUtils_PoseUtil] GetPCAData - " + originTransform.name + " Pca Length is to Small");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private VolumeData GetVolumeData(Transform originTransform, Transform axisTransform, List<Vector3> points)
|
|
||||||
{
|
|
||||||
return new ProfileUtils_VolumeUtil().GetVolumeData(originTransform, axisTransform, points);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Transform GetBaseBoneFromBoneMap(Dictionary<HumanBodyBones, HashSet<Transform>> boneMap, HumanBodyBones bone)
|
|
||||||
{
|
|
||||||
if (boneMap == null || !boneMap.TryGetValue(bone, out var value) || value == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.FirstOrDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 094b9fc668fbf684aa9bd5db84b2aaad
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileUtils_VertexUtil
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileUtils_VertexUtil
|
|
||||||
{
|
|
||||||
public BaseKey3[] LoadTable(string path, out int version, out int countInFile)
|
|
||||||
{
|
|
||||||
version = 0;
|
|
||||||
countInFile = 0;
|
|
||||||
if (string.IsNullOrEmpty(path))
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_VertexUtil] LoadTable - path is null or empty");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
path = Path.Combine(Application.dataPath, path);
|
|
||||||
if (!File.Exists(path))
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_VertexUtil] LoadTable - file not found");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
string text;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
text = File.ReadAllText(path, Encoding.UTF8);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_VertexUtil] LoadTable - read failed: " + ex.Message);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int num = 0;
|
|
||||||
string baseMagic = new ProfileUtils().GetBaseMagic();
|
|
||||||
if (text.Length < 4 || text.Substring(0, 4) != baseMagic)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_VertexUtil] LoadTable - MAGIC mismatch");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
num += 4;
|
|
||||||
version = this.ReadHexIntSafe(text, ref num);
|
|
||||||
countInFile = this.ReadHexIntSafe(text, ref num);
|
|
||||||
if (countInFile <= 0)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_VertexUtil] LoadTable - invalid count");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
BaseKey3[] array = new BaseKey3[countInFile];
|
|
||||||
for (int i = 0; i < countInFile; i++)
|
|
||||||
{
|
|
||||||
array[i] = this.ReadHexKey3Safe(text, ref num);
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int ReadHexIntSafe(string s, ref int p)
|
|
||||||
{
|
|
||||||
if (p + 8 > s.Length)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtil_VertexUtil] ReadHexIntSafe - out of range");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
string value = s.Substring(p, 8);
|
|
||||||
p += 8;
|
|
||||||
return (int)Convert.ToUInt32(value, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BaseKey3 ReadHexKey3Safe(string s, ref int p)
|
|
||||||
{
|
|
||||||
int x = this.ReadHexIntSafe(s, ref p);
|
|
||||||
uint y = (uint)this.ReadHexIntSafe(s, ref p);
|
|
||||||
uint z = (uint)this.ReadHexIntSafe(s, ref p);
|
|
||||||
return new BaseKey3((uint)x, y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 26eb8c4f9b6a08e4abb70a33d9b81ccf
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.ProfileUtils_VolumeUtil
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class ProfileUtils_VolumeUtil
|
|
||||||
{
|
|
||||||
public VolumeData GetVolumeData(Transform originTransform, Transform axisTransform, List<Vector3> points, int sampleStep = 1)
|
|
||||||
{
|
|
||||||
if (originTransform == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtils_VolumeUtil] originTransform is null");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (axisTransform == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtils_VolumeUtil] axisTransform is null");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (points == null || points.Count == 0)
|
|
||||||
{
|
|
||||||
Debug.LogError("[ProfileUtils_VolumeUtil] There is No Points to calculate volume");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
VolumeData volumeData = new VolumeData();
|
|
||||||
Vector3 forward = axisTransform.forward;
|
|
||||||
Vector3 right = axisTransform.right;
|
|
||||||
Vector3 up = axisTransform.up;
|
|
||||||
float num = float.PositiveInfinity;
|
|
||||||
float num2 = float.NegativeInfinity;
|
|
||||||
float num3 = float.PositiveInfinity;
|
|
||||||
float num4 = float.NegativeInfinity;
|
|
||||||
float num5 = float.PositiveInfinity;
|
|
||||||
float num6 = float.NegativeInfinity;
|
|
||||||
for (int i = 0; i < points.Count; i += sampleStep)
|
|
||||||
{
|
|
||||||
Vector3 lhs = points[i] - originTransform.position;
|
|
||||||
float num7 = Vector3.Dot(lhs, up);
|
|
||||||
if (num7 < num)
|
|
||||||
{
|
|
||||||
num = num7;
|
|
||||||
}
|
|
||||||
if (num7 > num2)
|
|
||||||
{
|
|
||||||
num2 = num7;
|
|
||||||
}
|
|
||||||
float num8 = Vector3.Dot(lhs, forward);
|
|
||||||
if (num8 < num3)
|
|
||||||
{
|
|
||||||
num3 = num8;
|
|
||||||
}
|
|
||||||
if (num8 > num4)
|
|
||||||
{
|
|
||||||
num4 = num8;
|
|
||||||
}
|
|
||||||
float num9 = Vector3.Dot(lhs, right);
|
|
||||||
if (num9 < num5)
|
|
||||||
{
|
|
||||||
num5 = num9;
|
|
||||||
}
|
|
||||||
if (num9 > num6)
|
|
||||||
{
|
|
||||||
num6 = num9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
volumeData.forwardDir = forward;
|
|
||||||
volumeData.rightDir = right;
|
|
||||||
volumeData.upDir = up;
|
|
||||||
volumeData.fMaxLocalPos = originTransform.InverseTransformPoint(originTransform.position + forward * num4);
|
|
||||||
volumeData.fMinLocalPos = originTransform.InverseTransformPoint(originTransform.position + forward * num3);
|
|
||||||
volumeData.rMaxLocalPos = originTransform.InverseTransformPoint(originTransform.position + right * num6);
|
|
||||||
volumeData.rMinLocalPos = originTransform.InverseTransformPoint(originTransform.position + right * num5);
|
|
||||||
volumeData.uMaxLocalPos = originTransform.InverseTransformPoint(originTransform.position + up * num2);
|
|
||||||
volumeData.uMinLocalPos = originTransform.InverseTransformPoint(originTransform.position + up * num);
|
|
||||||
return volumeData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b1bc4188262eb1140b111907361dfc56
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.VolumeData
|
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class VolumeData
|
|
||||||
{
|
|
||||||
public Vector3 forwardDir;
|
|
||||||
|
|
||||||
public Vector3 rightDir;
|
|
||||||
|
|
||||||
public Vector3 upDir;
|
|
||||||
|
|
||||||
public Vector3 fMaxLocalPos;
|
|
||||||
|
|
||||||
public Vector3 fMinLocalPos;
|
|
||||||
|
|
||||||
public Vector3 rMaxLocalPos;
|
|
||||||
|
|
||||||
public Vector3 rMinLocalPos;
|
|
||||||
|
|
||||||
public Vector3 uMaxLocalPos;
|
|
||||||
|
|
||||||
public Vector3 uMinLocalPos;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: c9990806ed64171428cb56bac9d781fa
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.profileBVHData
|
|
||||||
public class profileBVHData
|
|
||||||
{
|
|
||||||
public int verA;
|
|
||||||
|
|
||||||
public int verB;
|
|
||||||
|
|
||||||
public int verC;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 3e693ae64a726864a88a172c17d13af9
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
// EdenAutoMorpher_ProfileSaver_Script, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
||||||
// Eden.AutoMorpher.profile.profileBVHNode
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class profileBVHNode
|
|
||||||
{
|
|
||||||
public Bounds bounds;
|
|
||||||
|
|
||||||
public int leftChild;
|
|
||||||
|
|
||||||
public int rightChild;
|
|
||||||
|
|
||||||
public int start;
|
|
||||||
|
|
||||||
public int count;
|
|
||||||
|
|
||||||
public bool isLeaf;
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: d1647fc2736619c4fbf9804e952bf2c6
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e2a1bcfd751cc3849a426ce40c0cc77a
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e7a2f45922601af4b8c5ddf7a2690616
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 089a65b7b2de5d340be9185301f4742b
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: fac35f9984a9b074b96aef1277e7c9e2
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: fa918e3ca04b78e468ae9f5a1de3a753
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1ae9d7589452c7249b1f5273111af6fc
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8f11fb0ea5a15f347b7e8562f8b474f8
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5a6c324ec591f174cbc97744c8447ff6
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 6e4bed78da4a082428935e1820a5034f
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 7d5c9a011babea74aba9abf5a8f4bf56
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ef45d213589843a4ebe6d9b7a5b24247
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 175670fba1461ee44938eef5d12c329e
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 42349d897410ba04dbc6958029fe7b7c
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 7b3fe5d7e8d8b8d46b1961db5f53753e
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ea3639083c9301544b84c17809fce603
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 24eca8dc2fe8df84f9a0ea6d286044fb
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1041a0f4b4eaa5445800c894655b3715
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 796fdb117d06e9e4e8a438c432ee5660
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: dc87e2182d5939948940c02f64b9e182
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 071fbdd5892194649b9b696fd0aa1731
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 554f22e23c8a40a4883d0d0e06e9c23c
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 9e1a86580b159024db259379c26bf6e7
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user