diff --git a/.github/workflows/create-unitypackage.yml b/.github/workflows/create-unitypackage.yml index cfc0fd55f..65f062d51 100644 --- a/.github/workflows/create-unitypackage.yml +++ b/.github/workflows/create-unitypackage.yml @@ -14,23 +14,16 @@ defaults: shell: bash jobs: - checkout: + create-unitypackage: runs-on: [self-hosted, Windows, X64, Unity] - timeout-minutes: 10 + timeout-minutes: 60 steps: - id: checkout uses: actions/checkout@v4 with: submodules: recursive lfs: true - - detect-unity-version: - needs: checkout - runs-on: [self-hosted, Windows, X64, Unity] - timeout-minutes: 10 - outputs: - unity-editor-executable: ${{ steps.detect-unity-version.outputs.unity-editor-executable }} - steps: + - name: Detect Unity Version id: detect-unity-version run: | @@ -58,18 +51,13 @@ jobs: echo "${UNITY_EDITOR_EXECUTABLE} is installed." echo "unity-editor-executable=${UNITY_EDITOR_EXECUTABLE}" >> "${GITHUB_OUTPUT}" - run-edit-mode-tests: - needs: detect-unity-version - runs-on: [self-hosted, Windows, X64, Unity] - timeout-minutes: 10 - steps: - name: Run EditMode Tests id: run-edit-mode-tests run: | echo "Run EditMode Tests..." # RunEditModeTests の実行の結果、終了コードが 0 でない場合でもテストの結果を表示したいので set +e して一時的に回避する set +e - "${{ needs.detect-unity-version.outputs.unity-editor-executable }}" \ + "${{ steps.detect-unity-version.outputs.unity-editor-executable }}" \ -batchmode \ -silent-crashes \ -projectPath "${{ env.UNITY_PROJECT_PATH }}" \ @@ -91,7 +79,7 @@ jobs: echo "Test failed." exit 1 fi - + - name: Upload test results if: ${{ always() }} uses: actions/upload-artifact@v4 @@ -99,15 +87,10 @@ jobs: name: run-edit-mode-tests.xml path: ${{ env.UNITY_PROJECT_PATH }}/run-edit-mode-tests.xml - create-unitypackage: - needs: [detect-unity-version, run-edit-mode-tests] - runs-on: [self-hosted, Windows, X64, Unity] - timeout-minutes: 20 - steps: - name: Create UnityPackage id: create-unitypackage run: | - "${{ needs.detect-unity-version.outputs.unity-editor-executable }}" \ + "${{ steps.detect-unity-version.outputs.unity-editor-executable }}" \ -batchmode \ -silent-crashes \ -projectPath "${{ env.UNITY_PROJECT_PATH }}" \ diff --git a/Assets/UniGLTF/Editor/GltfImportMenu.cs b/Assets/UniGLTF/Editor/GltfImportMenu.cs index 913dd69dc..cbc19bdfc 100644 --- a/Assets/UniGLTF/Editor/GltfImportMenu.cs +++ b/Assets/UniGLTF/Editor/GltfImportMenu.cs @@ -6,18 +6,9 @@ namespace UniGLTF { public static class GltfImportMenu { - public const string MENU_NAME = "Import glTF... (*.gltf|*.glb|*.zip)"; public static void ImportGltfFileToGameObject() { - var path = EditorUtility.OpenFilePanel(MENU_NAME + ": open glb", "", -#if UNITY_EDITOR_OSX - // https://github.com/vrm-c/UniVRM/issues/1837 - "glb" -#else - "gltf,glb,zip" -#endif -); - if (string.IsNullOrEmpty(path)) + if(!UniGltfEditorDialog.TryOpenFilePanel("", out var path)) { return; } diff --git a/Assets/UniGLTF/Editor/TopMenu.cs b/Assets/UniGLTF/Editor/TopMenu.cs index f5e4e9cdf..0d6e4f678 100644 --- a/Assets/UniGLTF/Editor/TopMenu.cs +++ b/Assets/UniGLTF/Editor/TopMenu.cs @@ -23,7 +23,7 @@ namespace UniGLTF private static void ExportGameObjectToGltf() => GltfExportWindow.ExportGameObjectToGltfFile(); - [MenuItem(UserGltfMenuPrefix + "/" + GltfImportMenu.MENU_NAME, priority = 2)] + [MenuItem(UserGltfMenuPrefix + "/" + UniGltfEditorDialog.IMPORT_MENU_NAME, priority = 2)] private static void ImportGltfFile() => GltfImportMenu.ImportGltfFileToGameObject(); diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs index eb67943ea..41631f61a 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExportDialogBase.cs @@ -156,8 +156,7 @@ namespace UniGLTF if (GUILayout.Button("Export", GUILayout.MinWidth(100))) { - var path = SaveFileDialog.GetPath(SaveTitle, SaveName, SaveExtensions); - if (!string.IsNullOrEmpty(path)) + if (UniGltfEditorDialog.TrySaveFilePanel(SaveTitle, SaveName, SaveExtensions, out var path)) { ExportPath(path); // close diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/SaveFileDialog.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/SaveFileDialog.cs deleted file mode 100644 index 9ac7cea24..000000000 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/SaveFileDialog.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.IO; -using UnityEditor; -using UnityEngine; - -namespace UniGLTF -{ - public static class SaveFileDialog - { - static string m_lastExportDir; - - static string extensionString(string[] extensions) - { -#if UNITY_EDITOR_OSX - // in OSX multi extension cause exception. - // https://github.com/vrm-c/UniVRM/issues/1837 - return extensions.Length > 0 ? extensions[0] : ""; -#else - return string.Join(",", extensions); -#endif - } - - public static string GetPath(string title, string name, params string[] extensions) - { - string directory = m_lastExportDir; - if (string.IsNullOrEmpty(directory)) - { - directory = Directory.GetParent(Application.dataPath).ToString(); - } - - var path = EditorUtility.SaveFilePanel(title, directory, name, extensionString(extensions)); - if (!string.IsNullOrEmpty(path)) - { - m_lastExportDir = Path.GetDirectoryName(path).Replace("\\", "/"); - } - return path; - } - - public static string GetDir(string title, string dir = null) - { - string directory = string.IsNullOrEmpty(dir) ? m_lastExportDir : dir; - if (string.IsNullOrEmpty(directory)) - { - directory = Directory.GetParent(Application.dataPath).ToString(); - } - - var path = EditorUtility.SaveFolderPanel(title, directory, null); - if (!string.IsNullOrEmpty(path)) - { - m_lastExportDir = Path.GetDirectoryName(path).Replace("\\", "/"); - } - - return path; - } - } -} diff --git a/Assets/UniGLTF/Editor/UniGltfEditorDialog.cs b/Assets/UniGLTF/Editor/UniGltfEditorDialog.cs new file mode 100644 index 000000000..d11f08d4e --- /dev/null +++ b/Assets/UniGLTF/Editor/UniGltfEditorDialog.cs @@ -0,0 +1,78 @@ +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace UniGLTF +{ + public static class UniGltfEditorDialog + { + public const string IMPORT_MENU_NAME = "Import glTF... (*.gltf|*.glb|*.zip)"; + + static string extensionString(string[] extensions) + { + if (Application.platform == RuntimePlatform.WindowsEditor) + { + return string.Join(",", extensions); + } + else + { + // in OSX multi extension cause exception. + // https://github.com/vrm-c/UniVRM/issues/1837 + // in Linux + // https://github.com/vrm-c/UniVRM/issues/2515 + return extensions.Length > 0 ? extensions[0] : ""; + } + } + + public static bool TryOpenFilePanel(string directory, out string path) + { + path = EditorUtility.OpenFilePanel(IMPORT_MENU_NAME, directory, + // https://github.com/vrm-c/UniVRM/issues/1837 + Application.platform == RuntimePlatform.WindowsEditor ? "gltf,glb,zip" : "glb" + ); + if (string.IsNullOrEmpty(path)) + { + return false; + } + + return true; + } + + static string s_lastExportDir; + public static bool TrySaveFilePanel(string title, string name, string[] extensions, out string path) + { + string directory = s_lastExportDir; + if (string.IsNullOrEmpty(directory)) + { + directory = Directory.GetParent(Application.dataPath).ToString(); + } + + path = EditorUtility.SaveFilePanel(title, directory, name, extensionString(extensions)); + if (string.IsNullOrEmpty(path)) + { + return false; + } + + s_lastExportDir = Path.GetDirectoryName(path).Replace("\\", "/"); + return true; + } + + public static bool TryGetDir(string title, string dir, out string path) + { + string directory = string.IsNullOrEmpty(dir) ? s_lastExportDir : dir; + if (string.IsNullOrEmpty(directory)) + { + directory = Directory.GetParent(Application.dataPath).ToString(); + } + + path = EditorUtility.SaveFolderPanel(title, directory, null); + if (string.IsNullOrEmpty(path)) + { + return false; + } + + s_lastExportDir = Path.GetDirectoryName(path).Replace("\\", "/"); + return true; + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/SaveFileDialog.cs.meta b/Assets/UniGLTF/Editor/UniGltfEditorDialog.cs.meta similarity index 83% rename from Assets/UniGLTF/Editor/UniGLTF/ExportDialog/SaveFileDialog.cs.meta rename to Assets/UniGLTF/Editor/UniGltfEditorDialog.cs.meta index 1135ac002..e8b6cdfeb 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/SaveFileDialog.cs.meta +++ b/Assets/UniGLTF/Editor/UniGltfEditorDialog.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 35dc28badc82c5e4a8aa813ddd3369fe +guid: 20581dc53a52e174cbaec605148d3e78 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs index 455e17dd6..f420ed10e 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/InputPorts/FastSpringBoneBuffer.cs @@ -172,7 +172,14 @@ namespace UniGLTF.SpringBoneJobs.InputPorts for (int i = offset; i < end; ++i) { // mark velocity zero +#if UNITY_2022_2_OR_NEWER currentTails.GetSubArray(offset, Logics.Length).AsSpan().Fill(new Vector3(float.NaN, float.NaN, float.NaN)); +#else + var subArray = currentTails.GetSubArray(offset, Logics.Length); + var value = new Vector3(float.NaN, float.NaN, float.NaN); + for (int a = 0; a < subArray.Length; ++a) + subArray[a] = value; +#endif } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMesh.cs b/Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMesh.cs index bc65a325c..9ed27634b 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMesh.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/Format/glTFMesh.cs @@ -75,6 +75,17 @@ namespace UniGLTF [Serializable] public class glTFPrimitives { + public enum Mode + { + POINTS = 0, + LINES = 1, + LINE_LOOP = 2, + LINE_STRIP = 3, + TRIANGLES = 4, + TRIANGLE_STRIP = 5, + TRIANGLE_FAN = 6, + } + [JsonSchema(EnumValues = new object[] { 0, 1, 2, 3, 4, 5, 6 })] public int mode; diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ArrayByteBuffer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ArrayByteBuffer.cs index 722c1f8c2..11d1e8216 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ArrayByteBuffer.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ArrayByteBuffer.cs @@ -43,22 +43,18 @@ namespace UniGLTF public glTFBufferView Extend(IntPtr p, int bytesLength, int stride, glBufferTarget target) { - var tmp = m_bytes; // alignment var padding = m_used % stride == 0 ? 0 : stride - m_used % stride; + var requiredLength = m_used + padding + bytesLength; - if (m_bytes == null || m_used + padding + bytesLength > m_bytes.Length) + if (m_bytes == null || requiredLength > m_bytes.Length) { // recreate buffer - m_bytes = new Byte[m_used + padding + bytesLength]; + var newLength = Math.Max(requiredLength, m_bytes?.Length * 2 ?? 256); + var newBuffer = new Byte[newLength]; if (m_used > 0) - { - Buffer.BlockCopy(tmp, 0, m_bytes, 0, m_used); - } - } - if (m_used + padding + bytesLength > m_bytes.Length) - { - throw new ArgumentOutOfRangeException(); + Buffer.BlockCopy(m_bytes, 0, newBuffer, 0, m_used); + m_bytes = newBuffer; } Marshal.Copy(p, m_bytes, m_used + padding, bytesLength); @@ -70,7 +66,7 @@ namespace UniGLTF byteStride = stride, target = target, }; - m_used = m_used + padding + bytesLength; + m_used = requiredLength; return result; } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/Import/MaterialFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/Import/MaterialFactory.cs index ab4d0955b..518280865 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/Import/MaterialFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/Import/MaterialFactory.cs @@ -14,20 +14,22 @@ namespace UniGLTF private readonly MaterialDescriptor m_defaultMaterialParams; private readonly List m_materials = new List(); - /// - /// gltfPritmitive.material が無い場合のデフォルトマテリアル - /// https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#default-material - /// - /// - private Material m_defaultMaterial; - public IReadOnlyList Materials => m_materials; - public MaterialFactory(IReadOnlyDictionary externalMaterialMap, MaterialDescriptor defaultMaterialParams) { m_externalMap = externalMaterialMap; - m_defaultMaterialParams = defaultMaterialParams; + m_defaultMaterialParams = new MaterialDescriptor( + m_defaultMaterialKey.Name, + defaultMaterialParams.Shader, + defaultMaterialParams.RenderQueue, + defaultMaterialParams.TextureSlots, + defaultMaterialParams.FloatValues, + defaultMaterialParams.Colors, + defaultMaterialParams.Vectors, + defaultMaterialParams.Actions, + defaultMaterialParams.AsyncActions + ); } public struct MaterialLoadInfo @@ -56,11 +58,6 @@ namespace UniGLTF UnityObjectDestroyer.DestroyRuntimeOrEditor(x.Asset); } } - - if (m_defaultMaterial != null) - { - UnityObjectDestroyer.DestroyRuntimeOrEditor(m_defaultMaterial); - } } /// @@ -84,12 +81,6 @@ namespace UniGLTF m_materials.Remove(x); } } - - if (m_defaultMaterial != null) - { - take(m_defaultMaterialKey, m_defaultMaterial); - m_defaultMaterial = null; - } } public Material GetMaterial(int index) @@ -99,22 +90,16 @@ namespace UniGLTF return m_materials[index].Asset; } - public async Task GetDefaultMaterialAsync(IAwaitCaller awaitCaller) + /// + /// gltfPritmitive.material が無い場合のデフォルトマテリアル + /// https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#default-material + /// + /// + public Task GetDefaultMaterialAsync(IAwaitCaller awaitCaller) { - if (m_externalMap.ContainsKey(m_defaultMaterialKey)) - { - m_defaultMaterial = m_externalMap[m_defaultMaterialKey]; - return m_externalMap[m_defaultMaterialKey]; - } - - if (m_defaultMaterial == null) - { - m_defaultMaterial = await LoadAsync(m_defaultMaterialParams, (_, _) => null, awaitCaller); - } - return m_defaultMaterial; + return LoadAsync(m_defaultMaterialParams, (_, _) => null, awaitCaller); } - public async Task LoadAsync(MaterialDescriptor matDesc, GetTextureAsyncFunc getTexture, IAwaitCaller awaitCaller) { if (m_externalMap.TryGetValue(matDesc.SubAssetKey, out Material material)) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs index 17d798e43..95bcd7cc8 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs @@ -114,52 +114,7 @@ namespace UniGLTF attributes.JOINTS_0 = jointsAccessorIndex; } - var gltfMesh = new glTFMesh(mesh.name); - var indices = new List(); - for (int j = 0; j < mesh.subMeshCount; ++j) - { - indices.Clear(); - - var triangles = mesh.GetIndices(j); - if (triangles.Length == 0) - { - // https://github.com/vrm-c/UniVRM/issues/664 - continue; - } - - for (int i = 0; i < triangles.Length; i += 3) - { - var i0 = triangles[i]; - var i1 = triangles[i + 1]; - var i2 = triangles[i + 2]; - - // flip triangle - indices.Add((uint)i2); - indices.Add((uint)i1); - indices.Add((uint)i0); - } - - var indicesAccessorIndex = data.ExtendBufferAndGetAccessorIndex(indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER); - if (indicesAccessorIndex < 0) - { - // https://github.com/vrm-c/UniVRM/issues/664 - throw new Exception(); - } - - if (j >= materials.Length) - { - Debug.LogWarningFormat("{0}.materials is not enough", unityMesh.Mesh.name); - break; - } - - gltfMesh.primitives.Add(new glTFPrimitives - { - attributes = attributes, - indices = indicesAccessorIndex, - mode = 4, // triangles ? - material = unityMaterials.IndexOf(materials[j]) - }); - } + var gltfMesh = CreateGLTFMesh(attributes, data, unityMesh, unityMaterials); var blendShapeIndexMap = new Dictionary(); { @@ -201,6 +156,119 @@ namespace UniGLTF return (gltfMesh, blendShapeIndexMap); } + private static glTFMesh CreateGLTFMesh(glTFAttributes attributes, ExportingGltfData data, MeshExportInfo unityMesh, List unityMaterials) + { + var mesh = unityMesh.Mesh; + var materials = unityMesh.Materials; + var gltfMesh = new glTFMesh(mesh.name); + + var indices = new List(); + for (int j = 0; j < mesh.subMeshCount; ++j) + { + indices.Clear(); + if (j >= materials.Length) + { + Debug.LogWarningFormat("{0}.materials is not enough", mesh.name); + continue; + } + + var subMesh = mesh.GetSubMesh(j); + var topologyType = subMesh.topology; + var materialIndex = unityMaterials.IndexOf(materials[j]); + + var submeshIndices = mesh.GetIndices(j); + if (submeshIndices.Length == 0) + { + // https://github.com/vrm-c/UniVRM/issues/664 + break; + } + else if (submeshIndices.Length < 3) + { + Debug.LogWarningFormat("Invalid primitive of type {0} found", topologyType); + continue; + } + + // Add indices considering the topology type + switch (topologyType) + { + case MeshTopology.Triangles: + if (submeshIndices.Length % 3 != 0) + Debug.LogWarningFormat("triangle indices is not multiple of 3"); + GetTriangleIndices(indices, submeshIndices); + break; + case MeshTopology.Quads: + if (submeshIndices.Length % 4 != 0) + Debug.LogWarningFormat("quad indices is not multiple of 4"); + GetQuadIndices(indices, submeshIndices); + break; + default: + case MeshTopology.Lines: + case MeshTopology.LineStrip: + case MeshTopology.Points: + Debug.LogWarningFormat("Mesh {0} has unsupported topology type {1}.", mesh.name, topologyType); + continue; + } + + var primitive = CreatePrimitives(attributes, data, indices, materialIndex); + gltfMesh.primitives.Add(primitive); + } + + return gltfMesh; + } + + private static glTFPrimitives CreatePrimitives(glTFAttributes attributes, ExportingGltfData data, List indices, int materialIndex) + { + var indicesAccessorIndex = data.ExtendBufferAndGetAccessorIndex(indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER); + if (indicesAccessorIndex < 0) + { + // https://github.com/vrm-c/UniVRM/issues/664 + throw new Exception(); + } + var primitive = new glTFPrimitives + { + attributes = attributes, + indices = indicesAccessorIndex, + mode = (int)glTFPrimitives.Mode.TRIANGLES, // triangles ? + material = materialIndex + }; + return primitive; + } + + private static void GetQuadIndices(List indices, int[] quadIndices) + { + for (int i = 0; i < quadIndices.Length - 3; i += 4) + { + var i0 = quadIndices[i]; + var i1 = quadIndices[i + 1]; + var i2 = quadIndices[i + 2]; + var i3 = quadIndices[i + 3]; + + // flip triangles + indices.Add((uint)i2); + indices.Add((uint)i1); + indices.Add((uint)i0); + + indices.Add((uint)i3); + indices.Add((uint)i2); + indices.Add((uint)i0); + } + } + + private static void GetTriangleIndices(List indices, int[] triangleIndices) + { + for (int i = 0; i < triangleIndices.Length - 2; i += 3) + { + var i0 = triangleIndices[i]; + var i1 = triangleIndices[i + 1]; + var i2 = triangleIndices[i + 2]; + + // flip triangle + indices.Add((uint)i2); + indices.Add((uint)i1); + indices.Add((uint)i0); + } + } + static bool UseSparse( bool usePosition, Vector3 position, bool useNormal, Vector3 normal, diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/NativeArrayManager.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/NativeArrayManager.cs index fc8f4c05d..b02250bbb 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/NativeArrayManager.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/NativeArrayManager.cs @@ -69,8 +69,8 @@ namespace UniGLTF public NativeArray CreateNativeArray(ArraySegment data) where T : struct { var array = CreateNativeArray(data.Count); - // TODO: remove ToArray - array.CopyFrom(data.ToArray()); + for (int i = 0; i < data.Count; i++) + array[i] = data.Array[data.Offset + i]; return array; } diff --git a/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs.meta b/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs.meta index 3da5dea95..c44f5ef8c 100644 --- a/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs.meta +++ b/Assets/UniGLTF/Runtime/UniHumanoid/AvatarDescription.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 guid: 976e99d37c093ce4c9b249c81c2cbdd5 -timeCreated: 1520401720 -licenseType: Free MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Assets/VRM/Editor/Format/VRMExportOptions.cs b/Assets/VRM/Editor/Format/VRMExportOptions.cs index 1b23da7bc..dfe78e7ea 100644 --- a/Assets/VRM/Editor/Format/VRMExportOptions.cs +++ b/Assets/VRM/Editor/Format/VRMExportOptions.cs @@ -12,6 +12,10 @@ namespace VRM [LangMsg(Languages.en, "Model's normalization (bake to remove roation and scaling from the hierarchy)")] NORMALIZE, + [LangMsg(Languages.ja, "正規化するときににブレンドシェイプによる変形をベイク処理します。")] + [LangMsg(Languages.en, "Bake the blendshape deformations as the base model when normalizing.")] + FREEZE_BLENDSHAPE, + [LangMsg(Languages.ja, "エクスポート時に新しいJsonSerializerを使う")] [LangMsg(Languages.en, "The new version of JsonSerializer for model export")] USE_GENERATED_SERIALIZER, diff --git a/Assets/VRM/Editor/Format/VRMExportSettings.cs b/Assets/VRM/Editor/Format/VRMExportSettings.cs index cc634263a..29b93d57e 100644 --- a/Assets/VRM/Editor/Format/VRMExportSettings.cs +++ b/Assets/VRM/Editor/Format/VRMExportSettings.cs @@ -23,7 +23,7 @@ namespace VRM /// FreezeBlendShape /// [Tooltip("when freeze mesh, blendShpae base use current weight")] - public bool FreezeMeshUseCurrentBlendShapeWeight = false; + public bool FreezeMeshUseCurrentBlendShapeWeight = true; /// /// BlendShapeのシリアライズにSparseAccessorを使う diff --git a/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs b/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs index 9c8901ab3..3df60f240 100644 --- a/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs +++ b/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs @@ -48,6 +48,7 @@ namespace VRM private void OnEnable() { m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.PoseFreeze)), VRMExportOptions.NORMALIZE)); + m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.FreezeMeshUseCurrentBlendShapeWeight)), VRMExportOptions.FREEZE_BLENDSHAPE)); m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.UseSparseAccessor)), VRMExportOptions.BLENDSHAPE_USE_SPARSE)); m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.OnlyBlendshapePosition)), VRMExportOptions.BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT)); m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshape)), VRMExportOptions.BLENDSHAPE_ONLY_CLIP_USE)); diff --git a/Assets/VRM/Icons.meta b/Assets/VRM/Icons.meta new file mode 100644 index 000000000..17495c3e7 --- /dev/null +++ b/Assets/VRM/Icons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e811516644fdd954f866e2f48a257a16 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM/Icons/vrm0x-48x48.png b/Assets/VRM/Icons/vrm0x-48x48.png new file mode 100644 index 000000000..fb2624f78 Binary files /dev/null and b/Assets/VRM/Icons/vrm0x-48x48.png differ diff --git a/Assets/VRM/Icons/vrm0x-48x48.png.meta b/Assets/VRM/Icons/vrm0x-48x48.png.meta new file mode 100644 index 000000000..4118fd6f4 --- /dev/null +++ b/Assets/VRM/Icons/vrm0x-48x48.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 7656e3d0da852c54e979d2887196ef75 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM/Runtime/BlendShape/BlendShapeAvatar.cs.meta b/Assets/VRM/Runtime/BlendShape/BlendShapeAvatar.cs.meta index e67352a91..7a703ad97 100644 --- a/Assets/VRM/Runtime/BlendShape/BlendShapeAvatar.cs.meta +++ b/Assets/VRM/Runtime/BlendShape/BlendShapeAvatar.cs.meta @@ -1,13 +1,11 @@ fileFormatVersion: 2 guid: 329dca3bf78fcdd42b2df941673db76f -timeCreated: 1519195979 -licenseType: Free MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: 7656e3d0da852c54e979d2887196ef75, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM/Runtime/BlendShape/BlendShapeClip.cs.meta b/Assets/VRM/Runtime/BlendShape/BlendShapeClip.cs.meta index cddffb589..ac067239b 100644 --- a/Assets/VRM/Runtime/BlendShape/BlendShapeClip.cs.meta +++ b/Assets/VRM/Runtime/BlendShape/BlendShapeClip.cs.meta @@ -1,13 +1,11 @@ fileFormatVersion: 2 guid: 37562b39ff933b245ac2f35d87edbcd6 -timeCreated: 1517402750 -licenseType: Free MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: 7656e3d0da852c54e979d2887196ef75, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM/Runtime/BlendShape/VRMBlendShapeProxy.cs.meta b/Assets/VRM/Runtime/BlendShape/VRMBlendShapeProxy.cs.meta index 9eaaa544e..54218fa83 100644 --- a/Assets/VRM/Runtime/BlendShape/VRMBlendShapeProxy.cs.meta +++ b/Assets/VRM/Runtime/BlendShape/VRMBlendShapeProxy.cs.meta @@ -1,13 +1,11 @@ fileFormatVersion: 2 guid: 5b678c1df50cfb547990db24a32856da -timeCreated: 1517467747 -licenseType: Free MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: 7656e3d0da852c54e979d2887196ef75, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM/Runtime/FirstPerson/VRMFirstPerson.cs.meta b/Assets/VRM/Runtime/FirstPerson/VRMFirstPerson.cs.meta index 0711249b2..0151662d6 100644 --- a/Assets/VRM/Runtime/FirstPerson/VRMFirstPerson.cs.meta +++ b/Assets/VRM/Runtime/FirstPerson/VRMFirstPerson.cs.meta @@ -1,13 +1,11 @@ fileFormatVersion: 2 guid: dedba1309bdf12b42af2362f52eea134 -timeCreated: 1519218333 -licenseType: Free MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: 7656e3d0da852c54e979d2887196ef75, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM/Runtime/Meta/VRMMeta.cs.meta b/Assets/VRM/Runtime/Meta/VRMMeta.cs.meta index 0b7d246ea..94335389a 100644 --- a/Assets/VRM/Runtime/Meta/VRMMeta.cs.meta +++ b/Assets/VRM/Runtime/Meta/VRMMeta.cs.meta @@ -1,12 +1,11 @@ fileFormatVersion: 2 guid: 690ea0146224b8b4694a1925dddeb352 -timeCreated: 1522391118 -licenseType: Free MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: 7656e3d0da852c54e979d2887196ef75, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM/Runtime/Meta/VRMMetaObject.cs.meta b/Assets/VRM/Runtime/Meta/VRMMetaObject.cs.meta index 7ed6699a0..b0262cd32 100644 --- a/Assets/VRM/Runtime/Meta/VRMMetaObject.cs.meta +++ b/Assets/VRM/Runtime/Meta/VRMMetaObject.cs.meta @@ -1,12 +1,11 @@ fileFormatVersion: 2 guid: 63b589176a34b344b9ccbee2b7e7114a -timeCreated: 1522391129 -licenseType: Free MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: 7656e3d0da852c54e979d2887196ef75, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM/Runtime/SpringBone/VRMSpringBone.cs.meta b/Assets/VRM/Runtime/SpringBone/VRMSpringBone.cs.meta index 0efb4cccd..a811724a1 100644 --- a/Assets/VRM/Runtime/SpringBone/VRMSpringBone.cs.meta +++ b/Assets/VRM/Runtime/SpringBone/VRMSpringBone.cs.meta @@ -1,13 +1,11 @@ fileFormatVersion: 2 guid: 00ea06e1753e16f4ca870c39c067c86b -timeCreated: 1517224588 -licenseType: Free MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: 7656e3d0da852c54e979d2887196ef75, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs index 2ad132ac9..73da1d312 100644 --- a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderEditor.cs @@ -1,6 +1,7 @@ using UnityEditor; using UnityEngine; + namespace UniVRM10 { [CustomEditor(typeof(VRM10SpringBoneCollider))] @@ -9,32 +10,41 @@ namespace UniVRM10 VRM10SpringBoneCollider _target; Vrm10Instance _vrm; + SerializedProperty _script; + SerializedProperty _colliderType; + SerializedProperty _offset; + SerializedProperty _tail; + + static VRM10SpringBoneCollider s_selected; + private void OnEnable() { _target = (VRM10SpringBoneCollider)target; - if(_target!=null) + if (_target != null) { _vrm = _target.GetComponentInParent(); } + + _script = serializedObject.FindProperty("m_Script"); + _colliderType = serializedObject.FindProperty(nameof(_target.ColliderType)); + _offset = serializedObject.FindProperty(nameof(_target.Offset)); + _tail = serializedObject.FindProperty(nameof(_target.Tail)); } public override void OnInspectorGUI() { - // if (VRM10Window.Active == target) - // { - // GUI.backgroundColor = Color.cyan; - // Repaint(); - // } - var property = serializedObject.FindProperty("m_Script"); - var component = (VRM10SpringBoneCollider)target; - EditorGUILayout.PropertyField(property, new GUIContent("Script (" + component.GetIdentificationName() + ")")); - switch (component.ColliderType) + using (new EditorGUI.DisabledScope(true)) + { + EditorGUILayout.PropertyField(_script); + } + + switch (_target.ColliderType) { case VRM10SpringBoneColliderTypes.Plane: // radius: x // tail: x // normal: o - DrawPropertiesExcluding(serializedObject, "m_Script", nameof(component.Tail), nameof(component.Radius)); + DrawPropertiesExcluding(serializedObject, "m_Script", nameof(_target.Tail), nameof(_target.Radius)); break; case VRM10SpringBoneColliderTypes.Sphere: @@ -42,7 +52,7 @@ namespace UniVRM10 // radius: o // tail: x // normal: x - DrawPropertiesExcluding(serializedObject, nameof(component.Tail), nameof(component.Normal), "m_Script"); + DrawPropertiesExcluding(serializedObject, nameof(_target.Tail), nameof(_target.Normal), "m_Script"); break; case VRM10SpringBoneColliderTypes.Capsule: @@ -50,21 +60,74 @@ namespace UniVRM10 // radius: o // tail: o // normal: x - DrawPropertiesExcluding(serializedObject, nameof(component.Normal), "m_Script"); + DrawPropertiesExcluding(serializedObject, nameof(_target.Normal), "m_Script"); break; } + EditorGUILayout.BeginHorizontal(); + { + if (GUILayout.Button("Drag handle")) + { + s_selected = _target; + } + + if (_target.transform.childCount > 0) + { + if (GUILayout.Button("Fit head-tail capsule")) + { + _colliderType.enumValueFlag = (int)VRM10SpringBoneColliderTypes.Capsule; + _offset.vector3Value = Vector3.zero; + var tail = _target.transform.GetChild(0); + _tail.vector3Value = _target.transform.worldToLocalMatrix.MultiplyPoint( + tail.position); + } + } + } + EditorGUILayout.EndHorizontal(); + if (serializedObject.ApplyModifiedProperties()) { if (Application.isPlaying) { // UniGLTF.UniGLTFLogger.Log("invaliate"); - if(_vrm!=null) + if (_vrm != null) { _vrm.Runtime.SpringBone.ReconstructSpringBone(); } } } } + + public void OnSceneGUI() + { + HandleUtility.Repaint(); + + if (s_selected == _target) + { + var c = _target; + Handles.matrix = c.transform.localToWorldMatrix; + if (_target.ColliderType == VRM10SpringBoneColliderTypes.Capsule + || _target.ColliderType == VRM10SpringBoneColliderTypes.CapsuleInside) + { + EditorGUI.BeginChangeCheck(); + var newTargetPosition = Handles.PositionHandle(c.Tail, Quaternion.identity); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(c, "collider"); + c.Tail = newTargetPosition; + } + } + else + { + EditorGUI.BeginChangeCheck(); + var newTargetPosition = Handles.PositionHandle(c.Offset, Quaternion.identity); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(c, "collider"); + c.Offset = newTargetPosition; + } + } + } + } } } \ No newline at end of file diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs new file mode 100644 index 000000000..d5e0ff876 --- /dev/null +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs @@ -0,0 +1,82 @@ +using System; +using System.Linq; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + + +namespace UniVRM10 +{ + [CustomEditor(typeof(VRM10SpringBoneColliderGroup))] + class VRM10SpringBoneColliderGroupEditor : Editor + { + ListView m_colliders; + + static VRM10SpringBoneCollider s_collider; + + public override VisualElement CreateInspectorGUI() + { + var root = new VisualElement(); + + // root.TrackSerializedObjectValue(serializedObject, OnValueChanged); + + root.Bind(serializedObject); + + { + var s = new PropertyField { bindingPath = "m_Script" }; + s.SetEnabled(false); + root.Add(s); + } + + + root.Add(new PropertyField { bindingPath = nameof(VRM10SpringBoneColliderGroup.Name) }); + + { + m_colliders = new ListView + { + bindingPath = nameof(VRM10SpringBoneColliderGroup.Colliders) + }; + m_colliders.selectionChanged += (e) => + { + var item = (SerializedProperty)e.FirstOrDefault(); + if (item == null) + { + s_collider = null; + } + else + { + s_collider = (VRM10SpringBoneCollider)item.objectReferenceValue; + } + }; + m_colliders.showAddRemoveFooter = true; + m_colliders.showFoldoutHeader = true; + m_colliders.headerTitle = "Colliders"; + root.Add(m_colliders); + } + + return root; + } + + public void OnSceneGUI() + { + HandleUtility.Repaint(); + if (m_colliders == null) + { + return; + } + + if (s_collider is VRM10SpringBoneCollider c) + { + EditorGUI.BeginChangeCheck(); + Handles.matrix = c.transform.localToWorldMatrix; + var newTargetPosition = Handles.PositionHandle(c.Offset, Quaternion.identity); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(c, "collider"); + c.Offset = newTargetPosition; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs.meta b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs.meta new file mode 100644 index 000000000..5e1e59629 --- /dev/null +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneColliderGroupEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ccae4c83e5d3a6438402cdd307f4ad2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs new file mode 100644 index 000000000..da1791206 --- /dev/null +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs @@ -0,0 +1,63 @@ +using UniGLTF; +using UnityEngine; +using System.Linq; +using UnityEditor.AssetImporters; + + +namespace UniVRM10 +{ + [ScriptedImporter(1, "vrma")] + public class VrmaScriptedImporter : ScriptedImporter + { + /// + /// Vrm-1.0 の Asset にアイコンを付与する + /// + static Texture2D _AssetIcon = null; + static Texture2D AssetIcon + { + get + { + if (_AssetIcon == null) + { + // try package + _AssetIcon = UnityEditor.AssetDatabase.LoadAssetAtPath("Packages/com.vrmc.vrm/Icons/vrm-48x48.png"); + } + if (_AssetIcon == null) + { + // try assets + _AssetIcon = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/VRM10/Icons/vrm-48x48.png"); + } + return _AssetIcon; + } + } + + public override void OnImportAsset(AssetImportContext context) + { + // 2 回目以降の Asset Import において、 Importer の設定で Extract した UnityEngine.Object が入る + var extractedObjects = GetExternalObjectMap() + .Where(x => x.Value != null) + .ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value); + + using (var data = new AutoGltfFileParser(assetPath).Parse()) + using (var loader = new VrmAnimationImporter(data, extractedObjects)) + { + var loaded = loader.Load(); + + loaded.TransferOwnership((k, o) => + { + context.AddObjectToAsset(k.Name, o); + }); + + var root = loaded.Root; + GameObject.DestroyImmediate(loaded); + + // var vrma = root.GetComponent(); + // context.AddObjectToAsset("__boxman_mesh__", vrma.BoxMan.sharedMesh); + // context.AddObjectToAsset("__boxman_mesh__material__", vrma.BoxMan.sharedMaterial); + + context.AddObjectToAsset(root.name, root, AssetIcon); + context.SetMainObject(root); + } + } + } +} \ No newline at end of file diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs.meta b/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs.meta new file mode 100644 index 000000000..045128bee --- /dev/null +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmaScriptedImporter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19427481f19aca9429da3548d28da6f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Editor/Vrm10InstanceEditor.cs b/Assets/VRM10/Editor/Vrm10InstanceEditor.cs index 2b1125235..4c6cc7c28 100644 --- a/Assets/VRM10/Editor/Vrm10InstanceEditor.cs +++ b/Assets/VRM10/Editor/Vrm10InstanceEditor.cs @@ -190,8 +190,7 @@ namespace UniVRM10 if (GUILayout.Button("Create new VRM10Object and default Expressions. select target folder")) { var saveName = GetSaveName(instance); - var dir = SaveFileDialog.GetDir(SaveTitle, System.IO.Path.GetDirectoryName(saveName)); - if (!string.IsNullOrEmpty(dir)) + if (UniGltfEditorDialog.TryGetDir(SaveTitle, System.IO.Path.GetDirectoryName(saveName), out var dir)) { var expressions = new Dictionary(); foreach (ExpressionPreset expression in CachedEnum.GetValues()) diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs.meta index 205e03dc4..43c836095 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs.meta +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10AimConstraint.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs.meta index 4c6dc5979..46236ae1e 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs.meta +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RollConstraint.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RotationConstraint.cs.meta b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RotationConstraint.cs.meta index 4eaea4e14..82c8c0e65 100644 --- a/Assets/VRM10/Runtime/Components/Constraint/Vrm10RotationConstraint.cs.meta +++ b/Assets/VRM10/Runtime/Components/Constraint/Vrm10RotationConstraint.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs b/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs index 97cb99ff9..30983ea60 100644 --- a/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs +++ b/Assets/VRM10/Runtime/Components/Expression/MaterialValueBindingMerger.cs @@ -231,29 +231,6 @@ namespace UniVRM10 } } - // UVアクセスするテクスチャーのScaleOffsetプロパティの一覧 - static Dictionary UVPropMap = new Dictionary - { - {"Standard", new string[]{ - "_MainTex_ST", - }}, - {"VRM10/MToon10", new string[]{ - "_MainTex_ST", - }}, - }; - static string[] DefaultProps = { "_MainTex_ST" }; - public static String[] GetUVProps(string shaderName) - { - if (UVPropMap.TryGetValue(shaderName, out string[] props)) - { - return props; - } - else - { - return DefaultProps; - } - } - HashSet m_used = new HashSet(); public void Apply() { @@ -302,10 +279,8 @@ namespace UniVRM10 // // Standard and MToon use _MainTex_ST as uv0 scale/offset // - foreach (var prop in GetUVProps(item.Material.shader.name)) - { - item.Material.SetVector(prop, kv.Value); - } + item.Material.mainTextureScale = new Vector2(kv.Value.x, kv.Value.y); + item.Material.mainTextureOffset = new Vector2(kv.Value.z, kv.Value.w); } } m_materialUVMap.Clear(); diff --git a/Assets/VRM10/Runtime/Components/Expression/VRM10Expression.cs.meta b/Assets/VRM10/Runtime/Components/Expression/VRM10Expression.cs.meta index 4c6762ab3..7b4eb414a 100644 --- a/Assets/VRM10/Runtime/Components/Expression/VRM10Expression.cs.meta +++ b/Assets/VRM10/Runtime/Components/Expression/VRM10Expression.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs.meta b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs.meta index dd1463115..f1eadb27a 100644 --- a/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs.meta +++ b/Assets/VRM10/Runtime/Components/SpringBone/VRM10SpringBoneColliderGroup.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10Object.cs.meta b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10Object.cs.meta index 135924fd1..6eccf730f 100644 --- a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10Object.cs.meta +++ b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10Object.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs.meta index 7e61c997e..2d7531c54 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs.meta +++ b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10Instance.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10InstanceSpringBone.cs b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10InstanceSpringBone.cs index c1d2c7c7a..edc9b5397 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10InstanceSpringBone.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Instance/Vrm10InstanceSpringBone.cs @@ -54,21 +54,23 @@ namespace UniVRM10 public void DrawGizmos() { - var backup = Gizmos.matrix; - Gizmos.matrix = Matrix4x4.identity; - VRM10SpringBoneJoint lastJoint = Joints[0]; - for (int i = 1; i < Joints.Count; ++i) + if (Joints.Count > 0) { - var joint = Joints[i]; - Gizmos.color = JointColor(lastJoint); - if (joint != null && lastJoint != null) + var backup = Gizmos.matrix; + Gizmos.matrix = Matrix4x4.identity; + VRM10SpringBoneJoint lastJoint = Joints[0]; + for (int i = 1; i < Joints.Count; ++i) { - Gizmos.DrawLine(lastJoint.transform.position, joint.transform.position); + var joint = Joints[i]; + Gizmos.color = JointColor(lastJoint); + if (joint != null && lastJoint != null) + { + Gizmos.DrawLine(lastJoint.transform.position, joint.transform.position); + } + lastJoint = joint; } - lastJoint = joint; + Gizmos.matrix = backup; } - - Gizmos.matrix = backup; } } diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs index 438f74963..4f26d93d1 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntime.cs @@ -93,7 +93,7 @@ namespace UniVRM10 m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer); } - m_fastSpringBoneBuffer = await FastSpringBoneBufferFactory.ConstructSpringBoneAsync(new ImmediateCaller(), m_instance, m_fastSpringBoneBuffer); + m_fastSpringBoneBuffer = await FastSpringBoneBufferFactory.ConstructSpringBoneAsync(awaitCaller, m_instance, m_fastSpringBoneBuffer); // 登録 m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer); diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs index e45218ff5..31153063d 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10FastSpringboneRuntimeStandalone.cs @@ -94,7 +94,7 @@ namespace UniVRM10 m_bufferCombiner.Unregister(m_fastSpringBoneBuffer); } - m_fastSpringBoneBuffer = await FastSpringBoneBufferFactory.ConstructSpringBoneAsync(new ImmediateCaller(), m_instance, m_fastSpringBoneBuffer); + m_fastSpringBoneBuffer = await FastSpringBoneBufferFactory.ConstructSpringBoneAsync(awaitCaller, m_instance, m_fastSpringBoneBuffer); // 登録 m_bufferCombiner.Register(m_fastSpringBoneBuffer); diff --git a/Assets/VRM10/Runtime/Components/VrmAnimationInstance/Vrm10AnimationInstance.cs.meta b/Assets/VRM10/Runtime/Components/VrmAnimationInstance/Vrm10AnimationInstance.cs.meta index 81ed9bff9..62c6d9dfc 100644 --- a/Assets/VRM10/Runtime/Components/VrmAnimationInstance/Vrm10AnimationInstance.cs.meta +++ b/Assets/VRM10/Runtime/Components/VrmAnimationInstance/Vrm10AnimationInstance.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {instanceID: 0} + icon: {fileID: 2800000, guid: ad4861e134018c948ac79793d290f48b, type: 3} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs b/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs index 41674c19e..3c2d5f9b2 100644 --- a/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs +++ b/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs @@ -7,12 +7,15 @@ using UniGLTF.Extensions.VRMC_vrm_animation; using UniHumanoid; using UniJSON; using UnityEngine; +using VrmLib; namespace UniVRM10 { public class VrmAnimationImporter : UniGLTF.ImporterContext { VRMC_vrm_animation m_vrma; + ExpressionInfo[] m_expressions; + Material m_defaultMaterial; public VrmAnimationImporter(GltfData data, IReadOnlyDictionary externalObjectMap = null, @@ -230,8 +233,8 @@ namespace UniVRM10 { // Expression は AnimationClip を分ける。 // glTFData から関連 Animation を取り除いて、取っておく。 - var expressions = IterateExpressions().ToArray(); - foreach (var channelIndex in expressions.Select(x => x.ChannelIndex).OrderByDescending(x => x)) + m_expressions = IterateExpressions().ToArray(); + foreach (var channelIndex in m_expressions.Select(x => x.ChannelIndex).OrderByDescending(x => x)) { var nodeIndex = Data.GLTF.animations[0].channels[channelIndex].target.node; Data.GLTF.nodes.RemoveAt(nodeIndex); @@ -243,11 +246,16 @@ namespace UniVRM10 Data.GLTF.scenes[0].nodes = Data.GLTF.scenes[0].nodes.Take(1).ToArray(); // 可視化メッシュ用マテリアル。base.LoadAsync を呼ぶ前に生成する。 - var defaultMaterial = await MaterialFactory.GetDefaultMaterialAsync(awaitCaller); + m_defaultMaterial = await MaterialFactory.GetDefaultMaterialAsync(awaitCaller); // Humanoid Animation が Gltf アニメーションとしてロードされる var instance = await base.LoadAsync(awaitCaller, measureTime); + return instance; + } + + protected override Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func MeasureTime) + { // setup humanoid var humanMap = GetHumanMap(); if (humanMap.Count > 0) @@ -256,22 +264,23 @@ namespace UniVRM10 // // avatar // - var avatar = description.CreateAvatar(instance.Root.transform); + var avatar = description.CreateAvatar(Root.transform); avatar.name = "Avatar"; // AvatarDescription = description; - var animator = instance.gameObject.AddComponent(); + var animator = Root.AddComponent(); animator.avatar = avatar; } - if (expressions.Length > 0) + if (m_expressions.Length > 0) { - var animation = instance.GetComponentOrThrow(); + var animation = Root.GetComponentOrThrow(); var clip = animation.clip; + // m_expressionClip.name = "__expression__"; // Expression の float カーブを追加する // VrmAnimationInstance の "preset_xx" field に連動する var gltfAnimation = Data.GLTF.animations[0]; - foreach (var expression in expressions) + foreach (var expression in m_expressions) { var channel = expression.Channel; var sampler = gltfAnimation.samplers[channel.sampler]; @@ -284,11 +293,22 @@ namespace UniVRM10 } } - // VRMA-animation solver - var animationInstance = instance.gameObject.AddComponent(); - animationInstance.Initialize(expressions.Select(x => x.Key), defaultMaterial); + var animationInstance = Root.AddComponent(); - return instance; + animationInstance.Initialize(m_expressions.Select(x => x.Key), m_defaultMaterial); + + return Task.CompletedTask; + } + + public override void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take) + { + var animationInstance = Root.GetComponent(); + take(SubAssetKey.Create(animationInstance.BoxMan.sharedMesh), animationInstance.BoxMan.sharedMesh); + + var animator = Root.GetComponent(); + take(SubAssetKey.Create(animator.avatar), animator.avatar); + + base.TransferOwnership(take); } } -} +} \ No newline at end of file diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs index da73be448..13e0deab6 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothGuess.cs @@ -138,7 +138,7 @@ namespace UniVRM10.Cloth.Viewer var warp = childchild.gameObject.AddComponent(); // Name = name, // CollisionMask = mask, - warp.BaseSettings.radius = 0.02f; + warp.BaseSettings.Radius = 0.02f; // Connection = type transforms.Add(warp); break; @@ -179,7 +179,7 @@ namespace UniVRM10.Cloth.Viewer if (warp != null) { // CollisionMask = mask, - warp.BaseSettings.radius = 0.02f; + warp.BaseSettings.Radius = 0.02f; // Connection = type transforms.Add(warp); } diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewer.unity b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewer.unity index 75d5db057..d6abc2f6b 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewer.unity +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewer.unity @@ -402,7 +402,7 @@ MonoBehaviour: onValueChanged: m_PersistentCalls: m_Calls: [] - m_IsOn: 0 + m_IsOn: 1 --- !u!1 &153452228 GameObject: m_ObjectHideFlags: 0 @@ -686,6 +686,92 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 168425994} m_CullTransparentMesh: 0 +--- !u!1 &172483632 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 172483633} + - component: {fileID: 172483634} + m_Layer: 5 + m_Name: AddClothToHips + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &172483633 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 172483632} + 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: + - {fileID: 1472853923} + - {fileID: 1724807119} + m_Father: {fileID: 339774397} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 162, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &172483634 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 172483632} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1472853924} + toggleTransition: 1 + graphic: {fileID: 1236232219} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 --- !u!1 &175751362 GameObject: m_ObjectHideFlags: 0 @@ -1407,6 +1493,7 @@ RectTransform: - {fileID: 1767706907} - {fileID: 947409974} - {fileID: 135168672} + - {fileID: 172483633} - {fileID: 2144476967} - {fileID: 1194499280} - {fileID: 153452229} @@ -5027,6 +5114,81 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1215781541} m_CullTransparentMesh: 0 +--- !u!1 &1236232217 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1236232218} + - component: {fileID: 1236232220} + - component: {fileID: 1236232219} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1236232218 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1236232217} + 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: 1472853923} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1236232219 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1236232217} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10901, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1236232220 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1236232217} + m_CullTransparentMesh: 0 --- !u!1 &1242458542 GameObject: m_ObjectHideFlags: 0 @@ -6228,6 +6390,82 @@ MonoBehaviour: m_PersistentCalls: m_Calls: [] m_IsOn: 0 +--- !u!1 &1472853922 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1472853923} + - component: {fileID: 1472853925} + - component: {fileID: 1472853924} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1472853923 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1472853922} + 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: + - {fileID: 1236232218} + m_Father: {fileID: 172483633} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -10} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1472853924 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1472853922} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1472853925 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1472853922} + m_CullTransparentMesh: 0 --- !u!1 &1476033060 GameObject: m_ObjectHideFlags: 0 @@ -6774,6 +7012,85 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1684483641} m_CullTransparentMesh: 0 +--- !u!1 &1724807118 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1724807119} + - component: {fileID: 1724807121} + - component: {fileID: 1724807120} + m_Layer: 5 + m_Name: Label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1724807119 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1724807118} + 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: 172483633} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 9, y: -0.5} + m_SizeDelta: {x: -28, y: -3} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1724807120 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1724807118} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Add cloth to Hips +--- !u!222 &1724807121 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1724807118} + m_CullTransparentMesh: 0 --- !u!1 &1761414315 GameObject: m_ObjectHideFlags: 0 @@ -7224,6 +7541,7 @@ MonoBehaviour: m_openModel: {fileID: 2009818433} m_showBoxMan: {fileID: 1767706908} m_useJob: {fileID: 135168673} + m_addClothToHips: {fileID: 172483634} m_reconstructSprngBone: {fileID: 2144476968} m_resetSpringBone: {fileID: 1194499281} m_pauseSpringBone: {fileID: 153452230} diff --git a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewerUI.cs b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewerUI.cs index 5473dc515..a25670807 100644 --- a/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewerUI.cs +++ b/Assets/VRM10_Samples/ClothSample/ClothViewer/ClothViewerUI.cs @@ -21,6 +21,7 @@ namespace UniVRM10.Cloth.Viewer [Header("Cloth")] [SerializeField] Toggle m_useJob = default; + [SerializeField] Toggle m_addClothToHips = default; [SerializeField] Button m_reconstructSprngBone = default; [SerializeField] Button m_resetSpringBone = default; [SerializeField] Toggle m_pauseSpringBone = default; @@ -61,6 +62,7 @@ namespace UniVRM10.Cloth.Viewer m_showBoxMan = map.Get("ShowBoxMan"); m_useJob = map.Get("UseJob"); + m_addClothToHips = map.Get("AddClothToHips"); m_reconstructSprngBone = map.Get