From 216ef2f867526a12b719add68ca466da2ecd57cb Mon Sep 17 00:00:00 2001 From: yutopp Date: Fri, 28 Dec 2018 21:30:24 +0900 Subject: [PATCH] Change directory structures: Move UniGLTF/Core/* -> UniGLTF/*. Remove UniGLTF/Core --- UniGLTF/Core.meta | 10 - UniGLTF/{Core => }/Editor.meta | 0 UniGLTF/{Core => }/Editor/MaterialTests.cs | 360 +-- .../{Core => }/Editor/MaterialTests.cs.meta | 0 UniGLTF/{Core => }/Editor/UniGLTFTests.cs | 390 ++-- .../{Core => }/Editor/UniGLTFTests.cs.meta | 0 UniGLTF/{Core => }/Scripts.meta | 0 UniGLTF/{Core => }/Scripts/Editor.meta | 0 .../{Core => }/Scripts/Editor/ImporterMenu.cs | 102 +- .../Scripts/Editor/ImporterMenu.cs.meta | 0 .../Scripts/Editor/UniGLTFVersionMenu.cs | 90 +- .../Scripts/Editor/UniGLTFVersionMenu.cs.meta | 0 .../Scripts/Editor/gltfAssetPostprocessor.cs | 160 +- .../Editor/gltfAssetPostprocessor.cs.meta | 0 UniGLTF/{Core => }/Scripts/Extensions.meta | 0 .../Scripts/Extensions/ArrayExtensions.cs | 254 +-- .../Extensions/ArrayExtensions.cs.meta | 0 .../Extensions/JsonParserExtensions.cs | 38 +- .../Extensions/JsonParserExtensions.cs.meta | 0 .../Scripts/Extensions/StringExtensions.cs | 146 +- .../Extensions/StringExtensions.cs.meta | 0 .../Scripts/Extensions/UnityExtensions.cs | 626 +++--- .../Extensions/UnityExtensions.cs.meta | 0 .../Scripts/Extensions/glTFExtensions.cs | 406 ++-- .../Scripts/Extensions/glTFExtensions.cs.meta | 0 UniGLTF/{Core => }/Scripts/Format.meta | 0 .../{Core => }/Scripts/Format/BytesBuffer.cs | 374 +-- .../Scripts/Format/BytesBuffer.cs.meta | 0 .../Scripts/Format/ExtensionsAndExtras.meta | 0 .../KHR_draco_mesh_compression.cs | 64 +- .../KHR_draco_mesh_compression.cs.meta | 0 .../KHR_materials_unlit.cs | 110 +- .../KHR_materials_unlit.cs.meta | 0 .../glTFCameraExtensions.cs | 54 +- .../glTFCameraExtensions.cs.meta | 0 .../ExtensionsAndExtras/glTFExtensions.cs | 108 +- .../glTFExtensions.cs.meta | 0 .../glTFMesh.Primitives.extras.targetNames.cs | 64 +- ...Mesh.Primitives.extras.targetNames.cs.meta | 0 .../Format/ExtensionsAndExtras/glTFNode.cs | 22 +- .../ExtensionsAndExtras/glTFNode.cs.meta | 0 .../Scripts/Format/GLTFJsonFormatter.cs | 70 +- .../Scripts/Format/GLTFJsonFormatter.cs.meta | 0 .../Scripts/Format/JsonSerializableBase.cs | 44 +- .../Format/JsonSerializableBase.cs.meta | 0 .../Scripts/Format/MonoBehaviourComparator.cs | 136 +- .../Format/MonoBehaviourComparator.cs.meta | 0 UniGLTF/{Core => }/Scripts/Format/glEnum.cs | 96 +- .../{Core => }/Scripts/Format/glEnum.cs.meta | 0 UniGLTF/{Core => }/Scripts/Format/glTF.cs | 1036 ++++----- .../{Core => }/Scripts/Format/glTF.cs.meta | 0 .../Scripts/Format/glTFAnimation.cs | 420 ++-- .../Scripts/Format/glTFAnimation.cs.meta | 0 .../{Core => }/Scripts/Format/glTFAssets.cs | 68 +- .../Scripts/Format/glTFAssets.cs.meta | 0 .../{Core => }/Scripts/Format/glTFBuffer.cs | 522 ++--- .../Scripts/Format/glTFBuffer.cs.meta | 0 .../{Core => }/Scripts/Format/glTFCamera.cs | 120 +- .../Scripts/Format/glTFCamera.cs.meta | 0 .../{Core => }/Scripts/Format/glTFMaterial.cs | 450 ++-- .../Scripts/Format/glTFMaterial.cs.meta | 0 UniGLTF/{Core => }/Scripts/Format/glTFMesh.cs | 336 +-- .../Scripts/Format/glTFMesh.cs.meta | 0 UniGLTF/{Core => }/Scripts/Format/glTFNode.cs | 152 +- .../Scripts/Format/glTFNode.cs.meta | 0 UniGLTF/{Core => }/Scripts/Format/glTFSkin.cs | 68 +- .../Scripts/Format/glTFSkin.cs.meta | 0 .../{Core => }/Scripts/Format/glTFTexture.cs | 246 +- .../Scripts/Format/glTFTexture.cs.meta | 0 UniGLTF/{Core => }/Scripts/Format/glbTypes.cs | 284 +-- .../Scripts/Format/glbTypes.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO.meta | 0 .../Scripts/IO/AnimationCurveData.cs | 240 +- .../Scripts/IO/AnimationCurveData.cs.meta | 4 +- .../Scripts/IO/AnimationExporter.cs | 442 ++-- .../Scripts/IO/AnimationExporter.cs.meta | 4 +- .../Scripts/IO/AnimationImporter.cs | 660 +++--- .../Scripts/IO/AnimationImporter.cs.meta | 4 +- .../Scripts/IO/AnimationKeyframeData.cs | 106 +- .../Scripts/IO/AnimationKeyframeData.cs.meta | 4 +- UniGLTF/{Core => }/Scripts/IO/BytesReader.cs | 162 +- .../{Core => }/Scripts/IO/BytesReader.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/IStorage.cs | 148 +- .../{Core => }/Scripts/IO/IStorage.cs.meta | 0 .../{Core => }/Scripts/IO/ImporterContext.cs | 1998 ++++++++--------- .../Scripts/IO/ImporterContext.cs.meta | 0 .../{Core => }/Scripts/IO/MaterialExporter.cs | 536 ++--- .../Scripts/IO/MaterialExporter.cs.meta | 0 .../{Core => }/Scripts/IO/MaterialImporter.cs | 524 ++--- .../Scripts/IO/MaterialImporter.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/MeshExporter.cs | 522 ++--- .../Scripts/IO/MeshExporter.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/MeshImporter.cs | 1122 ++++----- .../Scripts/IO/MeshImporter.cs.meta | 0 .../Scripts/IO/MeshWithMaterials.cs | 26 +- .../Scripts/IO/MeshWithMaterials.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/NodeImporter.cs | 406 ++-- .../Scripts/IO/NodeImporter.cs.meta | 0 .../Scripts/IO/ShaderPropExporter.meta | 0 .../PreShaderPropExporter.cs | 266 +-- .../PreShaderPropExporter.cs.meta | 0 .../IO/ShaderPropExporter/ShaderProps.cs | 222 +- .../IO/ShaderPropExporter/ShaderProps.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/ShaderStore.cs | 246 +- .../{Core => }/Scripts/IO/ShaderStore.cs.meta | 0 .../Scripts/IO/StaticMeshIntegrator.cs | 372 +-- .../Scripts/IO/StaticMeshIntegrator.cs.meta | 0 .../{Core => }/Scripts/IO/TextureConverter.cs | 352 +-- .../Scripts/IO/TextureConverter.cs.meta | 4 +- .../Scripts/IO/TextureExportManager.cs | 0 .../Scripts/IO/TextureExportManager.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/TextureIO.cs | 350 +-- .../{Core => }/Scripts/IO/TextureIO.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/TextureItem.cs | 600 ++--- .../{Core => }/Scripts/IO/TextureItem.cs.meta | 0 .../{Core => }/Scripts/IO/TextureLoader.cs | 594 ++--- .../Scripts/IO/TextureLoader.cs.meta | 0 .../Scripts/IO/TextureSamplerUtil.cs | 514 ++--- .../Scripts/IO/TextureSamplerUtil.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/TriangleUtil.cs | 102 +- .../Scripts/IO/TriangleUtil.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/UnityPath.cs | 822 +++---- .../{Core => }/Scripts/IO/UnityPath.cs.meta | 0 .../Scripts/IO/ZipArchiveStorage.cs | 770 +++---- .../Scripts/IO/ZipArchiveStorage.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/glbImporter.cs | 158 +- .../{Core => }/Scripts/IO/glbImporter.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/gltfExporter.cs | 730 +++--- .../Scripts/IO/gltfExporter.cs.meta | 0 UniGLTF/{Core => }/Scripts/IO/gltfImporter.cs | 104 +- .../Scripts/IO/gltfImporter.cs.meta | 0 .../Scripts/PreExportShaderProps.meta | 0 .../Scripts/PreExportShaderProps/Standard.cs | 104 +- .../PreExportShaderProps/Standard.cs.meta | 0 .../PreExportShaderProps/UniGLTF_UniUnlit.cs | 68 +- .../UniGLTF_UniUnlit.cs.meta | 0 .../PreExportShaderProps/Unlit_Color.cs | 52 +- .../PreExportShaderProps/Unlit_Color.cs.meta | 0 .../PreExportShaderProps/Unlit_Texture.cs | 52 +- .../Unlit_Texture.cs.meta | 0 .../PreExportShaderProps/Unlit_Transparent.cs | 52 +- .../Unlit_Transparent.cs.meta | 0 .../Unlit_Transparent_Cutout.cs | 54 +- .../Unlit_Transparent_Cutout.cs.meta | 0 .../{Core => }/Scripts/UniGLTFException.cs | 34 +- .../Scripts/UniGLTFException.cs.meta | 0 UniGLTF/{Core => }/Scripts/UniGLTFVersion.cs | 22 +- .../{Core => }/Scripts/UniGLTFVersion.cs.meta | 0 .../Scripts/UniGLTFVersion_partial.cs | 16 +- .../Scripts/UniGLTFVersion_partial.cs.meta | 0 150 files changed, 10492 insertions(+), 10502 deletions(-) delete mode 100644 UniGLTF/Core.meta rename UniGLTF/{Core => }/Editor.meta (100%) rename UniGLTF/{Core => }/Editor/MaterialTests.cs (97%) rename UniGLTF/{Core => }/Editor/MaterialTests.cs.meta (100%) rename UniGLTF/{Core => }/Editor/UniGLTFTests.cs (96%) rename UniGLTF/{Core => }/Editor/UniGLTFTests.cs.meta (100%) rename UniGLTF/{Core => }/Scripts.meta (100%) rename UniGLTF/{Core => }/Scripts/Editor.meta (100%) rename UniGLTF/{Core => }/Scripts/Editor/ImporterMenu.cs (96%) rename UniGLTF/{Core => }/Scripts/Editor/ImporterMenu.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Editor/UniGLTFVersionMenu.cs (96%) rename UniGLTF/{Core => }/Scripts/Editor/UniGLTFVersionMenu.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Editor/gltfAssetPostprocessor.cs (97%) rename UniGLTF/{Core => }/Scripts/Editor/gltfAssetPostprocessor.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Extensions.meta (100%) rename UniGLTF/{Core => }/Scripts/Extensions/ArrayExtensions.cs (96%) rename UniGLTF/{Core => }/Scripts/Extensions/ArrayExtensions.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Extensions/JsonParserExtensions.cs (95%) rename UniGLTF/{Core => }/Scripts/Extensions/JsonParserExtensions.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Extensions/StringExtensions.cs (96%) rename UniGLTF/{Core => }/Scripts/Extensions/StringExtensions.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Extensions/UnityExtensions.cs (96%) rename UniGLTF/{Core => }/Scripts/Extensions/UnityExtensions.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Extensions/glTFExtensions.cs (97%) rename UniGLTF/{Core => }/Scripts/Extensions/glTFExtensions.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/BytesBuffer.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/BytesBuffer.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs (97%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/glTFNode.cs (95%) rename UniGLTF/{Core => }/Scripts/Format/ExtensionsAndExtras/glTFNode.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/GLTFJsonFormatter.cs (95%) rename UniGLTF/{Core => }/Scripts/Format/GLTFJsonFormatter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/JsonSerializableBase.cs (94%) rename UniGLTF/{Core => }/Scripts/Format/JsonSerializableBase.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/MonoBehaviourComparator.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/MonoBehaviourComparator.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glEnum.cs (95%) rename UniGLTF/{Core => }/Scripts/Format/glEnum.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTF.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTF.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFAnimation.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTFAnimation.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFAssets.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTFAssets.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFBuffer.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTFBuffer.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFCamera.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTFCamera.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFMaterial.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTFMaterial.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFMesh.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTFMesh.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFNode.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTFNode.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFSkin.cs (95%) rename UniGLTF/{Core => }/Scripts/Format/glTFSkin.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glTFTexture.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glTFTexture.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/Format/glbTypes.cs (96%) rename UniGLTF/{Core => }/Scripts/Format/glbTypes.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/AnimationCurveData.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/AnimationCurveData.cs.meta (71%) rename UniGLTF/{Core => }/Scripts/IO/AnimationExporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/AnimationExporter.cs.meta (71%) rename UniGLTF/{Core => }/Scripts/IO/AnimationImporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/AnimationImporter.cs.meta (71%) rename UniGLTF/{Core => }/Scripts/IO/AnimationKeyframeData.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/AnimationKeyframeData.cs.meta (71%) rename UniGLTF/{Core => }/Scripts/IO/BytesReader.cs (95%) rename UniGLTF/{Core => }/Scripts/IO/BytesReader.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/IStorage.cs (95%) rename UniGLTF/{Core => }/Scripts/IO/IStorage.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/ImporterContext.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/ImporterContext.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/MaterialExporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/MaterialExporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/MaterialImporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/MaterialImporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/MeshExporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/MeshExporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/MeshImporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/MeshImporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/MeshWithMaterials.cs (95%) rename UniGLTF/{Core => }/Scripts/IO/MeshWithMaterials.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/NodeImporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/NodeImporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/ShaderPropExporter.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/ShaderPropExporter/ShaderProps.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/ShaderPropExporter/ShaderProps.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/ShaderStore.cs (95%) rename UniGLTF/{Core => }/Scripts/IO/ShaderStore.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/StaticMeshIntegrator.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/StaticMeshIntegrator.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/TextureConverter.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/TextureConverter.cs.meta (71%) rename UniGLTF/{Core => }/Scripts/IO/TextureExportManager.cs (100%) rename UniGLTF/{Core => }/Scripts/IO/TextureExportManager.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/TextureIO.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/TextureIO.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/TextureItem.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/TextureItem.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/TextureLoader.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/TextureLoader.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/TextureSamplerUtil.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/TextureSamplerUtil.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/TriangleUtil.cs (95%) rename UniGLTF/{Core => }/Scripts/IO/TriangleUtil.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/UnityPath.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/UnityPath.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/ZipArchiveStorage.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/ZipArchiveStorage.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/glbImporter.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/glbImporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/gltfExporter.cs (97%) rename UniGLTF/{Core => }/Scripts/IO/gltfExporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/IO/gltfImporter.cs (96%) rename UniGLTF/{Core => }/Scripts/IO/gltfImporter.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps.meta (100%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Standard.cs (97%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Standard.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs (97%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Unlit_Color.cs (96%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Unlit_Color.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Unlit_Texture.cs (96%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Unlit_Texture.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Unlit_Transparent.cs (96%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Unlit_Transparent.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs (96%) rename UniGLTF/{Core => }/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/UniGLTFException.cs (96%) rename UniGLTF/{Core => }/Scripts/UniGLTFException.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/UniGLTFVersion.cs (94%) rename UniGLTF/{Core => }/Scripts/UniGLTFVersion.cs.meta (100%) rename UniGLTF/{Core => }/Scripts/UniGLTFVersion_partial.cs (94%) rename UniGLTF/{Core => }/Scripts/UniGLTFVersion_partial.cs.meta (100%) diff --git a/UniGLTF/Core.meta b/UniGLTF/Core.meta deleted file mode 100644 index a3c576c34..000000000 --- a/UniGLTF/Core.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: d2d37db807d5f0946b5d264a870ac053 -folderAsset: yes -timeCreated: 1517139118 -licenseType: Free -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UniGLTF/Core/Editor.meta b/UniGLTF/Editor.meta similarity index 100% rename from UniGLTF/Core/Editor.meta rename to UniGLTF/Editor.meta diff --git a/UniGLTF/Core/Editor/MaterialTests.cs b/UniGLTF/Editor/MaterialTests.cs similarity index 97% rename from UniGLTF/Core/Editor/MaterialTests.cs rename to UniGLTF/Editor/MaterialTests.cs index 7685532c4..015e362ca 100644 --- a/UniGLTF/Core/Editor/MaterialTests.cs +++ b/UniGLTF/Editor/MaterialTests.cs @@ -1,180 +1,180 @@ -using NUnit.Framework; - - -namespace UniGLTF -{ - public class MaterialTests - { - [Test] - public void UnlitShaderImportTest() - { - var shaderStore = new ShaderStore(null); - - { - // OPAQUE/Color - var shader = shaderStore.GetShader(new glTFMaterial - { - alphaMode = "OPAQUE", - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorFactor = new float[] { 1, 0, 0, 1 }, - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - - { - // OPAQUE/Texture - var shader = shaderStore.GetShader(new glTFMaterial - { - alphaMode = "OPAQUE", - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorTexture = new glTFMaterialBaseColorTextureInfo(), - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - - { - // OPAQUE/Color/Texture - var shader = shaderStore.GetShader(new glTFMaterial - { - alphaMode = "OPAQUE", - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorFactor = new float[] { 1, 0, 0, 1 }, - baseColorTexture = new glTFMaterialBaseColorTextureInfo(), - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - - { - // BLEND/Color - var shader = shaderStore.GetShader(new glTFMaterial - { - alphaMode = "BLEND", - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorFactor = new float[] { 1, 0, 0, 1 }, - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - - { - // BLEND/Texture - var shader = shaderStore.GetShader(new glTFMaterial - { - alphaMode = "BLEND", - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorTexture = new glTFMaterialBaseColorTextureInfo(), - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - - { - // BLEND/Color/Texture - var shader = shaderStore.GetShader(new glTFMaterial - { - alphaMode = "BLEND", - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorFactor = new float[] { 1, 0, 0, 1 }, - baseColorTexture = new glTFMaterialBaseColorTextureInfo(), - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - - { - // MASK/Texture - var shader = shaderStore.GetShader(new glTFMaterial - { - alphaMode = "MASK", - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorTexture = new glTFMaterialBaseColorTextureInfo(), - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - - { - // MASK/Color/Texture - var shader = shaderStore.GetShader(new glTFMaterial - { - alphaMode = "MASK", - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorFactor = new float[] { 1, 0, 0, 1 }, - baseColorTexture = new glTFMaterialBaseColorTextureInfo(), - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - - { - // default - var shader = shaderStore.GetShader(new glTFMaterial - { - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit { } - } - }); - Assert.AreEqual("UniGLTF/UniUnlit", shader.name); - } - } - - [Test] - public void MaterialImportTest() - { - var shaderStore = new ShaderStore(null); - var materialImporter = new MaterialImporter(shaderStore, null); - - { - var material = materialImporter.CreateMaterial(0, new glTFMaterial - { - - }); - Assert.AreEqual("Standard", material.shader.name); - } - } - } -} +using NUnit.Framework; + + +namespace UniGLTF +{ + public class MaterialTests + { + [Test] + public void UnlitShaderImportTest() + { + var shaderStore = new ShaderStore(null); + + { + // OPAQUE/Color + var shader = shaderStore.GetShader(new glTFMaterial + { + alphaMode = "OPAQUE", + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorFactor = new float[] { 1, 0, 0, 1 }, + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + + { + // OPAQUE/Texture + var shader = shaderStore.GetShader(new glTFMaterial + { + alphaMode = "OPAQUE", + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorTexture = new glTFMaterialBaseColorTextureInfo(), + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + + { + // OPAQUE/Color/Texture + var shader = shaderStore.GetShader(new glTFMaterial + { + alphaMode = "OPAQUE", + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorFactor = new float[] { 1, 0, 0, 1 }, + baseColorTexture = new glTFMaterialBaseColorTextureInfo(), + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + + { + // BLEND/Color + var shader = shaderStore.GetShader(new glTFMaterial + { + alphaMode = "BLEND", + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorFactor = new float[] { 1, 0, 0, 1 }, + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + + { + // BLEND/Texture + var shader = shaderStore.GetShader(new glTFMaterial + { + alphaMode = "BLEND", + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorTexture = new glTFMaterialBaseColorTextureInfo(), + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + + { + // BLEND/Color/Texture + var shader = shaderStore.GetShader(new glTFMaterial + { + alphaMode = "BLEND", + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorFactor = new float[] { 1, 0, 0, 1 }, + baseColorTexture = new glTFMaterialBaseColorTextureInfo(), + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + + { + // MASK/Texture + var shader = shaderStore.GetShader(new glTFMaterial + { + alphaMode = "MASK", + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorTexture = new glTFMaterialBaseColorTextureInfo(), + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + + { + // MASK/Color/Texture + var shader = shaderStore.GetShader(new glTFMaterial + { + alphaMode = "MASK", + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorFactor = new float[] { 1, 0, 0, 1 }, + baseColorTexture = new glTFMaterialBaseColorTextureInfo(), + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + + { + // default + var shader = shaderStore.GetShader(new glTFMaterial + { + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit { } + } + }); + Assert.AreEqual("UniGLTF/UniUnlit", shader.name); + } + } + + [Test] + public void MaterialImportTest() + { + var shaderStore = new ShaderStore(null); + var materialImporter = new MaterialImporter(shaderStore, null); + + { + var material = materialImporter.CreateMaterial(0, new glTFMaterial + { + + }); + Assert.AreEqual("Standard", material.shader.name); + } + } + } +} diff --git a/UniGLTF/Core/Editor/MaterialTests.cs.meta b/UniGLTF/Editor/MaterialTests.cs.meta similarity index 100% rename from UniGLTF/Core/Editor/MaterialTests.cs.meta rename to UniGLTF/Editor/MaterialTests.cs.meta diff --git a/UniGLTF/Core/Editor/UniGLTFTests.cs b/UniGLTF/Editor/UniGLTFTests.cs similarity index 96% rename from UniGLTF/Core/Editor/UniGLTFTests.cs rename to UniGLTF/Editor/UniGLTFTests.cs index d66e9e264..51b36cad9 100644 --- a/UniGLTF/Core/Editor/UniGLTFTests.cs +++ b/UniGLTF/Editor/UniGLTFTests.cs @@ -1,195 +1,195 @@ -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using UniJSON; -using UnityEngine; - - -namespace UniGLTF -{ - public class UniGLTFTests - { - static GameObject CreateSimpelScene() - { - var root = new GameObject("gltfRoot").transform; - - var scene = new GameObject("scene0").transform; - scene.SetParent(root, false); - scene.localPosition = new Vector3(1, 2, 3); - - return root.gameObject; - } - - void AssertAreEqual(Transform go, Transform other) - { - var lt = go.Traverse().GetEnumerator(); - var rt = go.Traverse().GetEnumerator(); - - while (lt.MoveNext()) - { - if (!rt.MoveNext()) - { - throw new Exception("rt shorter"); - } - - MonoBehaviourComparator.AssertAreEquals(lt.Current.gameObject, rt.Current.gameObject); - } - - if (rt.MoveNext()) - { - throw new Exception("rt longer"); - } - } - - [Test] - public void UniGLTFSimpleSceneTest() - { - var go = CreateSimpelScene(); - var context = new ImporterContext(); - - try - { - // export - var gltf = new glTF(); - - string json = null; - using (var exporter = new gltfExporter(gltf)) - { - exporter.Prepare(go); - exporter.Export(); - - // remove empty buffer - gltf.buffers.Clear(); - - json = gltf.ToJson(); - } - - // import - context.ParseJson(json, new SimpleStorage(new ArraySegment())); - //Debug.LogFormat("{0}", context.Json); - context.Load(); - - AssertAreEqual(go.transform, context.Root.transform); - } - finally - { - //Debug.LogFormat("Destory, {0}", go.name); - GameObject.DestroyImmediate(go); - context.EditorDestroyRootAndAssets(); - } - } - - void BufferTest(int init, params int[] size) - { - var initBytes = init == 0 ? null : new byte[init]; - var storage = new ArrayByteBuffer(initBytes); - var buffer = new glTFBuffer(storage); - - var values = new List(); - int offset = 0; - foreach (var x in size) - { - var nums = Enumerable.Range(offset, x).Select(y => (Byte)y).ToArray(); - values.AddRange(nums); - var bytes = new ArraySegment(nums); - offset += x; - buffer.Append(bytes, glBufferTarget.NONE); - } - - Assert.AreEqual(values.Count, buffer.byteLength); - Assert.True(Enumerable.SequenceEqual(values, buffer.GetBytes().ToArray())); - } - - [Test] - public void BufferTest() - { - BufferTest(0, 0, 100, 200); - BufferTest(0, 128); - BufferTest(0, 256); - - BufferTest(1024, 0); - BufferTest(1024, 128); - BufferTest(1024, 2048); - BufferTest(1024, 900, 900); - } - - [Test] - public void UnityPathTest() - { - var root = UnityPath.FromUnityPath("."); - Assert.IsFalse(root.IsNull); - Assert.IsFalse(root.IsUnderAssetsFolder); - Assert.AreEqual(UnityPath.FromUnityPath("."), root); - - var assets = UnityPath.FromUnityPath("Assets"); - Assert.IsFalse(assets.IsNull); - Assert.IsTrue(assets.IsUnderAssetsFolder); - - var rootChild = root.Child("Assets"); - Assert.AreEqual(assets, rootChild); - - var assetsChild = assets.Child("Hoge"); - var hoge = UnityPath.FromUnityPath("Assets/Hoge"); - Assert.AreEqual(assetsChild, hoge); - - //var children = root.TravserseDir().ToArray(); - } - - [Test] - public void VersionChecker() - { - Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("hoge", 1, 16)); - Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.16", 1, 16)); - Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.15", 1, 16)); - Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-11.16", 1, 16)); - Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-0.16", 1, 16)); - Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF", 1, 16)); - } - - [Test] - public void MeshTest() - { - var mesh = new glTFMesh("mesh") - { - primitives = new List - { - new glTFPrimitives - { - attributes=new glTFAttributes - { - POSITION=0, - } - } - } - }; - - var f = new JsonFormatter(); - f.Serialize(mesh); - - var json = new Utf8String(f.GetStoreBytes()).ToString(); - Debug.Log(json); - } - - [Test] - public void PrimitiveTest() - { - var prims = new List { - new glTFPrimitives - { - attributes = new glTFAttributes - { - POSITION = 0, - } - } - }; - - var f = new JsonFormatter(); - f.Serialize(prims); - - var json = new Utf8String(f.GetStoreBytes()).ToString(); - Debug.Log(json); - } - - } -} +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using UniJSON; +using UnityEngine; + + +namespace UniGLTF +{ + public class UniGLTFTests + { + static GameObject CreateSimpelScene() + { + var root = new GameObject("gltfRoot").transform; + + var scene = new GameObject("scene0").transform; + scene.SetParent(root, false); + scene.localPosition = new Vector3(1, 2, 3); + + return root.gameObject; + } + + void AssertAreEqual(Transform go, Transform other) + { + var lt = go.Traverse().GetEnumerator(); + var rt = go.Traverse().GetEnumerator(); + + while (lt.MoveNext()) + { + if (!rt.MoveNext()) + { + throw new Exception("rt shorter"); + } + + MonoBehaviourComparator.AssertAreEquals(lt.Current.gameObject, rt.Current.gameObject); + } + + if (rt.MoveNext()) + { + throw new Exception("rt longer"); + } + } + + [Test] + public void UniGLTFSimpleSceneTest() + { + var go = CreateSimpelScene(); + var context = new ImporterContext(); + + try + { + // export + var gltf = new glTF(); + + string json = null; + using (var exporter = new gltfExporter(gltf)) + { + exporter.Prepare(go); + exporter.Export(); + + // remove empty buffer + gltf.buffers.Clear(); + + json = gltf.ToJson(); + } + + // import + context.ParseJson(json, new SimpleStorage(new ArraySegment())); + //Debug.LogFormat("{0}", context.Json); + context.Load(); + + AssertAreEqual(go.transform, context.Root.transform); + } + finally + { + //Debug.LogFormat("Destory, {0}", go.name); + GameObject.DestroyImmediate(go); + context.EditorDestroyRootAndAssets(); + } + } + + void BufferTest(int init, params int[] size) + { + var initBytes = init == 0 ? null : new byte[init]; + var storage = new ArrayByteBuffer(initBytes); + var buffer = new glTFBuffer(storage); + + var values = new List(); + int offset = 0; + foreach (var x in size) + { + var nums = Enumerable.Range(offset, x).Select(y => (Byte)y).ToArray(); + values.AddRange(nums); + var bytes = new ArraySegment(nums); + offset += x; + buffer.Append(bytes, glBufferTarget.NONE); + } + + Assert.AreEqual(values.Count, buffer.byteLength); + Assert.True(Enumerable.SequenceEqual(values, buffer.GetBytes().ToArray())); + } + + [Test] + public void BufferTest() + { + BufferTest(0, 0, 100, 200); + BufferTest(0, 128); + BufferTest(0, 256); + + BufferTest(1024, 0); + BufferTest(1024, 128); + BufferTest(1024, 2048); + BufferTest(1024, 900, 900); + } + + [Test] + public void UnityPathTest() + { + var root = UnityPath.FromUnityPath("."); + Assert.IsFalse(root.IsNull); + Assert.IsFalse(root.IsUnderAssetsFolder); + Assert.AreEqual(UnityPath.FromUnityPath("."), root); + + var assets = UnityPath.FromUnityPath("Assets"); + Assert.IsFalse(assets.IsNull); + Assert.IsTrue(assets.IsUnderAssetsFolder); + + var rootChild = root.Child("Assets"); + Assert.AreEqual(assets, rootChild); + + var assetsChild = assets.Child("Hoge"); + var hoge = UnityPath.FromUnityPath("Assets/Hoge"); + Assert.AreEqual(assetsChild, hoge); + + //var children = root.TravserseDir().ToArray(); + } + + [Test] + public void VersionChecker() + { + Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("hoge", 1, 16)); + Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.16", 1, 16)); + Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.15", 1, 16)); + Assert.False(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-11.16", 1, 16)); + Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF-0.16", 1, 16)); + Assert.True(ImporterContext.IsGeneratedUniGLTFAndOlderThan("UniGLTF", 1, 16)); + } + + [Test] + public void MeshTest() + { + var mesh = new glTFMesh("mesh") + { + primitives = new List + { + new glTFPrimitives + { + attributes=new glTFAttributes + { + POSITION=0, + } + } + } + }; + + var f = new JsonFormatter(); + f.Serialize(mesh); + + var json = new Utf8String(f.GetStoreBytes()).ToString(); + Debug.Log(json); + } + + [Test] + public void PrimitiveTest() + { + var prims = new List { + new glTFPrimitives + { + attributes = new glTFAttributes + { + POSITION = 0, + } + } + }; + + var f = new JsonFormatter(); + f.Serialize(prims); + + var json = new Utf8String(f.GetStoreBytes()).ToString(); + Debug.Log(json); + } + + } +} diff --git a/UniGLTF/Core/Editor/UniGLTFTests.cs.meta b/UniGLTF/Editor/UniGLTFTests.cs.meta similarity index 100% rename from UniGLTF/Core/Editor/UniGLTFTests.cs.meta rename to UniGLTF/Editor/UniGLTFTests.cs.meta diff --git a/UniGLTF/Core/Scripts.meta b/UniGLTF/Scripts.meta similarity index 100% rename from UniGLTF/Core/Scripts.meta rename to UniGLTF/Scripts.meta diff --git a/UniGLTF/Core/Scripts/Editor.meta b/UniGLTF/Scripts/Editor.meta similarity index 100% rename from UniGLTF/Core/Scripts/Editor.meta rename to UniGLTF/Scripts/Editor.meta diff --git a/UniGLTF/Core/Scripts/Editor/ImporterMenu.cs b/UniGLTF/Scripts/Editor/ImporterMenu.cs similarity index 96% rename from UniGLTF/Core/Scripts/Editor/ImporterMenu.cs rename to UniGLTF/Scripts/Editor/ImporterMenu.cs index d12a02b04..816600e1f 100644 --- a/UniGLTF/Core/Scripts/Editor/ImporterMenu.cs +++ b/UniGLTF/Scripts/Editor/ImporterMenu.cs @@ -1,51 +1,51 @@ -using System.IO; -using UnityEditor; -using UnityEngine; - - -namespace UniGLTF -{ - public static class ImporterMenu - { - [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Import", priority = 1)] - public static void ImportMenu() - { - var path = EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb,zip"); - if (string.IsNullOrEmpty(path)) - { - return; - } - - if (Application.isPlaying) - { - // - // load into scene - // - var context = new ImporterContext(); - context.Load(path); - context.ShowMeshes(); - Selection.activeGameObject = context.Root; - } - else - { - // - // save as asset - // - if (path.StartsWithUnityAssetPath()) - { - Debug.LogWarningFormat("disallow import from folder under the Assets"); - return; - } - - var assetPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab"); - if (string.IsNullOrEmpty(path)) - { - return; - } - - // import as asset - gltfAssetPostprocessor.ImportAsset(path, Path.GetExtension(path).ToLower(), UnityPath.FromFullpath(assetPath)); - } - } - } -} +using System.IO; +using UnityEditor; +using UnityEngine; + + +namespace UniGLTF +{ + public static class ImporterMenu + { + [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Import", priority = 1)] + public static void ImportMenu() + { + var path = EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb,zip"); + if (string.IsNullOrEmpty(path)) + { + return; + } + + if (Application.isPlaying) + { + // + // load into scene + // + var context = new ImporterContext(); + context.Load(path); + context.ShowMeshes(); + Selection.activeGameObject = context.Root; + } + else + { + // + // save as asset + // + if (path.StartsWithUnityAssetPath()) + { + Debug.LogWarningFormat("disallow import from folder under the Assets"); + return; + } + + var assetPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab"); + if (string.IsNullOrEmpty(path)) + { + return; + } + + // import as asset + gltfAssetPostprocessor.ImportAsset(path, Path.GetExtension(path).ToLower(), UnityPath.FromFullpath(assetPath)); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/Editor/ImporterMenu.cs.meta b/UniGLTF/Scripts/Editor/ImporterMenu.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Editor/ImporterMenu.cs.meta rename to UniGLTF/Scripts/Editor/ImporterMenu.cs.meta diff --git a/UniGLTF/Core/Scripts/Editor/UniGLTFVersionMenu.cs b/UniGLTF/Scripts/Editor/UniGLTFVersionMenu.cs similarity index 96% rename from UniGLTF/Core/Scripts/Editor/UniGLTFVersionMenu.cs rename to UniGLTF/Scripts/Editor/UniGLTFVersionMenu.cs index de2390c2b..a52073cf3 100644 --- a/UniGLTF/Core/Scripts/Editor/UniGLTFVersionMenu.cs +++ b/UniGLTF/Scripts/Editor/UniGLTFVersionMenu.cs @@ -1,45 +1,45 @@ -#if UNIGLTF_DEVELOP -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEditor; - - -namespace UniGLTF -{ - public static class UniGLTFVersionMenu - { - public const int MENU_PRIORITY = 99; - static string path = "Assets/UniGLTF/Core/Scripts/UniGLTFVersion.cs"; - - const string template = @" -namespace UniGLTF -{{ - public static partial class UniGLTFVersion - {{ - public const int MAJOR = {0}; - public const int MINOR = {1}; - - public const string VERSION = ""{0}.{1}""; - }} -}} -"; - - [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Increment", priority = MENU_PRIORITY)] - public static void IncrementVersion() - { - var source = string.Format(template, UniGLTFVersion.MAJOR, UniGLTFVersion.MINOR + 1); - File.WriteAllText(path, source); - AssetDatabase.Refresh(); - } - - [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Decrement", priority = MENU_PRIORITY)] - public static void DecrementVersion() - { - var source = string.Format(template, UniGLTFVersion.MAJOR, UniGLTFVersion.MINOR - 1); - File.WriteAllText(path, source); - AssetDatabase.Refresh(); - } - } -} -#endif +#if UNIGLTF_DEVELOP +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; + + +namespace UniGLTF +{ + public static class UniGLTFVersionMenu + { + public const int MENU_PRIORITY = 99; + static string path = "Assets/UniGLTF/Core/Scripts/UniGLTFVersion.cs"; + + const string template = @" +namespace UniGLTF +{{ + public static partial class UniGLTFVersion + {{ + public const int MAJOR = {0}; + public const int MINOR = {1}; + + public const string VERSION = ""{0}.{1}""; + }} +}} +"; + + [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Increment", priority = MENU_PRIORITY)] + public static void IncrementVersion() + { + var source = string.Format(template, UniGLTFVersion.MAJOR, UniGLTFVersion.MINOR + 1); + File.WriteAllText(path, source); + AssetDatabase.Refresh(); + } + + [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Decrement", priority = MENU_PRIORITY)] + public static void DecrementVersion() + { + var source = string.Format(template, UniGLTFVersion.MAJOR, UniGLTFVersion.MINOR - 1); + File.WriteAllText(path, source); + AssetDatabase.Refresh(); + } + } +} +#endif diff --git a/UniGLTF/Core/Scripts/Editor/UniGLTFVersionMenu.cs.meta b/UniGLTF/Scripts/Editor/UniGLTFVersionMenu.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Editor/UniGLTFVersionMenu.cs.meta rename to UniGLTF/Scripts/Editor/UniGLTFVersionMenu.cs.meta diff --git a/UniGLTF/Core/Scripts/Editor/gltfAssetPostprocessor.cs b/UniGLTF/Scripts/Editor/gltfAssetPostprocessor.cs similarity index 97% rename from UniGLTF/Core/Scripts/Editor/gltfAssetPostprocessor.cs rename to UniGLTF/Scripts/Editor/gltfAssetPostprocessor.cs index 2990f3035..2ec3b0732 100644 --- a/UniGLTF/Core/Scripts/Editor/gltfAssetPostprocessor.cs +++ b/UniGLTF/Scripts/Editor/gltfAssetPostprocessor.cs @@ -1,80 +1,80 @@ -using System; -using System.IO; -using UnityEditor; -using UnityEngine; - - -namespace UniGLTF -{ - public class gltfAssetPostprocessor : AssetPostprocessor - { - static void OnPostprocessAllAssets(string[] importedAssets, - string[] deletedAssets, - string[] movedAssets, - string[] movedFromAssetPaths) - { - foreach (string path in importedAssets) - { - var ext = Path.GetExtension(path).ToLower(); - switch (ext) - { - case ".gltf": - case ".glb": - { - var gltfPath = UnityPath.FromUnityPath(path); - var prefabPath = gltfPath.Parent.Child(gltfPath.FileNameWithoutExtension + ".prefab"); - ImportAsset(UnityPath.FromUnityPath(path).FullPath, ext, prefabPath); - break; - } - } - } - } - - public static void ImportAsset(string src, string ext, UnityPath prefabPath) - { - if (!prefabPath.IsUnderAssetsFolder) - { - Debug.LogWarningFormat("out of asset path: {0}", prefabPath); - return; - } - - var context = new ImporterContext(); - context.Parse(src); - - // Extract textures to assets folder - context.ExtranctImages(prefabPath); - - ImportDelayed(src, prefabPath, context); - } - - static void ImportDelayed(string src, UnityPath prefabPath, ImporterContext context) - { - EditorApplication.delayCall += () => - { - // - // After textures imported(To ensure TextureImporter be accessible). - // - try - { - context.Load(); - context.SaveAsAsset(prefabPath); - context.EditorDestroyRoot(); - } - catch (UniGLTFNotSupportedException ex) - { - Debug.LogWarningFormat("{0}: {1}", - src, - ex.Message - ); - context.EditorDestroyRootAndAssets(); - } - catch (Exception ex) - { - Debug.LogErrorFormat("import error: {0}", src); - Debug.LogErrorFormat("{0}", ex); - context.EditorDestroyRootAndAssets(); - } - }; - } - } -} +using System; +using System.IO; +using UnityEditor; +using UnityEngine; + + +namespace UniGLTF +{ + public class gltfAssetPostprocessor : AssetPostprocessor + { + static void OnPostprocessAllAssets(string[] importedAssets, + string[] deletedAssets, + string[] movedAssets, + string[] movedFromAssetPaths) + { + foreach (string path in importedAssets) + { + var ext = Path.GetExtension(path).ToLower(); + switch (ext) + { + case ".gltf": + case ".glb": + { + var gltfPath = UnityPath.FromUnityPath(path); + var prefabPath = gltfPath.Parent.Child(gltfPath.FileNameWithoutExtension + ".prefab"); + ImportAsset(UnityPath.FromUnityPath(path).FullPath, ext, prefabPath); + break; + } + } + } + } + + public static void ImportAsset(string src, string ext, UnityPath prefabPath) + { + if (!prefabPath.IsUnderAssetsFolder) + { + Debug.LogWarningFormat("out of asset path: {0}", prefabPath); + return; + } + + var context = new ImporterContext(); + context.Parse(src); + + // Extract textures to assets folder + context.ExtranctImages(prefabPath); + + ImportDelayed(src, prefabPath, context); + } + + static void ImportDelayed(string src, UnityPath prefabPath, ImporterContext context) + { + EditorApplication.delayCall += () => + { + // + // After textures imported(To ensure TextureImporter be accessible). + // + try + { + context.Load(); + context.SaveAsAsset(prefabPath); + context.EditorDestroyRoot(); + } + catch (UniGLTFNotSupportedException ex) + { + Debug.LogWarningFormat("{0}: {1}", + src, + ex.Message + ); + context.EditorDestroyRootAndAssets(); + } + catch (Exception ex) + { + Debug.LogErrorFormat("import error: {0}", src); + Debug.LogErrorFormat("{0}", ex); + context.EditorDestroyRootAndAssets(); + } + }; + } + } +} diff --git a/UniGLTF/Core/Scripts/Editor/gltfAssetPostprocessor.cs.meta b/UniGLTF/Scripts/Editor/gltfAssetPostprocessor.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Editor/gltfAssetPostprocessor.cs.meta rename to UniGLTF/Scripts/Editor/gltfAssetPostprocessor.cs.meta diff --git a/UniGLTF/Core/Scripts/Extensions.meta b/UniGLTF/Scripts/Extensions.meta similarity index 100% rename from UniGLTF/Core/Scripts/Extensions.meta rename to UniGLTF/Scripts/Extensions.meta diff --git a/UniGLTF/Core/Scripts/Extensions/ArrayExtensions.cs b/UniGLTF/Scripts/Extensions/ArrayExtensions.cs similarity index 96% rename from UniGLTF/Core/Scripts/Extensions/ArrayExtensions.cs rename to UniGLTF/Scripts/Extensions/ArrayExtensions.cs index 3aebceef0..e764f4f4e 100644 --- a/UniGLTF/Core/Scripts/Extensions/ArrayExtensions.cs +++ b/UniGLTF/Scripts/Extensions/ArrayExtensions.cs @@ -1,127 +1,127 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Runtime.InteropServices; - - -namespace UniGLTF -{ - public static class Pin - { - public static Pin Create(ArraySegment src) where T : struct - { - return new Pin(src); - } - public static Pin Create(T[] src) where T : struct - { - return Create(new ArraySegment(src)); - } - } - public class Pin : IDisposable - where T : struct - { - GCHandle m_pinnedArray; - - ArraySegment m_src; - - public int Length - { - get - { - return m_src.Count * Marshal.SizeOf(typeof(T)); - } - } - - public Pin(ArraySegment src) - { - m_src = src; - m_pinnedArray = GCHandle.Alloc(src.Array, GCHandleType.Pinned); - } - - public IntPtr Ptr - { - get - { - var ptr = m_pinnedArray.AddrOfPinnedObject(); - return new IntPtr(ptr.ToInt64() + m_src.Offset); - } - } - - #region IDisposable Support - private bool disposedValue = false; // 重複する呼び出しを検出するには - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // TODO: マネージ状態を破棄します (マネージ オブジェクト)。 - } - - // TODO: アンマネージ リソース (アンマネージ オブジェクト) を解放し、下のファイナライザーをオーバーライドします。 - // TODO: 大きなフィールドを null に設定します。 - if (m_pinnedArray.IsAllocated) - { - m_pinnedArray.Free(); - } - - disposedValue = true; - } - } - - // TODO: 上の Dispose(bool disposing) にアンマネージ リソースを解放するコードが含まれる場合にのみ、ファイナライザーをオーバーライドします。 - // ~Pin() { - // // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 - // Dispose(false); - // } - - // このコードは、破棄可能なパターンを正しく実装できるように追加されました。 - public void Dispose() - { - // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 - Dispose(true); - // TODO: 上のファイナライザーがオーバーライドされる場合は、次の行のコメントを解除してください。 - // GC.SuppressFinalize(this); - } - #endregion - } - - public static class ArrayExtensions - { - public static int MarshalCoyTo(this ArraySegment src, T[] dst) where T : struct - { - var size = dst.Length * Marshal.SizeOf(typeof(T)); - using (var pin = Pin.Create(dst)) - { - Marshal.Copy(src.Array, src.Offset, pin.Ptr, size); - } - return size; - } - - public static Byte[] ToArray(this ArraySegment src) - { - var dst = new byte[src.Count]; - Array.Copy(src.Array, src.Offset, dst, 0, src.Count); - return dst; - } - - public static T[] SelectInplace(this T[] src, Func pred) - { - for (int i = 0; i < src.Length; ++i) - { - src[i] = pred(src[i]); - } - return src; - } - } - - public static class ListExtensions - { - public static void Assign(this List dst, T[] src, Func pred) - { - dst.Capacity = src.Length; - dst.AddRange(src.Select(pred)); - } - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using System.Runtime.InteropServices; + + +namespace UniGLTF +{ + public static class Pin + { + public static Pin Create(ArraySegment src) where T : struct + { + return new Pin(src); + } + public static Pin Create(T[] src) where T : struct + { + return Create(new ArraySegment(src)); + } + } + public class Pin : IDisposable + where T : struct + { + GCHandle m_pinnedArray; + + ArraySegment m_src; + + public int Length + { + get + { + return m_src.Count * Marshal.SizeOf(typeof(T)); + } + } + + public Pin(ArraySegment src) + { + m_src = src; + m_pinnedArray = GCHandle.Alloc(src.Array, GCHandleType.Pinned); + } + + public IntPtr Ptr + { + get + { + var ptr = m_pinnedArray.AddrOfPinnedObject(); + return new IntPtr(ptr.ToInt64() + m_src.Offset); + } + } + + #region IDisposable Support + private bool disposedValue = false; // 重複する呼び出しを検出するには + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: マネージ状態を破棄します (マネージ オブジェクト)。 + } + + // TODO: アンマネージ リソース (アンマネージ オブジェクト) を解放し、下のファイナライザーをオーバーライドします。 + // TODO: 大きなフィールドを null に設定します。 + if (m_pinnedArray.IsAllocated) + { + m_pinnedArray.Free(); + } + + disposedValue = true; + } + } + + // TODO: 上の Dispose(bool disposing) にアンマネージ リソースを解放するコードが含まれる場合にのみ、ファイナライザーをオーバーライドします。 + // ~Pin() { + // // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 + // Dispose(false); + // } + + // このコードは、破棄可能なパターンを正しく実装できるように追加されました。 + public void Dispose() + { + // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 + Dispose(true); + // TODO: 上のファイナライザーがオーバーライドされる場合は、次の行のコメントを解除してください。 + // GC.SuppressFinalize(this); + } + #endregion + } + + public static class ArrayExtensions + { + public static int MarshalCoyTo(this ArraySegment src, T[] dst) where T : struct + { + var size = dst.Length * Marshal.SizeOf(typeof(T)); + using (var pin = Pin.Create(dst)) + { + Marshal.Copy(src.Array, src.Offset, pin.Ptr, size); + } + return size; + } + + public static Byte[] ToArray(this ArraySegment src) + { + var dst = new byte[src.Count]; + Array.Copy(src.Array, src.Offset, dst, 0, src.Count); + return dst; + } + + public static T[] SelectInplace(this T[] src, Func pred) + { + for (int i = 0; i < src.Length; ++i) + { + src[i] = pred(src[i]); + } + return src; + } + } + + public static class ListExtensions + { + public static void Assign(this List dst, T[] src, Func pred) + { + dst.Capacity = src.Length; + dst.AddRange(src.Select(pred)); + } + } +} diff --git a/UniGLTF/Core/Scripts/Extensions/ArrayExtensions.cs.meta b/UniGLTF/Scripts/Extensions/ArrayExtensions.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Extensions/ArrayExtensions.cs.meta rename to UniGLTF/Scripts/Extensions/ArrayExtensions.cs.meta diff --git a/UniGLTF/Core/Scripts/Extensions/JsonParserExtensions.cs b/UniGLTF/Scripts/Extensions/JsonParserExtensions.cs similarity index 95% rename from UniGLTF/Core/Scripts/Extensions/JsonParserExtensions.cs rename to UniGLTF/Scripts/Extensions/JsonParserExtensions.cs index e8e5341eb..2163a4204 100644 --- a/UniGLTF/Core/Scripts/Extensions/JsonParserExtensions.cs +++ b/UniGLTF/Scripts/Extensions/JsonParserExtensions.cs @@ -1,19 +1,19 @@ -using System.Linq; -using UnityEngine; -using System.Collections.Generic; - - -namespace UniJSON -{ - public static class JsonParserExtensions - { - public static List DeserializeList(this ListTreeNode jsonList) - { - return jsonList.ArrayItems().Select(x => { - - return JsonUtility.FromJson(new Utf8String(x.Value.Bytes).ToString()); - - }).ToList(); - } - } -} +using System.Linq; +using UnityEngine; +using System.Collections.Generic; + + +namespace UniJSON +{ + public static class JsonParserExtensions + { + public static List DeserializeList(this ListTreeNode jsonList) + { + return jsonList.ArrayItems().Select(x => { + + return JsonUtility.FromJson(new Utf8String(x.Value.Bytes).ToString()); + + }).ToList(); + } + } +} diff --git a/UniGLTF/Core/Scripts/Extensions/JsonParserExtensions.cs.meta b/UniGLTF/Scripts/Extensions/JsonParserExtensions.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Extensions/JsonParserExtensions.cs.meta rename to UniGLTF/Scripts/Extensions/JsonParserExtensions.cs.meta diff --git a/UniGLTF/Core/Scripts/Extensions/StringExtensions.cs b/UniGLTF/Scripts/Extensions/StringExtensions.cs similarity index 96% rename from UniGLTF/Core/Scripts/Extensions/StringExtensions.cs rename to UniGLTF/Scripts/Extensions/StringExtensions.cs index bd5e5cdfe..d181c7d40 100644 --- a/UniGLTF/Core/Scripts/Extensions/StringExtensions.cs +++ b/UniGLTF/Scripts/Extensions/StringExtensions.cs @@ -1,73 +1,73 @@ -using System.IO; -using UnityEngine; - -namespace UniGLTF -{ - public static class StringExtensions - { - public static string ToLowerCamelCase(this string lower) - { - return lower.Substring(0, 1).ToLower() + lower.Substring(1); - } - public static string ToUpperCamelCase(this string lower) - { - return lower.Substring(0, 1).ToUpper() + lower.Substring(1); - } - - static string m_unityBasePath; - public static string UnityBasePath - { - get - { - if (m_unityBasePath == null) - { - m_unityBasePath = Path.GetFullPath(Application.dataPath + "/..").Replace("\\", "/"); - } - return m_unityBasePath; - } - } - - public static string AssetPathToFullPath(this string path) - { - return UnityBasePath + "/" + path; - } - - public static bool StartsWithUnityAssetPath(this string path) - { - return path.Replace("\\", "/").StartsWith(UnityBasePath + "/Assets"); - } - - public static string ToUnityRelativePath(this string path) - { - path = path.Replace("\\", "/"); - if (path.StartsWith(UnityBasePath)) - { - return path.Substring(UnityBasePath.Length + 1); - } - - //Debug.LogWarningFormat("{0} is starts with {1}", path, basePath); - return path; - } - - static readonly char[] EscapeChars = new char[] - { - '\\', - '/', - ':', - '*', - '?', - '"', - '<', - '>', - '|', - }; - public static string EscapeFilePath(this string path) - { - foreach(var x in EscapeChars) - { - path = path.Replace(x, '+'); - } - return path; - } - } -} +using System.IO; +using UnityEngine; + +namespace UniGLTF +{ + public static class StringExtensions + { + public static string ToLowerCamelCase(this string lower) + { + return lower.Substring(0, 1).ToLower() + lower.Substring(1); + } + public static string ToUpperCamelCase(this string lower) + { + return lower.Substring(0, 1).ToUpper() + lower.Substring(1); + } + + static string m_unityBasePath; + public static string UnityBasePath + { + get + { + if (m_unityBasePath == null) + { + m_unityBasePath = Path.GetFullPath(Application.dataPath + "/..").Replace("\\", "/"); + } + return m_unityBasePath; + } + } + + public static string AssetPathToFullPath(this string path) + { + return UnityBasePath + "/" + path; + } + + public static bool StartsWithUnityAssetPath(this string path) + { + return path.Replace("\\", "/").StartsWith(UnityBasePath + "/Assets"); + } + + public static string ToUnityRelativePath(this string path) + { + path = path.Replace("\\", "/"); + if (path.StartsWith(UnityBasePath)) + { + return path.Substring(UnityBasePath.Length + 1); + } + + //Debug.LogWarningFormat("{0} is starts with {1}", path, basePath); + return path; + } + + static readonly char[] EscapeChars = new char[] + { + '\\', + '/', + ':', + '*', + '?', + '"', + '<', + '>', + '|', + }; + public static string EscapeFilePath(this string path) + { + foreach(var x in EscapeChars) + { + path = path.Replace(x, '+'); + } + return path; + } + } +} diff --git a/UniGLTF/Core/Scripts/Extensions/StringExtensions.cs.meta b/UniGLTF/Scripts/Extensions/StringExtensions.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Extensions/StringExtensions.cs.meta rename to UniGLTF/Scripts/Extensions/StringExtensions.cs.meta diff --git a/UniGLTF/Core/Scripts/Extensions/UnityExtensions.cs b/UniGLTF/Scripts/Extensions/UnityExtensions.cs similarity index 96% rename from UniGLTF/Core/Scripts/Extensions/UnityExtensions.cs rename to UniGLTF/Scripts/Extensions/UnityExtensions.cs index 49784a7f2..c3e2f5883 100644 --- a/UniGLTF/Core/Scripts/Extensions/UnityExtensions.cs +++ b/UniGLTF/Scripts/Extensions/UnityExtensions.cs @@ -1,313 +1,313 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public struct PosRot - { - public Vector3 Position; - public Quaternion Rotation; - - public static PosRot FromGlobalTransform(Transform t) - { - return new PosRot - { - Position = t.position, - Rotation = t.rotation, - }; - } - } - - public class BlendShape - { - public string Name; - - public BlendShape(string name) - { - Name = name; - } - - public List Positions = new List(); - public List Normals = new List(); - public List Tangents = new List(); - } - - public static class UnityExtensions - { - public static Vector4 ReverseZ(this Vector4 v) - { - return new Vector4(v.x, v.y, -v.z, v.w); - } - - public static Vector3 ReverseZ(this Vector3 v) - { - return new Vector3(v.x, v.y, -v.z); - } - - [Obsolete] - public static Vector2 ReverseY(this Vector2 v) - { - return new Vector2(v.x, -v.y); - } - - public static Vector2 ReverseUV(this Vector2 v) - { - return new Vector2(v.x, 1.0f - v.y); - } - - public static Quaternion ReverseZ(this Quaternion q) - { - float angle; - Vector3 axis; - q.ToAngleAxis(out angle, out axis); - return Quaternion.AngleAxis(-angle, ReverseZ(axis)); - } - - public static Matrix4x4 Matrix4x4FromColumns(Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3) - { -#if UNITY_2017_1_OR_NEWER - return new Matrix4x4(c0, c1, c2, c3); -#else - var m = default(Matrix4x4); - m.SetColumn(0, c0); - m.SetColumn(1, c1); - m.SetColumn(2, c2); - m.SetColumn(3, c3); - return m; -#endif - } - - public static Matrix4x4 Matrix4x4FromRotation(Quaternion q) - { -#if UNITY_2017_1_OR_NEWER - return Matrix4x4.Rotate(q); -#else - var m = default(Matrix4x4); - m.SetTRS(Vector3.zero, q, Vector3.one); - return m; -#endif - } - - public static Matrix4x4 ReverseZ(this Matrix4x4 m) - { - m.SetTRS(m.ExtractPosition().ReverseZ(), m.ExtractRotation().ReverseZ(), m.ExtractScale()); - return m; - } - - public static Matrix4x4 MatrixFromArray(float[] values) - { - var m = new Matrix4x4(); - m.m00 = values[0]; - m.m10 = values[1]; - m.m20 = values[2]; - m.m30 = values[3]; - m.m01 = values[4]; - m.m11 = values[5]; - m.m21 = values[6]; - m.m31 = values[7]; - m.m02 = values[8]; - m.m12 = values[9]; - m.m22 = values[10]; - m.m32 = values[11]; - m.m03 = values[12]; - m.m13 = values[13]; - m.m23 = values[14]; - m.m33 = values[15]; - return m; - } - - // https://forum.unity.com/threads/how-to-assign-matrix4x4-to-transform.121966/ - public static Quaternion ExtractRotation(this Matrix4x4 matrix) - { - Vector3 forward; - forward.x = matrix.m02; - forward.y = matrix.m12; - forward.z = matrix.m22; - - Vector3 upwards; - upwards.x = matrix.m01; - upwards.y = matrix.m11; - upwards.z = matrix.m21; - - return Quaternion.LookRotation(forward, upwards); - } - - public static Vector3 ExtractPosition(this Matrix4x4 matrix) - { - Vector3 position; - position.x = matrix.m03; - position.y = matrix.m13; - position.z = matrix.m23; - return position; - } - - public static Vector3 ExtractScale(this Matrix4x4 matrix) - { - Vector3 scale; - scale.x = new Vector4(matrix.m00, matrix.m10, matrix.m20, matrix.m30).magnitude; - scale.y = new Vector4(matrix.m01, matrix.m11, matrix.m21, matrix.m31).magnitude; - scale.z = new Vector4(matrix.m02, matrix.m12, matrix.m22, matrix.m32).magnitude; - return scale; - } - - public static string RelativePathFrom(this Transform self, Transform root) - { - var path = new List(); - for (var current = self; current != null; current = current.parent) - { - if (current == root) - { - return String.Join("/", path.ToArray()); - } - - path.Insert(0, current.name); - } - - throw new Exception("no RelativePath"); - } - - public static Transform GetChildByName(this Transform self, string childName) - { - foreach (Transform child in self) - { - if (child.name == childName) - { - return child; - } - } - - throw new KeyNotFoundException(); - } - - public static Transform GetFromPath(this Transform self, string path) - { - var current = self; - - var splited = path.Split('/'); - - foreach (var childName in splited) - { - current = current.GetChildByName(childName); - } - - return current; - } - - public static IEnumerable GetChildren(this Transform self) - { - foreach (Transform child in self) - { - yield return child; - } - } - - public static IEnumerable Traverse(this Transform t) - { - yield return t; - foreach (Transform x in t) - { - foreach (Transform y in x.Traverse()) - { - yield return y; - } - } - } - - public static Transform FindDescenedant(this Transform t, string name) - { - return t.Traverse().First(x => x.name == name); - } - - public static IEnumerable Ancestors(this Transform t) - { - yield return t; - if (t.parent != null) - { - foreach (Transform x in t.parent.Ancestors()) - { - yield return x; - } - } - } - - public static float[] ToArray(this Quaternion q) - { - return new float[] { q.x, q.y, q.z, q.w }; - } - - public static float[] ToArray(this Vector3 v) - { - return new float[] { v.x, v.y, v.z }; - } - - public static float[] ToArray(this Vector4 v) - { - return new float[] { v.x, v.y, v.z, v.w }; - } - - public static float[] ToArray(this Color c) - { - return new float[] { c.r, c.g, c.b, c.a }; - } - - public static void ReverseZRecursive(this Transform root) - { - var globalMap = root.Traverse().ToDictionary(x => x, x => PosRot.FromGlobalTransform(x)); - - foreach (var x in root.Traverse()) - { - x.position = globalMap[x].Position.ReverseZ(); - x.rotation = globalMap[x].Rotation.ReverseZ(); - } - } - - public static Mesh GetSharedMesh(this Transform t) - { - var meshFilter = t.GetComponent(); - if (meshFilter != null) - { - return meshFilter.sharedMesh; - } - - var skinnedMeshRenderer = t.GetComponent(); - if (skinnedMeshRenderer != null) - { - return skinnedMeshRenderer.sharedMesh; - } - - return null; - } - - public static Material[] GetSharedMaterials(this Transform t) - { - var renderer = t.GetComponent(); - if (renderer != null) - { - return renderer.sharedMaterials; - } - - return new Material[] { }; - } - - public static bool Has(this Transform transform, T t) where T : Component - { - return transform.GetComponent() == t; - } - - public static T GetOrAddComponent(this GameObject go) where T : Component - { - var c = go.GetComponent(); - if (c != null) - { - return c; - } - return go.AddComponent(); - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + public struct PosRot + { + public Vector3 Position; + public Quaternion Rotation; + + public static PosRot FromGlobalTransform(Transform t) + { + return new PosRot + { + Position = t.position, + Rotation = t.rotation, + }; + } + } + + public class BlendShape + { + public string Name; + + public BlendShape(string name) + { + Name = name; + } + + public List Positions = new List(); + public List Normals = new List(); + public List Tangents = new List(); + } + + public static class UnityExtensions + { + public static Vector4 ReverseZ(this Vector4 v) + { + return new Vector4(v.x, v.y, -v.z, v.w); + } + + public static Vector3 ReverseZ(this Vector3 v) + { + return new Vector3(v.x, v.y, -v.z); + } + + [Obsolete] + public static Vector2 ReverseY(this Vector2 v) + { + return new Vector2(v.x, -v.y); + } + + public static Vector2 ReverseUV(this Vector2 v) + { + return new Vector2(v.x, 1.0f - v.y); + } + + public static Quaternion ReverseZ(this Quaternion q) + { + float angle; + Vector3 axis; + q.ToAngleAxis(out angle, out axis); + return Quaternion.AngleAxis(-angle, ReverseZ(axis)); + } + + public static Matrix4x4 Matrix4x4FromColumns(Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3) + { +#if UNITY_2017_1_OR_NEWER + return new Matrix4x4(c0, c1, c2, c3); +#else + var m = default(Matrix4x4); + m.SetColumn(0, c0); + m.SetColumn(1, c1); + m.SetColumn(2, c2); + m.SetColumn(3, c3); + return m; +#endif + } + + public static Matrix4x4 Matrix4x4FromRotation(Quaternion q) + { +#if UNITY_2017_1_OR_NEWER + return Matrix4x4.Rotate(q); +#else + var m = default(Matrix4x4); + m.SetTRS(Vector3.zero, q, Vector3.one); + return m; +#endif + } + + public static Matrix4x4 ReverseZ(this Matrix4x4 m) + { + m.SetTRS(m.ExtractPosition().ReverseZ(), m.ExtractRotation().ReverseZ(), m.ExtractScale()); + return m; + } + + public static Matrix4x4 MatrixFromArray(float[] values) + { + var m = new Matrix4x4(); + m.m00 = values[0]; + m.m10 = values[1]; + m.m20 = values[2]; + m.m30 = values[3]; + m.m01 = values[4]; + m.m11 = values[5]; + m.m21 = values[6]; + m.m31 = values[7]; + m.m02 = values[8]; + m.m12 = values[9]; + m.m22 = values[10]; + m.m32 = values[11]; + m.m03 = values[12]; + m.m13 = values[13]; + m.m23 = values[14]; + m.m33 = values[15]; + return m; + } + + // https://forum.unity.com/threads/how-to-assign-matrix4x4-to-transform.121966/ + public static Quaternion ExtractRotation(this Matrix4x4 matrix) + { + Vector3 forward; + forward.x = matrix.m02; + forward.y = matrix.m12; + forward.z = matrix.m22; + + Vector3 upwards; + upwards.x = matrix.m01; + upwards.y = matrix.m11; + upwards.z = matrix.m21; + + return Quaternion.LookRotation(forward, upwards); + } + + public static Vector3 ExtractPosition(this Matrix4x4 matrix) + { + Vector3 position; + position.x = matrix.m03; + position.y = matrix.m13; + position.z = matrix.m23; + return position; + } + + public static Vector3 ExtractScale(this Matrix4x4 matrix) + { + Vector3 scale; + scale.x = new Vector4(matrix.m00, matrix.m10, matrix.m20, matrix.m30).magnitude; + scale.y = new Vector4(matrix.m01, matrix.m11, matrix.m21, matrix.m31).magnitude; + scale.z = new Vector4(matrix.m02, matrix.m12, matrix.m22, matrix.m32).magnitude; + return scale; + } + + public static string RelativePathFrom(this Transform self, Transform root) + { + var path = new List(); + for (var current = self; current != null; current = current.parent) + { + if (current == root) + { + return String.Join("/", path.ToArray()); + } + + path.Insert(0, current.name); + } + + throw new Exception("no RelativePath"); + } + + public static Transform GetChildByName(this Transform self, string childName) + { + foreach (Transform child in self) + { + if (child.name == childName) + { + return child; + } + } + + throw new KeyNotFoundException(); + } + + public static Transform GetFromPath(this Transform self, string path) + { + var current = self; + + var splited = path.Split('/'); + + foreach (var childName in splited) + { + current = current.GetChildByName(childName); + } + + return current; + } + + public static IEnumerable GetChildren(this Transform self) + { + foreach (Transform child in self) + { + yield return child; + } + } + + public static IEnumerable Traverse(this Transform t) + { + yield return t; + foreach (Transform x in t) + { + foreach (Transform y in x.Traverse()) + { + yield return y; + } + } + } + + public static Transform FindDescenedant(this Transform t, string name) + { + return t.Traverse().First(x => x.name == name); + } + + public static IEnumerable Ancestors(this Transform t) + { + yield return t; + if (t.parent != null) + { + foreach (Transform x in t.parent.Ancestors()) + { + yield return x; + } + } + } + + public static float[] ToArray(this Quaternion q) + { + return new float[] { q.x, q.y, q.z, q.w }; + } + + public static float[] ToArray(this Vector3 v) + { + return new float[] { v.x, v.y, v.z }; + } + + public static float[] ToArray(this Vector4 v) + { + return new float[] { v.x, v.y, v.z, v.w }; + } + + public static float[] ToArray(this Color c) + { + return new float[] { c.r, c.g, c.b, c.a }; + } + + public static void ReverseZRecursive(this Transform root) + { + var globalMap = root.Traverse().ToDictionary(x => x, x => PosRot.FromGlobalTransform(x)); + + foreach (var x in root.Traverse()) + { + x.position = globalMap[x].Position.ReverseZ(); + x.rotation = globalMap[x].Rotation.ReverseZ(); + } + } + + public static Mesh GetSharedMesh(this Transform t) + { + var meshFilter = t.GetComponent(); + if (meshFilter != null) + { + return meshFilter.sharedMesh; + } + + var skinnedMeshRenderer = t.GetComponent(); + if (skinnedMeshRenderer != null) + { + return skinnedMeshRenderer.sharedMesh; + } + + return null; + } + + public static Material[] GetSharedMaterials(this Transform t) + { + var renderer = t.GetComponent(); + if (renderer != null) + { + return renderer.sharedMaterials; + } + + return new Material[] { }; + } + + public static bool Has(this Transform transform, T t) where T : Component + { + return transform.GetComponent() == t; + } + + public static T GetOrAddComponent(this GameObject go) where T : Component + { + var c = go.GetComponent(); + if (c != null) + { + return c; + } + return go.AddComponent(); + } + } +} diff --git a/UniGLTF/Core/Scripts/Extensions/UnityExtensions.cs.meta b/UniGLTF/Scripts/Extensions/UnityExtensions.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Extensions/UnityExtensions.cs.meta rename to UniGLTF/Scripts/Extensions/UnityExtensions.cs.meta diff --git a/UniGLTF/Core/Scripts/Extensions/glTFExtensions.cs b/UniGLTF/Scripts/Extensions/glTFExtensions.cs similarity index 97% rename from UniGLTF/Core/Scripts/Extensions/glTFExtensions.cs rename to UniGLTF/Scripts/Extensions/glTFExtensions.cs index 91c697c84..ffe895ace 100644 --- a/UniGLTF/Core/Scripts/Extensions/glTFExtensions.cs +++ b/UniGLTF/Scripts/Extensions/glTFExtensions.cs @@ -1,203 +1,203 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using UnityEngine; - - -namespace UniGLTF -{ - [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)] - struct UShort4 - { - public ushort x; - public ushort y; - public ushort z; - public ushort w; - - public UShort4(ushort _x, ushort _y, ushort _z, ushort _w) - { - x = _x; - y = _y; - z = _z; - w = _w; - } - } - - public static class glTFExtensions - { - struct ComponentVec - { - public glComponentType ComponentType; - public int ElementCount; - - public ComponentVec(glComponentType componentType, int elementCount) - { - ComponentType = componentType; - ElementCount = elementCount; - } - } - - static Dictionary ComponentTypeMap = new Dictionary - { - { typeof(Vector2), new ComponentVec(glComponentType.FLOAT, 2) }, - { typeof(Vector3), new ComponentVec(glComponentType.FLOAT, 3) }, - { typeof(Vector4), new ComponentVec(glComponentType.FLOAT, 4) }, - { typeof(UShort4), new ComponentVec(glComponentType.UNSIGNED_SHORT, 4) }, - { typeof(Matrix4x4), new ComponentVec(glComponentType.FLOAT, 16) }, - { typeof(Color), new ComponentVec(glComponentType.FLOAT, 4) }, - }; - - static glComponentType GetComponentType() - { - var cv = default(ComponentVec); - if (ComponentTypeMap.TryGetValue(typeof(T), out cv)) - { - return cv.ComponentType; - } - else if (typeof(T) == typeof(uint)) - { - return glComponentType.UNSIGNED_INT; - } - else if (typeof(T) == typeof(float)) - { - return glComponentType.FLOAT; - } - else - { - throw new NotImplementedException(typeof(T).Name); - } - } - - static string GetAccessorType() - { - var cv = default(ComponentVec); - if (ComponentTypeMap.TryGetValue(typeof(T), out cv)) - { - switch (cv.ElementCount) - { - case 2: return "VEC2"; - case 3: return "VEC3"; - case 4: return "VEC4"; - case 16: return "MAT4"; - default: throw new Exception(); - } - } - else - { - return "SCALAR"; - } - } - - static int GetAccessorElementCount() - { - var cv = default(ComponentVec); - if (ComponentTypeMap.TryGetValue(typeof(T), out cv)) - { - return cv.ElementCount; - } - else - { - return 1; - } - } - - public static int ExtendBufferAndGetAccessorIndex(this glTF gltf, int bufferIndex, T[] array, - glBufferTarget target = glBufferTarget.NONE) where T : struct - { - return gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, new ArraySegment(array), target); - } - - public static int ExtendBufferAndGetAccessorIndex(this glTF gltf, int bufferIndex, - ArraySegment array, - glBufferTarget target = glBufferTarget.NONE) where T : struct - { - if (array.Count == 0) - { - return -1; - } - var viewIndex = ExtendBufferAndGetViewIndex(gltf, bufferIndex, array, target); - - // index buffer's byteStride is unnecessary - gltf.bufferViews[viewIndex].byteStride = 0; - - var accessorIndex = gltf.accessors.Count; - gltf.accessors.Add(new glTFAccessor - { - bufferView = viewIndex, - byteOffset = 0, - componentType = GetComponentType(), - type = GetAccessorType(), - count = array.Count, - }); - return accessorIndex; - } - - public static int ExtendBufferAndGetViewIndex(this glTF gltf, int bufferIndex, - T[] array, - glBufferTarget target = glBufferTarget.NONE) where T : struct - { - return ExtendBufferAndGetViewIndex(gltf, bufferIndex, new ArraySegment(array), target); - } - - public static int ExtendBufferAndGetViewIndex(this glTF gltf, int bufferIndex, - ArraySegment array, - glBufferTarget target = glBufferTarget.NONE) where T : struct - { - if (array.Count == 0) - { - return -1; - } - var view = gltf.buffers[bufferIndex].Append(array, target); - var viewIndex = gltf.bufferViews.Count; - gltf.bufferViews.Add(view); - return viewIndex; - } - - public static int ExtendSparseBufferAndGetAccessorIndex(this glTF gltf, int bufferIndex, - int accessorCount, - T[] sparseValues, int[] sparseIndices, int sparseViewIndex, - glBufferTarget target = glBufferTarget.NONE) where T : struct - { - return ExtendSparseBufferAndGetAccessorIndex(gltf, bufferIndex, - accessorCount, - new ArraySegment(sparseValues), sparseIndices, sparseViewIndex, - target); - } - - public static int ExtendSparseBufferAndGetAccessorIndex(this glTF gltf, int bufferIndex, - int accessorCount, - ArraySegment sparseValues, int[] sparseIndices, int sparseIndicesViewIndex, - glBufferTarget target = glBufferTarget.NONE) where T : struct - { - if (sparseValues.Count == 0) - { - return -1; - } - var sparseValuesViewIndex = ExtendBufferAndGetViewIndex(gltf, bufferIndex, sparseValues, target); - var accessorIndex = gltf.accessors.Count; - gltf.accessors.Add(new glTFAccessor - { - byteOffset = 0, - componentType = GetComponentType(), - type = GetAccessorType(), - count = accessorCount, - - sparse = new glTFSparse - { - count=sparseIndices.Length, - indices = new glTFSparseIndices - { - bufferView = sparseIndicesViewIndex, - componentType = glComponentType.UNSIGNED_INT - }, - values = new glTFSparseValues - { - bufferView = sparseValuesViewIndex, - } - } - }); - return accessorIndex; - } - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using UnityEngine; + + +namespace UniGLTF +{ + [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)] + struct UShort4 + { + public ushort x; + public ushort y; + public ushort z; + public ushort w; + + public UShort4(ushort _x, ushort _y, ushort _z, ushort _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + } + + public static class glTFExtensions + { + struct ComponentVec + { + public glComponentType ComponentType; + public int ElementCount; + + public ComponentVec(glComponentType componentType, int elementCount) + { + ComponentType = componentType; + ElementCount = elementCount; + } + } + + static Dictionary ComponentTypeMap = new Dictionary + { + { typeof(Vector2), new ComponentVec(glComponentType.FLOAT, 2) }, + { typeof(Vector3), new ComponentVec(glComponentType.FLOAT, 3) }, + { typeof(Vector4), new ComponentVec(glComponentType.FLOAT, 4) }, + { typeof(UShort4), new ComponentVec(glComponentType.UNSIGNED_SHORT, 4) }, + { typeof(Matrix4x4), new ComponentVec(glComponentType.FLOAT, 16) }, + { typeof(Color), new ComponentVec(glComponentType.FLOAT, 4) }, + }; + + static glComponentType GetComponentType() + { + var cv = default(ComponentVec); + if (ComponentTypeMap.TryGetValue(typeof(T), out cv)) + { + return cv.ComponentType; + } + else if (typeof(T) == typeof(uint)) + { + return glComponentType.UNSIGNED_INT; + } + else if (typeof(T) == typeof(float)) + { + return glComponentType.FLOAT; + } + else + { + throw new NotImplementedException(typeof(T).Name); + } + } + + static string GetAccessorType() + { + var cv = default(ComponentVec); + if (ComponentTypeMap.TryGetValue(typeof(T), out cv)) + { + switch (cv.ElementCount) + { + case 2: return "VEC2"; + case 3: return "VEC3"; + case 4: return "VEC4"; + case 16: return "MAT4"; + default: throw new Exception(); + } + } + else + { + return "SCALAR"; + } + } + + static int GetAccessorElementCount() + { + var cv = default(ComponentVec); + if (ComponentTypeMap.TryGetValue(typeof(T), out cv)) + { + return cv.ElementCount; + } + else + { + return 1; + } + } + + public static int ExtendBufferAndGetAccessorIndex(this glTF gltf, int bufferIndex, T[] array, + glBufferTarget target = glBufferTarget.NONE) where T : struct + { + return gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, new ArraySegment(array), target); + } + + public static int ExtendBufferAndGetAccessorIndex(this glTF gltf, int bufferIndex, + ArraySegment array, + glBufferTarget target = glBufferTarget.NONE) where T : struct + { + if (array.Count == 0) + { + return -1; + } + var viewIndex = ExtendBufferAndGetViewIndex(gltf, bufferIndex, array, target); + + // index buffer's byteStride is unnecessary + gltf.bufferViews[viewIndex].byteStride = 0; + + var accessorIndex = gltf.accessors.Count; + gltf.accessors.Add(new glTFAccessor + { + bufferView = viewIndex, + byteOffset = 0, + componentType = GetComponentType(), + type = GetAccessorType(), + count = array.Count, + }); + return accessorIndex; + } + + public static int ExtendBufferAndGetViewIndex(this glTF gltf, int bufferIndex, + T[] array, + glBufferTarget target = glBufferTarget.NONE) where T : struct + { + return ExtendBufferAndGetViewIndex(gltf, bufferIndex, new ArraySegment(array), target); + } + + public static int ExtendBufferAndGetViewIndex(this glTF gltf, int bufferIndex, + ArraySegment array, + glBufferTarget target = glBufferTarget.NONE) where T : struct + { + if (array.Count == 0) + { + return -1; + } + var view = gltf.buffers[bufferIndex].Append(array, target); + var viewIndex = gltf.bufferViews.Count; + gltf.bufferViews.Add(view); + return viewIndex; + } + + public static int ExtendSparseBufferAndGetAccessorIndex(this glTF gltf, int bufferIndex, + int accessorCount, + T[] sparseValues, int[] sparseIndices, int sparseViewIndex, + glBufferTarget target = glBufferTarget.NONE) where T : struct + { + return ExtendSparseBufferAndGetAccessorIndex(gltf, bufferIndex, + accessorCount, + new ArraySegment(sparseValues), sparseIndices, sparseViewIndex, + target); + } + + public static int ExtendSparseBufferAndGetAccessorIndex(this glTF gltf, int bufferIndex, + int accessorCount, + ArraySegment sparseValues, int[] sparseIndices, int sparseIndicesViewIndex, + glBufferTarget target = glBufferTarget.NONE) where T : struct + { + if (sparseValues.Count == 0) + { + return -1; + } + var sparseValuesViewIndex = ExtendBufferAndGetViewIndex(gltf, bufferIndex, sparseValues, target); + var accessorIndex = gltf.accessors.Count; + gltf.accessors.Add(new glTFAccessor + { + byteOffset = 0, + componentType = GetComponentType(), + type = GetAccessorType(), + count = accessorCount, + + sparse = new glTFSparse + { + count=sparseIndices.Length, + indices = new glTFSparseIndices + { + bufferView = sparseIndicesViewIndex, + componentType = glComponentType.UNSIGNED_INT + }, + values = new glTFSparseValues + { + bufferView = sparseValuesViewIndex, + } + } + }); + return accessorIndex; + } + } +} diff --git a/UniGLTF/Core/Scripts/Extensions/glTFExtensions.cs.meta b/UniGLTF/Scripts/Extensions/glTFExtensions.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Extensions/glTFExtensions.cs.meta rename to UniGLTF/Scripts/Extensions/glTFExtensions.cs.meta diff --git a/UniGLTF/Core/Scripts/Format.meta b/UniGLTF/Scripts/Format.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format.meta rename to UniGLTF/Scripts/Format.meta diff --git a/UniGLTF/Core/Scripts/Format/BytesBuffer.cs b/UniGLTF/Scripts/Format/BytesBuffer.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/BytesBuffer.cs rename to UniGLTF/Scripts/Format/BytesBuffer.cs index 38a27ec3a..1c50307a7 100644 --- a/UniGLTF/Core/Scripts/Format/BytesBuffer.cs +++ b/UniGLTF/Scripts/Format/BytesBuffer.cs @@ -1,187 +1,187 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; - - -namespace UniGLTF -{ - public interface IBytesBuffer - { - string Uri { get; } - ArraySegment GetBytes(); - glTFBufferView Extend(ArraySegment array, glBufferTarget target) where T : struct; - } - - public static class IBytesBufferExtensions - { - public static glTFBufferView Extend(this IBytesBuffer buffer, T[] array, glBufferTarget target) where T : struct - { - return buffer.Extend(new ArraySegment(array), target); - } - } - - /// - /// for buffer with uri read - /// - public class UriByteBuffer : IBytesBuffer - { - public string Uri - { - get; - private set; - } - - Byte[] m_bytes; - public ArraySegment GetBytes() - { - return new ArraySegment(m_bytes); - } - - public UriByteBuffer(string baseDir, string uri) - { - Uri = uri; - m_bytes = ReadFromUri(baseDir, uri); - } - - const string DataPrefix = "data:application/octet-stream;base64,"; - - const string DataPrefix2 = "data:application/gltf-buffer;base64,"; - - const string DataPrefix3 = "data:image/jpeg;base64,"; - - public static Byte[] ReadEmbeded(string uri) - { - var pos = uri.IndexOf(";base64,"); - if (pos < 0) - { - throw new NotImplementedException(); - } - else - { - return Convert.FromBase64String(uri.Substring(pos + 8)); - } - } - - Byte[] ReadFromUri(string baseDir, string uri) - { - var bytes = ReadEmbeded(uri); - if (bytes != null) - { - return bytes; - } - else - { - // as local file path - return File.ReadAllBytes(Path.Combine(baseDir, uri)); - } - } - - public glTFBufferView Extend(ArraySegment array, glBufferTarget target) where T : struct - { - throw new NotImplementedException(); - } - } - - /// - /// for glb chunk buffer read - /// - public class ArraySegmentByteBuffer : IBytesBuffer - { - ArraySegment m_bytes; - - public ArraySegmentByteBuffer(ArraySegment bytes) - { - m_bytes = bytes; - } - - public string Uri - { - get; - private set; - } - - public glTFBufferView Extend(ArraySegment array, glBufferTarget target) where T : struct - { - throw new NotImplementedException(); - } - - public ArraySegment GetBytes() - { - return m_bytes; - } - } - - /// - /// for exporter - /// - public class ArrayByteBuffer : IBytesBuffer - { - public string Uri - { - get; - private set; - } - - Byte[] m_bytes; - int m_used; - - public ArrayByteBuffer(Byte[] bytes = null) - { - Uri = ""; - m_bytes = bytes; - } - - public glTFBufferView Extend(ArraySegment array, glBufferTarget target) where T : struct - { - using (var pin = Pin.Create(array)) - { - var elementSize = Marshal.SizeOf(typeof(T)); - var view = Extend(pin.Ptr, array.Count * elementSize, elementSize, target); - return view; - } - } - - 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; - - if (m_bytes == null || m_used + padding + bytesLength > m_bytes.Length) - { - // recreate buffer - m_bytes = new Byte[m_used + padding + bytesLength]; - if (m_used > 0) - { - Buffer.BlockCopy(tmp, 0, m_bytes, 0, m_used); - } - } - if (m_used + padding + bytesLength > m_bytes.Length) - { - throw new ArgumentOutOfRangeException(); - } - - Marshal.Copy(p, m_bytes, m_used + padding, bytesLength); - var result=new glTFBufferView - { - buffer = 0, - byteLength = bytesLength, - byteOffset = m_used + padding, - byteStride = stride, - target = target, - }; - m_used = m_used + padding + bytesLength; - return result; - } - - public ArraySegment GetBytes() - { - if (m_bytes == null) - { - return new ArraySegment(); - } - - return new ArraySegment(m_bytes, 0, m_used); - } - } -} +using System; +using System.IO; +using System.Runtime.InteropServices; + + +namespace UniGLTF +{ + public interface IBytesBuffer + { + string Uri { get; } + ArraySegment GetBytes(); + glTFBufferView Extend(ArraySegment array, glBufferTarget target) where T : struct; + } + + public static class IBytesBufferExtensions + { + public static glTFBufferView Extend(this IBytesBuffer buffer, T[] array, glBufferTarget target) where T : struct + { + return buffer.Extend(new ArraySegment(array), target); + } + } + + /// + /// for buffer with uri read + /// + public class UriByteBuffer : IBytesBuffer + { + public string Uri + { + get; + private set; + } + + Byte[] m_bytes; + public ArraySegment GetBytes() + { + return new ArraySegment(m_bytes); + } + + public UriByteBuffer(string baseDir, string uri) + { + Uri = uri; + m_bytes = ReadFromUri(baseDir, uri); + } + + const string DataPrefix = "data:application/octet-stream;base64,"; + + const string DataPrefix2 = "data:application/gltf-buffer;base64,"; + + const string DataPrefix3 = "data:image/jpeg;base64,"; + + public static Byte[] ReadEmbeded(string uri) + { + var pos = uri.IndexOf(";base64,"); + if (pos < 0) + { + throw new NotImplementedException(); + } + else + { + return Convert.FromBase64String(uri.Substring(pos + 8)); + } + } + + Byte[] ReadFromUri(string baseDir, string uri) + { + var bytes = ReadEmbeded(uri); + if (bytes != null) + { + return bytes; + } + else + { + // as local file path + return File.ReadAllBytes(Path.Combine(baseDir, uri)); + } + } + + public glTFBufferView Extend(ArraySegment array, glBufferTarget target) where T : struct + { + throw new NotImplementedException(); + } + } + + /// + /// for glb chunk buffer read + /// + public class ArraySegmentByteBuffer : IBytesBuffer + { + ArraySegment m_bytes; + + public ArraySegmentByteBuffer(ArraySegment bytes) + { + m_bytes = bytes; + } + + public string Uri + { + get; + private set; + } + + public glTFBufferView Extend(ArraySegment array, glBufferTarget target) where T : struct + { + throw new NotImplementedException(); + } + + public ArraySegment GetBytes() + { + return m_bytes; + } + } + + /// + /// for exporter + /// + public class ArrayByteBuffer : IBytesBuffer + { + public string Uri + { + get; + private set; + } + + Byte[] m_bytes; + int m_used; + + public ArrayByteBuffer(Byte[] bytes = null) + { + Uri = ""; + m_bytes = bytes; + } + + public glTFBufferView Extend(ArraySegment array, glBufferTarget target) where T : struct + { + using (var pin = Pin.Create(array)) + { + var elementSize = Marshal.SizeOf(typeof(T)); + var view = Extend(pin.Ptr, array.Count * elementSize, elementSize, target); + return view; + } + } + + 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; + + if (m_bytes == null || m_used + padding + bytesLength > m_bytes.Length) + { + // recreate buffer + m_bytes = new Byte[m_used + padding + bytesLength]; + if (m_used > 0) + { + Buffer.BlockCopy(tmp, 0, m_bytes, 0, m_used); + } + } + if (m_used + padding + bytesLength > m_bytes.Length) + { + throw new ArgumentOutOfRangeException(); + } + + Marshal.Copy(p, m_bytes, m_used + padding, bytesLength); + var result=new glTFBufferView + { + buffer = 0, + byteLength = bytesLength, + byteOffset = m_used + padding, + byteStride = stride, + target = target, + }; + m_used = m_used + padding + bytesLength; + return result; + } + + public ArraySegment GetBytes() + { + if (m_bytes == null) + { + return new ArraySegment(); + } + + return new ArraySegment(m_bytes, 0, m_used); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/BytesBuffer.cs.meta b/UniGLTF/Scripts/Format/BytesBuffer.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/BytesBuffer.cs.meta rename to UniGLTF/Scripts/Format/BytesBuffer.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras.meta b/UniGLTF/Scripts/Format/ExtensionsAndExtras.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras.meta rename to UniGLTF/Scripts/Format/ExtensionsAndExtras.meta diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs b/UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs index 11111e27b..4f846a782 100644 --- a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs +++ b/UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs @@ -1,32 +1,32 @@ -using System; -using UniJSON; - - -namespace UniGLTF -{ - [Serializable] - public class glTF_KHR_draco_mesh_compression : JsonSerializableBase - { - [JsonSchema(Required = true, Minimum = 0)] - public int bufferView = -1; - public glTFAttributes attributes; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - //throw new NotImplementedException(); - } - } - - [Serializable] - public partial class glTFPrimitives_extensions : ExtensionsBase - { - [JsonSchema(Required = true)] - public glTF_KHR_draco_mesh_compression KHR_draco_mesh_compression; - - [JsonSerializeMembers] - void SerializeMembers_draco(GLTFJsonFormatter f) - { - //throw new NotImplementedException(); - } - } -} +using System; +using UniJSON; + + +namespace UniGLTF +{ + [Serializable] + public class glTF_KHR_draco_mesh_compression : JsonSerializableBase + { + [JsonSchema(Required = true, Minimum = 0)] + public int bufferView = -1; + public glTFAttributes attributes; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + //throw new NotImplementedException(); + } + } + + [Serializable] + public partial class glTFPrimitives_extensions : ExtensionsBase + { + [JsonSchema(Required = true)] + public glTF_KHR_draco_mesh_compression KHR_draco_mesh_compression; + + [JsonSerializeMembers] + void SerializeMembers_draco(GLTFJsonFormatter f) + { + //throw new NotImplementedException(); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs.meta b/UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs.meta rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_draco_mesh_compression.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs b/UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs index 6797c4c26..a24d2207d 100644 --- a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs +++ b/UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs @@ -1,55 +1,55 @@ -using System; -using UniJSON; - -namespace UniGLTF -{ - [Serializable] - public class glTF_KHR_materials_unlit : JsonSerializableBase - { - public static string ExtensionName - { - get - { - return "KHR_materials_unlit"; - } - } - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - //throw new System.NotImplementedException(); - } - - public static glTFMaterial CreateDefault() - { - return new glTFMaterial - { - pbrMetallicRoughness = new glTFPbrMetallicRoughness - { - baseColorFactor = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }, - roughnessFactor = 0.9f, - metallicFactor = 0.0f, - }, - extensions = new glTFMaterial_extensions - { - KHR_materials_unlit = new glTF_KHR_materials_unlit(), - }, - }; - } - } - - [Serializable] - public partial class glTFMaterial_extensions : ExtensionsBase - { - [JsonSchema(Required = true)] - public glTF_KHR_materials_unlit KHR_materials_unlit; - - [JsonSerializeMembers] - void SerializeMembers_unlit(GLTFJsonFormatter f) - { - if (KHR_materials_unlit != null) - { - f.KeyValue(() => KHR_materials_unlit); - } - } - } -} +using System; +using UniJSON; + +namespace UniGLTF +{ + [Serializable] + public class glTF_KHR_materials_unlit : JsonSerializableBase + { + public static string ExtensionName + { + get + { + return "KHR_materials_unlit"; + } + } + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + //throw new System.NotImplementedException(); + } + + public static glTFMaterial CreateDefault() + { + return new glTFMaterial + { + pbrMetallicRoughness = new glTFPbrMetallicRoughness + { + baseColorFactor = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }, + roughnessFactor = 0.9f, + metallicFactor = 0.0f, + }, + extensions = new glTFMaterial_extensions + { + KHR_materials_unlit = new glTF_KHR_materials_unlit(), + }, + }; + } + } + + [Serializable] + public partial class glTFMaterial_extensions : ExtensionsBase + { + [JsonSchema(Required = true)] + public glTF_KHR_materials_unlit KHR_materials_unlit; + + [JsonSerializeMembers] + void SerializeMembers_unlit(GLTFJsonFormatter f) + { + if (KHR_materials_unlit != null) + { + f.KeyValue(() => KHR_materials_unlit); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs.meta b/UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs.meta rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/KHR_materials_unlit.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs similarity index 97% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs index 4f5d0e18c..f7bae3667 100644 --- a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs +++ b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs @@ -1,27 +1,27 @@ -using System; -using UniJSON; - - -namespace UniGLTF -{ - [Serializable] - [ItemJsonSchema(ValueType = ValueNodeType.Object)] - public partial class glTFOrthographic_extensions : ExtensionsBase { } - - [Serializable] - public partial class glTFOrthographic_extras : ExtraBase { } - - [Serializable] - [ItemJsonSchema(ValueType = ValueNodeType.Object)] - public partial class glTFPerspective_extensions : ExtensionsBase { } - - [Serializable] - public partial class glTFPerspective_extras : ExtraBase { } - - [Serializable] - [ItemJsonSchema(ValueType = ValueNodeType.Object)] - public partial class glTFCamera_extensions : ExtensionsBase { } - - [Serializable] - public partial class glTFCamera_extras : ExtraBase { } -} +using System; +using UniJSON; + + +namespace UniGLTF +{ + [Serializable] + [ItemJsonSchema(ValueType = ValueNodeType.Object)] + public partial class glTFOrthographic_extensions : ExtensionsBase { } + + [Serializable] + public partial class glTFOrthographic_extras : ExtraBase { } + + [Serializable] + [ItemJsonSchema(ValueType = ValueNodeType.Object)] + public partial class glTFPerspective_extensions : ExtensionsBase { } + + [Serializable] + public partial class glTFPerspective_extras : ExtraBase { } + + [Serializable] + [ItemJsonSchema(ValueType = ValueNodeType.Object)] + public partial class glTFCamera_extensions : ExtensionsBase { } + + [Serializable] + public partial class glTFCamera_extras : ExtraBase { } +} diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs.meta b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs.meta rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFCameraExtensions.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs index 0c192865b..fefe47fea 100644 --- a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs +++ b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs @@ -1,54 +1,54 @@ -using System; -using System.Linq; -using System.Reflection; -using UniJSON; - - -namespace UniGLTF -{ - #region Base - public class JsonSerializeMembersAttribute : Attribute { } - - public class PartialExtensionBase : JsonSerializableBase - { - protected override void SerializeMembers(GLTFJsonFormatter f) - { - foreach (var method in this.GetType().GetMethods(BindingFlags.Instance | - BindingFlags.Public | BindingFlags.NonPublic)) - { - if (method.GetCustomAttributes(typeof(JsonSerializeMembersAttribute), true).Any()) - { - method.Invoke(this, new[] { f }); - } - } - } - - public int __count - { - get - { - return typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .Where(x => x.GetCustomAttributes(typeof(JsonSerializeMembersAttribute), true).Any()) - .Count(); - } - } - } - - [ItemJsonSchema(ValueType = ValueNodeType.Object)] - [JsonSchema(MinProperties = 1)] - public partial class ExtensionsBase : PartialExtensionBase - { - } - - [JsonSchema(MinProperties = 1)] - public partial class ExtraBase : PartialExtensionBase - { - } - #endregion - - [Serializable] - public partial class glTF_extensions : ExtensionsBase { } - - [Serializable] - public partial class gltf_extras : ExtraBase { } -} +using System; +using System.Linq; +using System.Reflection; +using UniJSON; + + +namespace UniGLTF +{ + #region Base + public class JsonSerializeMembersAttribute : Attribute { } + + public class PartialExtensionBase : JsonSerializableBase + { + protected override void SerializeMembers(GLTFJsonFormatter f) + { + foreach (var method in this.GetType().GetMethods(BindingFlags.Instance | + BindingFlags.Public | BindingFlags.NonPublic)) + { + if (method.GetCustomAttributes(typeof(JsonSerializeMembersAttribute), true).Any()) + { + method.Invoke(this, new[] { f }); + } + } + } + + public int __count + { + get + { + return typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .Where(x => x.GetCustomAttributes(typeof(JsonSerializeMembersAttribute), true).Any()) + .Count(); + } + } + } + + [ItemJsonSchema(ValueType = ValueNodeType.Object)] + [JsonSchema(MinProperties = 1)] + public partial class ExtensionsBase : PartialExtensionBase + { + } + + [JsonSchema(MinProperties = 1)] + public partial class ExtraBase : PartialExtensionBase + { + } + #endregion + + [Serializable] + public partial class glTF_extensions : ExtensionsBase { } + + [Serializable] + public partial class gltf_extras : ExtraBase { } +} diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs.meta b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs.meta rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFExtensions.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs index f9bfb7952..bbfc18965 100644 --- a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs +++ b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs @@ -1,32 +1,32 @@ -using System; -using System.Collections.Generic; -using UniJSON; - - -namespace UniGLTF -{ - /// - /// https://github.com/KhronosGroup/glTF/issues/1036 - /// - [Serializable] - public partial class glTFPrimitives_extras : ExtraBase - { - [JsonSchema(Required = true, MinItems = 1)] - public List targetNames = new List(); - - [JsonSerializeMembers] - void PrimitiveMembers(GLTFJsonFormatter f) - { - if (targetNames.Count > 0) - { - f.Key("targetNames"); - f.BeginList(); - foreach (var x in targetNames) - { - f.Value(x); - } - f.EndList(); - } - } - } -} +using System; +using System.Collections.Generic; +using UniJSON; + + +namespace UniGLTF +{ + /// + /// https://github.com/KhronosGroup/glTF/issues/1036 + /// + [Serializable] + public partial class glTFPrimitives_extras : ExtraBase + { + [JsonSchema(Required = true, MinItems = 1)] + public List targetNames = new List(); + + [JsonSerializeMembers] + void PrimitiveMembers(GLTFJsonFormatter f) + { + if (targetNames.Count > 0) + { + f.Key("targetNames"); + f.BeginList(); + foreach (var x in targetNames) + { + f.Value(x); + } + f.EndList(); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs.meta b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs.meta rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFMesh.Primitives.extras.targetNames.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFNode.cs b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFNode.cs similarity index 95% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFNode.cs rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFNode.cs index f41ec3847..0c0b9825e 100644 --- a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFNode.cs +++ b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFNode.cs @@ -1,11 +1,11 @@ -using System; - - -namespace UniGLTF -{ - [Serializable] - public partial class glTFNode_extensions : ExtensionsBase { } - - [Serializable] - public partial class glTFNode_extra : ExtraBase { } -} +using System; + + +namespace UniGLTF +{ + [Serializable] + public partial class glTFNode_extensions : ExtensionsBase { } + + [Serializable] + public partial class glTFNode_extra : ExtraBase { } +} diff --git a/UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFNode.cs.meta b/UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFNode.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/ExtensionsAndExtras/glTFNode.cs.meta rename to UniGLTF/Scripts/Format/ExtensionsAndExtras/glTFNode.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/GLTFJsonFormatter.cs b/UniGLTF/Scripts/Format/GLTFJsonFormatter.cs similarity index 95% rename from UniGLTF/Core/Scripts/Format/GLTFJsonFormatter.cs rename to UniGLTF/Scripts/Format/GLTFJsonFormatter.cs index f171e85cb..7a6b1b061 100644 --- a/UniGLTF/Core/Scripts/Format/GLTFJsonFormatter.cs +++ b/UniGLTF/Scripts/Format/GLTFJsonFormatter.cs @@ -1,35 +1,35 @@ -using System.Collections.Generic; -using UniJSON; - - -namespace UniGLTF -{ - public class GLTFJsonFormatter: UniJSON.JsonFormatter - { - public void GLTFValue(JsonSerializableBase s) - { - CommaCheck(); - Store.Write(s.ToJson()); - } - - public void GLTFValue(IEnumerable values) where T : JsonSerializableBase - { - BeginList(); - foreach (var value in values) - { - GLTFValue(value); - } - EndList(); - } - - public void GLTFValue(List values) - { - BeginList(); - foreach (var value in values) - { - this.Value(value); - } - EndList(); - } - } -} +using System.Collections.Generic; +using UniJSON; + + +namespace UniGLTF +{ + public class GLTFJsonFormatter: UniJSON.JsonFormatter + { + public void GLTFValue(JsonSerializableBase s) + { + CommaCheck(); + Store.Write(s.ToJson()); + } + + public void GLTFValue(IEnumerable values) where T : JsonSerializableBase + { + BeginList(); + foreach (var value in values) + { + GLTFValue(value); + } + EndList(); + } + + public void GLTFValue(List values) + { + BeginList(); + foreach (var value in values) + { + this.Value(value); + } + EndList(); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/GLTFJsonFormatter.cs.meta b/UniGLTF/Scripts/Format/GLTFJsonFormatter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/GLTFJsonFormatter.cs.meta rename to UniGLTF/Scripts/Format/GLTFJsonFormatter.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/JsonSerializableBase.cs b/UniGLTF/Scripts/Format/JsonSerializableBase.cs similarity index 94% rename from UniGLTF/Core/Scripts/Format/JsonSerializableBase.cs rename to UniGLTF/Scripts/Format/JsonSerializableBase.cs index de1eee467..3d302b1da 100644 --- a/UniGLTF/Core/Scripts/Format/JsonSerializableBase.cs +++ b/UniGLTF/Scripts/Format/JsonSerializableBase.cs @@ -1,22 +1,22 @@ -using System; - - -namespace UniGLTF -{ - [Serializable] - public abstract class JsonSerializableBase - { - protected abstract void SerializeMembers(GLTFJsonFormatter f); - - public string ToJson() - { - var f = new GLTFJsonFormatter(); - f.BeginMap(); - - SerializeMembers(f); - - f.EndMap(); - return f.ToString(); - } - } -} +using System; + + +namespace UniGLTF +{ + [Serializable] + public abstract class JsonSerializableBase + { + protected abstract void SerializeMembers(GLTFJsonFormatter f); + + public string ToJson() + { + var f = new GLTFJsonFormatter(); + f.BeginMap(); + + SerializeMembers(f); + + f.EndMap(); + return f.ToString(); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/JsonSerializableBase.cs.meta b/UniGLTF/Scripts/Format/JsonSerializableBase.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/JsonSerializableBase.cs.meta rename to UniGLTF/Scripts/Format/JsonSerializableBase.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/MonoBehaviourComparator.cs b/UniGLTF/Scripts/Format/MonoBehaviourComparator.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/MonoBehaviourComparator.cs rename to UniGLTF/Scripts/Format/MonoBehaviourComparator.cs index dceccdb9f..ad50a70b5 100644 --- a/UniGLTF/Core/Scripts/Format/MonoBehaviourComparator.cs +++ b/UniGLTF/Scripts/Format/MonoBehaviourComparator.cs @@ -1,68 +1,68 @@ -using System; -using UnityEngine; - - -namespace UniGLTF -{ - public static class MonoBehaviourComparator - { - public static bool AssertAreEquals(GameObject l, GameObject r) - { - return - l.name == r.name - && AssertAreEquals(l, r, - (x, y) => AssertAreEquals(x[0], y[0])) - && AssertAreEquals(l, r, - (x, y) => AssertAreEquals(x[0], y[0])) - && AssertAreEquals(l, r, - (x, y) => AssertAreEquals(x[0], y[0])) - && AssertAreEquals(l, r, - (x, y) => AssertAreEquals(x[0], y[0])) - ; - } - - public static bool AssertAreEquals(GameObject l, GameObject r, Func pred) where T : Component - { - var ll = l.GetComponents(); - var rr = r.GetComponents(); - if (ll.Length != rr.Length) - { - return false; - } - if (ll.Length == 0) - { - return true; - } - return pred(ll, rr); - } - - public static bool AssertAreEquals(Transform l, Transform r) - { - return - (l.localPosition == r.localPosition) - && (l.localRotation == r.localRotation) - && (l.localScale == r.localScale) - ; - } - - public static bool AssertAreEquals(MeshFilter l, MeshFilter r) - { - throw new NotImplementedException(); - } - - public static bool AssertAreEquals(MeshRenderer l, MeshRenderer r) - { - throw new NotImplementedException(); - } - - public static bool AssertAreEquals(SkinnedMeshRenderer l, SkinnedMeshRenderer r) - { - throw new NotImplementedException(); - } - - public static bool AssetAreEquals(Texture2D l, Texture2D r) - { - throw new NotImplementedException(); - } - } -} +using System; +using UnityEngine; + + +namespace UniGLTF +{ + public static class MonoBehaviourComparator + { + public static bool AssertAreEquals(GameObject l, GameObject r) + { + return + l.name == r.name + && AssertAreEquals(l, r, + (x, y) => AssertAreEquals(x[0], y[0])) + && AssertAreEquals(l, r, + (x, y) => AssertAreEquals(x[0], y[0])) + && AssertAreEquals(l, r, + (x, y) => AssertAreEquals(x[0], y[0])) + && AssertAreEquals(l, r, + (x, y) => AssertAreEquals(x[0], y[0])) + ; + } + + public static bool AssertAreEquals(GameObject l, GameObject r, Func pred) where T : Component + { + var ll = l.GetComponents(); + var rr = r.GetComponents(); + if (ll.Length != rr.Length) + { + return false; + } + if (ll.Length == 0) + { + return true; + } + return pred(ll, rr); + } + + public static bool AssertAreEquals(Transform l, Transform r) + { + return + (l.localPosition == r.localPosition) + && (l.localRotation == r.localRotation) + && (l.localScale == r.localScale) + ; + } + + public static bool AssertAreEquals(MeshFilter l, MeshFilter r) + { + throw new NotImplementedException(); + } + + public static bool AssertAreEquals(MeshRenderer l, MeshRenderer r) + { + throw new NotImplementedException(); + } + + public static bool AssertAreEquals(SkinnedMeshRenderer l, SkinnedMeshRenderer r) + { + throw new NotImplementedException(); + } + + public static bool AssetAreEquals(Texture2D l, Texture2D r) + { + throw new NotImplementedException(); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/MonoBehaviourComparator.cs.meta b/UniGLTF/Scripts/Format/MonoBehaviourComparator.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/MonoBehaviourComparator.cs.meta rename to UniGLTF/Scripts/Format/MonoBehaviourComparator.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glEnum.cs b/UniGLTF/Scripts/Format/glEnum.cs similarity index 95% rename from UniGLTF/Core/Scripts/Format/glEnum.cs rename to UniGLTF/Scripts/Format/glEnum.cs index f2ad5a884..1915c1d9d 100644 --- a/UniGLTF/Core/Scripts/Format/glEnum.cs +++ b/UniGLTF/Scripts/Format/glEnum.cs @@ -1,48 +1,48 @@ -/// -/// https://gist.github.com/szimek/763999 -/// -namespace UniGLTF -{ - public enum glComponentType : int - { - BYTE = 5120, // signed ? - UNSIGNED_BYTE = 5121, - - SHORT = 5122, - UNSIGNED_SHORT = 5123, - - //INT = 5124, - UNSIGNED_INT = 5125, - - FLOAT = 5126, - } - - public enum glBufferTarget : int - { - NONE = 0, - ARRAY_BUFFER = 34962, - ELEMENT_ARRAY_BUFFER = 34963, - } - - public enum glFilter : int - { - NONE = 0, - NEAREST = 9728, - LINEAR = 9729, - - #region for minFilter only - NEAREST_MIPMAP_NEAREST = 9984, - LINEAR_MIPMAP_NEAREST = 9985, - NEAREST_MIPMAP_LINEAR = 9986, - LINEAR_MIPMAP_LINEAR = 9987, - #endregion - } - - public enum glWrap : int - { - NONE = 0, - CLAMP_TO_EDGE = 33071, - REPEAT = 10497, - MIRRORED_REPEAT = 33648, - } -} +/// +/// https://gist.github.com/szimek/763999 +/// +namespace UniGLTF +{ + public enum glComponentType : int + { + BYTE = 5120, // signed ? + UNSIGNED_BYTE = 5121, + + SHORT = 5122, + UNSIGNED_SHORT = 5123, + + //INT = 5124, + UNSIGNED_INT = 5125, + + FLOAT = 5126, + } + + public enum glBufferTarget : int + { + NONE = 0, + ARRAY_BUFFER = 34962, + ELEMENT_ARRAY_BUFFER = 34963, + } + + public enum glFilter : int + { + NONE = 0, + NEAREST = 9728, + LINEAR = 9729, + + #region for minFilter only + NEAREST_MIPMAP_NEAREST = 9984, + LINEAR_MIPMAP_NEAREST = 9985, + NEAREST_MIPMAP_LINEAR = 9986, + LINEAR_MIPMAP_LINEAR = 9987, + #endregion + } + + public enum glWrap : int + { + NONE = 0, + CLAMP_TO_EDGE = 33071, + REPEAT = 10497, + MIRRORED_REPEAT = 33648, + } +} diff --git a/UniGLTF/Core/Scripts/Format/glEnum.cs.meta b/UniGLTF/Scripts/Format/glEnum.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glEnum.cs.meta rename to UniGLTF/Scripts/Format/glEnum.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTF.cs b/UniGLTF/Scripts/Format/glTF.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTF.cs rename to UniGLTF/Scripts/Format/glTF.cs index 9481cd5dc..d4a54b634 100644 --- a/UniGLTF/Core/Scripts/Format/glTF.cs +++ b/UniGLTF/Scripts/Format/glTF.cs @@ -1,518 +1,518 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UniJSON; - - -namespace UniGLTF -{ - [Serializable] - public class gltfScene : JsonSerializableBase - { - [JsonSchema(MinItems = 1)] - [ItemJsonSchema(Minimum = 0)] - public int[] nodes; - - public object extensions; - public object extras; - public string name; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => nodes); - } - } - - [Serializable] - public class glTF : JsonSerializableBase, IEquatable - { - [JsonSchema(Required = true)] - public glTFAssets asset = new glTFAssets(); - - #region Buffer - [JsonSchema(MinItems = 1)] - public List buffers = new List(); - public int AddBuffer(IBytesBuffer bytesBuffer) - { - var index = buffers.Count; - buffers.Add(new glTFBuffer(bytesBuffer)); - return index; - } - - [JsonSchema(MinItems = 1)] - public List bufferViews = new List(); - public int AddBufferView(glTFBufferView view) - { - var index = bufferViews.Count; - bufferViews.Add(view); - return index; - } - - [JsonSchema(MinItems = 1)] - public List accessors = new List(); - - T[] GetAttrib(glTFAccessor accessor, glTFBufferView view) where T : struct - { - return GetAttrib(accessor.count, accessor.byteOffset, view); - } - T[] GetAttrib(int count, int byteOffset, glTFBufferView view) where T : struct - { - var attrib = new T[count]; - // - var segment = buffers[view.buffer].GetBytes(); - var bytes = new ArraySegment(segment.Array, segment.Offset + view.byteOffset + byteOffset, count * view.byteStride); - bytes.MarshalCoyTo(attrib); - return attrib; - } - - public ArraySegment GetViewBytes(int bufferView) - { - var view = bufferViews[bufferView]; - var segment = buffers[view.buffer].GetBytes(); - return new ArraySegment(segment.Array, segment.Offset + view.byteOffset, view.byteLength); - } - - IEnumerable _GetIndices(glTFAccessor accessor, out int count) - { - count = accessor.count; - var view = bufferViews[accessor.bufferView]; - switch ((glComponentType)accessor.componentType) - { - case glComponentType.UNSIGNED_BYTE: - { - return GetAttrib(accessor, view).Select(x => (int)(x)); - } - - case glComponentType.UNSIGNED_SHORT: - { - return GetAttrib(accessor, view).Select(x => (int)(x)); - } - - case glComponentType.UNSIGNED_INT: - { - return GetAttrib(accessor, view).Select(x => (int)(x)); - } - } - throw new NotImplementedException("GetIndices: unknown componenttype: " + accessor.componentType); - } - - IEnumerable _GetIndices(glTFBufferView view, int count, int byteOffset, glComponentType componentType) - { - switch (componentType) - { - case glComponentType.UNSIGNED_BYTE: - { - return GetAttrib(count, byteOffset, view).Select(x => (int)(x)); - } - - case glComponentType.UNSIGNED_SHORT: - { - return GetAttrib(count, byteOffset, view).Select(x => (int)(x)); - } - - case glComponentType.UNSIGNED_INT: - { - return GetAttrib(count, byteOffset, view).Select(x => (int)(x)); - } - } - throw new NotImplementedException("GetIndices: unknown componenttype: " + componentType); - } - - public int[] GetIndices(int accessorIndex) - { - int count; - var result = _GetIndices(accessors[accessorIndex], out count); - var indices = new int[count]; - - // flip triangles - var it = result.GetEnumerator(); - { - for (int i = 0; i < count; i += 3) - { - it.MoveNext(); indices[i + 2] = it.Current; - it.MoveNext(); indices[i + 1] = it.Current; - it.MoveNext(); indices[i] = it.Current; - } - } - - return indices; - } - - public T[] GetArrayFromAccessor(int accessorIndex) where T : struct - { - var vertexAccessor = accessors[accessorIndex]; - - if (vertexAccessor.count <= 0) return new T[] { }; - - var result = (vertexAccessor.bufferView != -1) - ? GetAttrib(vertexAccessor, bufferViews[vertexAccessor.bufferView]) - : new T[vertexAccessor.count] - ; - - var sparse = vertexAccessor.sparse; - if (sparse != null && sparse.count > 0) - { - // override sparse values - var indices = _GetIndices(bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType); - var values = GetAttrib(sparse.count, sparse.values.byteOffset, bufferViews[sparse.values.bufferView]); - - var it = indices.GetEnumerator(); - for (int i = 0; i < sparse.count; ++i) - { - it.MoveNext(); - result[it.Current] = values[i]; - } - } - return result; - } - - public float[] GetArrayFromAccessorAsFloat(int accessorIndex) - { - var vertexAccessor = accessors[accessorIndex]; - - if (vertexAccessor.count <= 0) return new float[] { }; - - var bufferCount = vertexAccessor.count * vertexAccessor.TypeCount; - var result = (vertexAccessor.bufferView != -1) - ? GetAttrib(bufferCount, vertexAccessor.byteOffset, bufferViews[vertexAccessor.bufferView]) - : new float[bufferCount] - ; - - var sparse = vertexAccessor.sparse; - if (sparse != null && sparse.count > 0) - { - // override sparse values - var indices = _GetIndices(bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType); - var values = GetAttrib(sparse.count * vertexAccessor.TypeCount, sparse.values.byteOffset, bufferViews[sparse.values.bufferView]); - - var it = indices.GetEnumerator(); - for (int i = 0; i < sparse.count; ++i) - { - it.MoveNext(); - result[it.Current] = values[i]; - } - } - return result; - } - #endregion - - [JsonSchema(MinItems = 1)] - public List textures = new List(); - - [JsonSchema(MinItems = 1)] - public List samplers = new List(); - public glTFTextureSampler GetSampler(int index) - { - if (samplers.Count == 0) - { - samplers.Add(new glTFTextureSampler()); // default sampler - } - - return samplers[index]; - } - - [JsonSchema(MinItems = 1)] - public List images = new List(); - - public int GetImageIndexFromTextureIndex(int textureIndex) - { - return textures[textureIndex].source; - } - - public glTFImage GetImageFromTextureIndex(int textureIndex) - { - return images[GetImageIndexFromTextureIndex(textureIndex)]; - } - - public glTFTextureSampler GetSamplerFromTextureIndex(int textureIndex) - { - var samplerIndex = textures[textureIndex].sampler; - return GetSampler(samplerIndex); - } - - public ArraySegment GetImageBytes(IStorage storage, int imageIndex, out string textureName) - { - var image = images[imageIndex]; - if (string.IsNullOrEmpty(image.uri)) - { - // - // use buffer view (GLB) - // - //m_imageBytes = ToArray(byteSegment); - textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#GLB", imageIndex); - return GetViewBytes(image.bufferView); - } - else - { - if (image.uri.StartsWith("data:")) - { - textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#Base64Embeded", imageIndex); - } - else - { - textureName = !string.IsNullOrEmpty(image.name) ? image.name : Path.GetFileNameWithoutExtension(image.uri); - } - return storage.Get(image.uri); - } - } - - [JsonSchema(MinItems = 1)] - public List materials = new List(); - public string GetUniqueMaterialName(int index) - { - if (materials.Any(x => string.IsNullOrEmpty(x.name)) - || materials.Select(x => x.name).Distinct().Count() != materials.Count) - { - return String.Format("{0:00}_{1}", index, materials[index].name); - } - else - { - return materials[index].name; - } - } - - public bool MaterialHasVertexColor(glTFMaterial material) - { - if (material == null) - { - return false; - } - - var materialIndex = materials.IndexOf(material); - if (materialIndex == -1) - { - return false; - } - - return MaterialHasVertexColor(materialIndex); - } - - [JsonSchema(MinItems = 1)] - public List meshes = new List(); - - public bool MaterialHasVertexColor(int materialIndex) - { - if (materialIndex < 0 || materialIndex >= materials.Count) - { - return false; - } - - var hasVertexColor = meshes.SelectMany(x => x.primitives).Any(x => x.material == materialIndex && x.HasVertexColor); - return hasVertexColor; - } - - [JsonSchema(MinItems = 1)] - public List nodes = new List(); - - [JsonSchema(MinItems = 1)] - public List skins = new List(); - - [JsonSchema(Dependencies = new string[] { "scenes" }, Minimum = 0)] - public int scene; - - [JsonSchema(MinItems = 1)] - public List scenes = new List(); - public int[] rootnodes - { - get - { - return scenes[scene].nodes; - } - } - - [JsonSchema(MinItems = 1)] - public List animations = new List(); - - [JsonSchema(MinItems = 1)] - public List cameras = new List(); - - [JsonSchema(MinItems = 1)] - public List extensionsUsed = new List(); - - [JsonSchema(MinItems = 1)] - public List extensionsRequired = new List(); - - public glTF_extensions extensions = new glTF_extensions(); - public gltf_extras extras = new gltf_extras(); - - public override string ToString() - { - return string.Format("{0}", asset); - } - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - if (extensionsUsed.Count > 0) - { - f.KeyValue(() => extensionsUsed); - } - if (extensions.__count > 0) - { - f.KeyValue(() => extensions); - } - if (extras.__count > 0) - { - f.KeyValue(() => extras); - } - - f.KeyValue(() => asset); - - // buffer - if (buffers.Any()) - { - f.KeyValue(() => buffers); - } - if (bufferViews.Any()) - { - f.Key("bufferViews"); f.GLTFValue(bufferViews); - } - if (accessors.Any()) - { - f.Key("accessors"); f.GLTFValue(accessors); - } - - // materials - if (images.Any()) - { - f.Key("images"); f.GLTFValue(images); - if (samplers.Count == 0) - { - samplers.Add(new glTFTextureSampler()); - } - } - - if (samplers.Any()) - { - f.Key("samplers"); f.GLTFValue(samplers); - } - - if (textures.Any()) - { - f.Key("textures"); f.GLTFValue(textures); - } - if (materials.Any()) - { - f.Key("materials"); f.GLTFValue(materials); - } - - // meshes - if (meshes.Any()) - { - f.KeyValue(() => meshes); - } - if (skins.Any()) - { - f.KeyValue(() => skins); - } - - // scene - if (nodes.Any()) - { - f.KeyValue(() => nodes); - } - if (scenes.Any()) - { - f.KeyValue(() => scenes); - if (scene >= 0) - { - f.KeyValue(() => scene); - } - } - - // animations - if (animations.Any()) - { - f.Key("animations"); f.GLTFValue(animations); - } - } - - public bool Equals(glTF other) - { - return - textures.SequenceEqual(other.textures) - && samplers.SequenceEqual(other.samplers) - && images.SequenceEqual(other.images) - && materials.SequenceEqual(other.materials) - && meshes.SequenceEqual(other.meshes) - && nodes.SequenceEqual(other.nodes) - && skins.SequenceEqual(other.skins) - && scene == other.scene - && scenes.SequenceEqual(other.scenes) - && animations.SequenceEqual(other.animations) - ; - } - - bool UsedExtension(string key) - { - if (extensionsUsed.Contains(key)) - { - return true; - } - - return false; - } - - static Utf8String s_extensions = Utf8String.From("extensions"); - - void Traverse(ListTreeNode node, JsonFormatter f, Utf8String parentKey) - { - if(node.IsMap()) - { - f.BeginMap(); - foreach(var kv in node.ObjectItems()) - { - if (parentKey == s_extensions) - { - if (!UsedExtension(kv.Key.GetString())) - { - continue; - } - } - f.Key(kv.Key.GetUtf8String()); - Traverse(kv.Value, f, kv.Key.GetUtf8String()); - } - f.EndMap(); - } - else if(node.IsArray()) - { - f.BeginList(); - foreach(var x in node.ArrayItems()) - { - Traverse(x, f, default(Utf8String)); - } - f.EndList(); - } - else - { - f.Value(node); - } - } - - string RemoveUnusedExtensions(string json) - { - var f = new JsonFormatter(); - - Traverse(JsonParser.Parse(json), f, default(Utf8String)); - - return f.ToString(); - } - - public byte[] ToGlbBytes(bool UseUniJSONSerializer = false) - { - string json; - if (UseUniJSONSerializer) - { - json = JsonSchema.FromType(GetType()).Serialize(this); - } - else - { - json = ToJson(); - } - - RemoveUnusedExtensions(json); - - return Glb.ToBytes(json, buffers[0].GetBytes()); - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UniJSON; + + +namespace UniGLTF +{ + [Serializable] + public class gltfScene : JsonSerializableBase + { + [JsonSchema(MinItems = 1)] + [ItemJsonSchema(Minimum = 0)] + public int[] nodes; + + public object extensions; + public object extras; + public string name; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => nodes); + } + } + + [Serializable] + public class glTF : JsonSerializableBase, IEquatable + { + [JsonSchema(Required = true)] + public glTFAssets asset = new glTFAssets(); + + #region Buffer + [JsonSchema(MinItems = 1)] + public List buffers = new List(); + public int AddBuffer(IBytesBuffer bytesBuffer) + { + var index = buffers.Count; + buffers.Add(new glTFBuffer(bytesBuffer)); + return index; + } + + [JsonSchema(MinItems = 1)] + public List bufferViews = new List(); + public int AddBufferView(glTFBufferView view) + { + var index = bufferViews.Count; + bufferViews.Add(view); + return index; + } + + [JsonSchema(MinItems = 1)] + public List accessors = new List(); + + T[] GetAttrib(glTFAccessor accessor, glTFBufferView view) where T : struct + { + return GetAttrib(accessor.count, accessor.byteOffset, view); + } + T[] GetAttrib(int count, int byteOffset, glTFBufferView view) where T : struct + { + var attrib = new T[count]; + // + var segment = buffers[view.buffer].GetBytes(); + var bytes = new ArraySegment(segment.Array, segment.Offset + view.byteOffset + byteOffset, count * view.byteStride); + bytes.MarshalCoyTo(attrib); + return attrib; + } + + public ArraySegment GetViewBytes(int bufferView) + { + var view = bufferViews[bufferView]; + var segment = buffers[view.buffer].GetBytes(); + return new ArraySegment(segment.Array, segment.Offset + view.byteOffset, view.byteLength); + } + + IEnumerable _GetIndices(glTFAccessor accessor, out int count) + { + count = accessor.count; + var view = bufferViews[accessor.bufferView]; + switch ((glComponentType)accessor.componentType) + { + case glComponentType.UNSIGNED_BYTE: + { + return GetAttrib(accessor, view).Select(x => (int)(x)); + } + + case glComponentType.UNSIGNED_SHORT: + { + return GetAttrib(accessor, view).Select(x => (int)(x)); + } + + case glComponentType.UNSIGNED_INT: + { + return GetAttrib(accessor, view).Select(x => (int)(x)); + } + } + throw new NotImplementedException("GetIndices: unknown componenttype: " + accessor.componentType); + } + + IEnumerable _GetIndices(glTFBufferView view, int count, int byteOffset, glComponentType componentType) + { + switch (componentType) + { + case glComponentType.UNSIGNED_BYTE: + { + return GetAttrib(count, byteOffset, view).Select(x => (int)(x)); + } + + case glComponentType.UNSIGNED_SHORT: + { + return GetAttrib(count, byteOffset, view).Select(x => (int)(x)); + } + + case glComponentType.UNSIGNED_INT: + { + return GetAttrib(count, byteOffset, view).Select(x => (int)(x)); + } + } + throw new NotImplementedException("GetIndices: unknown componenttype: " + componentType); + } + + public int[] GetIndices(int accessorIndex) + { + int count; + var result = _GetIndices(accessors[accessorIndex], out count); + var indices = new int[count]; + + // flip triangles + var it = result.GetEnumerator(); + { + for (int i = 0; i < count; i += 3) + { + it.MoveNext(); indices[i + 2] = it.Current; + it.MoveNext(); indices[i + 1] = it.Current; + it.MoveNext(); indices[i] = it.Current; + } + } + + return indices; + } + + public T[] GetArrayFromAccessor(int accessorIndex) where T : struct + { + var vertexAccessor = accessors[accessorIndex]; + + if (vertexAccessor.count <= 0) return new T[] { }; + + var result = (vertexAccessor.bufferView != -1) + ? GetAttrib(vertexAccessor, bufferViews[vertexAccessor.bufferView]) + : new T[vertexAccessor.count] + ; + + var sparse = vertexAccessor.sparse; + if (sparse != null && sparse.count > 0) + { + // override sparse values + var indices = _GetIndices(bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType); + var values = GetAttrib(sparse.count, sparse.values.byteOffset, bufferViews[sparse.values.bufferView]); + + var it = indices.GetEnumerator(); + for (int i = 0; i < sparse.count; ++i) + { + it.MoveNext(); + result[it.Current] = values[i]; + } + } + return result; + } + + public float[] GetArrayFromAccessorAsFloat(int accessorIndex) + { + var vertexAccessor = accessors[accessorIndex]; + + if (vertexAccessor.count <= 0) return new float[] { }; + + var bufferCount = vertexAccessor.count * vertexAccessor.TypeCount; + var result = (vertexAccessor.bufferView != -1) + ? GetAttrib(bufferCount, vertexAccessor.byteOffset, bufferViews[vertexAccessor.bufferView]) + : new float[bufferCount] + ; + + var sparse = vertexAccessor.sparse; + if (sparse != null && sparse.count > 0) + { + // override sparse values + var indices = _GetIndices(bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType); + var values = GetAttrib(sparse.count * vertexAccessor.TypeCount, sparse.values.byteOffset, bufferViews[sparse.values.bufferView]); + + var it = indices.GetEnumerator(); + for (int i = 0; i < sparse.count; ++i) + { + it.MoveNext(); + result[it.Current] = values[i]; + } + } + return result; + } + #endregion + + [JsonSchema(MinItems = 1)] + public List textures = new List(); + + [JsonSchema(MinItems = 1)] + public List samplers = new List(); + public glTFTextureSampler GetSampler(int index) + { + if (samplers.Count == 0) + { + samplers.Add(new glTFTextureSampler()); // default sampler + } + + return samplers[index]; + } + + [JsonSchema(MinItems = 1)] + public List images = new List(); + + public int GetImageIndexFromTextureIndex(int textureIndex) + { + return textures[textureIndex].source; + } + + public glTFImage GetImageFromTextureIndex(int textureIndex) + { + return images[GetImageIndexFromTextureIndex(textureIndex)]; + } + + public glTFTextureSampler GetSamplerFromTextureIndex(int textureIndex) + { + var samplerIndex = textures[textureIndex].sampler; + return GetSampler(samplerIndex); + } + + public ArraySegment GetImageBytes(IStorage storage, int imageIndex, out string textureName) + { + var image = images[imageIndex]; + if (string.IsNullOrEmpty(image.uri)) + { + // + // use buffer view (GLB) + // + //m_imageBytes = ToArray(byteSegment); + textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#GLB", imageIndex); + return GetViewBytes(image.bufferView); + } + else + { + if (image.uri.StartsWith("data:")) + { + textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#Base64Embeded", imageIndex); + } + else + { + textureName = !string.IsNullOrEmpty(image.name) ? image.name : Path.GetFileNameWithoutExtension(image.uri); + } + return storage.Get(image.uri); + } + } + + [JsonSchema(MinItems = 1)] + public List materials = new List(); + public string GetUniqueMaterialName(int index) + { + if (materials.Any(x => string.IsNullOrEmpty(x.name)) + || materials.Select(x => x.name).Distinct().Count() != materials.Count) + { + return String.Format("{0:00}_{1}", index, materials[index].name); + } + else + { + return materials[index].name; + } + } + + public bool MaterialHasVertexColor(glTFMaterial material) + { + if (material == null) + { + return false; + } + + var materialIndex = materials.IndexOf(material); + if (materialIndex == -1) + { + return false; + } + + return MaterialHasVertexColor(materialIndex); + } + + [JsonSchema(MinItems = 1)] + public List meshes = new List(); + + public bool MaterialHasVertexColor(int materialIndex) + { + if (materialIndex < 0 || materialIndex >= materials.Count) + { + return false; + } + + var hasVertexColor = meshes.SelectMany(x => x.primitives).Any(x => x.material == materialIndex && x.HasVertexColor); + return hasVertexColor; + } + + [JsonSchema(MinItems = 1)] + public List nodes = new List(); + + [JsonSchema(MinItems = 1)] + public List skins = new List(); + + [JsonSchema(Dependencies = new string[] { "scenes" }, Minimum = 0)] + public int scene; + + [JsonSchema(MinItems = 1)] + public List scenes = new List(); + public int[] rootnodes + { + get + { + return scenes[scene].nodes; + } + } + + [JsonSchema(MinItems = 1)] + public List animations = new List(); + + [JsonSchema(MinItems = 1)] + public List cameras = new List(); + + [JsonSchema(MinItems = 1)] + public List extensionsUsed = new List(); + + [JsonSchema(MinItems = 1)] + public List extensionsRequired = new List(); + + public glTF_extensions extensions = new glTF_extensions(); + public gltf_extras extras = new gltf_extras(); + + public override string ToString() + { + return string.Format("{0}", asset); + } + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + if (extensionsUsed.Count > 0) + { + f.KeyValue(() => extensionsUsed); + } + if (extensions.__count > 0) + { + f.KeyValue(() => extensions); + } + if (extras.__count > 0) + { + f.KeyValue(() => extras); + } + + f.KeyValue(() => asset); + + // buffer + if (buffers.Any()) + { + f.KeyValue(() => buffers); + } + if (bufferViews.Any()) + { + f.Key("bufferViews"); f.GLTFValue(bufferViews); + } + if (accessors.Any()) + { + f.Key("accessors"); f.GLTFValue(accessors); + } + + // materials + if (images.Any()) + { + f.Key("images"); f.GLTFValue(images); + if (samplers.Count == 0) + { + samplers.Add(new glTFTextureSampler()); + } + } + + if (samplers.Any()) + { + f.Key("samplers"); f.GLTFValue(samplers); + } + + if (textures.Any()) + { + f.Key("textures"); f.GLTFValue(textures); + } + if (materials.Any()) + { + f.Key("materials"); f.GLTFValue(materials); + } + + // meshes + if (meshes.Any()) + { + f.KeyValue(() => meshes); + } + if (skins.Any()) + { + f.KeyValue(() => skins); + } + + // scene + if (nodes.Any()) + { + f.KeyValue(() => nodes); + } + if (scenes.Any()) + { + f.KeyValue(() => scenes); + if (scene >= 0) + { + f.KeyValue(() => scene); + } + } + + // animations + if (animations.Any()) + { + f.Key("animations"); f.GLTFValue(animations); + } + } + + public bool Equals(glTF other) + { + return + textures.SequenceEqual(other.textures) + && samplers.SequenceEqual(other.samplers) + && images.SequenceEqual(other.images) + && materials.SequenceEqual(other.materials) + && meshes.SequenceEqual(other.meshes) + && nodes.SequenceEqual(other.nodes) + && skins.SequenceEqual(other.skins) + && scene == other.scene + && scenes.SequenceEqual(other.scenes) + && animations.SequenceEqual(other.animations) + ; + } + + bool UsedExtension(string key) + { + if (extensionsUsed.Contains(key)) + { + return true; + } + + return false; + } + + static Utf8String s_extensions = Utf8String.From("extensions"); + + void Traverse(ListTreeNode node, JsonFormatter f, Utf8String parentKey) + { + if(node.IsMap()) + { + f.BeginMap(); + foreach(var kv in node.ObjectItems()) + { + if (parentKey == s_extensions) + { + if (!UsedExtension(kv.Key.GetString())) + { + continue; + } + } + f.Key(kv.Key.GetUtf8String()); + Traverse(kv.Value, f, kv.Key.GetUtf8String()); + } + f.EndMap(); + } + else if(node.IsArray()) + { + f.BeginList(); + foreach(var x in node.ArrayItems()) + { + Traverse(x, f, default(Utf8String)); + } + f.EndList(); + } + else + { + f.Value(node); + } + } + + string RemoveUnusedExtensions(string json) + { + var f = new JsonFormatter(); + + Traverse(JsonParser.Parse(json), f, default(Utf8String)); + + return f.ToString(); + } + + public byte[] ToGlbBytes(bool UseUniJSONSerializer = false) + { + string json; + if (UseUniJSONSerializer) + { + json = JsonSchema.FromType(GetType()).Serialize(this); + } + else + { + json = ToJson(); + } + + RemoveUnusedExtensions(json); + + return Glb.ToBytes(json, buffers[0].GetBytes()); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTF.cs.meta b/UniGLTF/Scripts/Format/glTF.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTF.cs.meta rename to UniGLTF/Scripts/Format/glTF.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFAnimation.cs b/UniGLTF/Scripts/Format/glTFAnimation.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTFAnimation.cs rename to UniGLTF/Scripts/Format/glTFAnimation.cs index 04de4b8a8..3bf6020ec 100644 --- a/UniGLTF/Core/Scripts/Format/glTFAnimation.cs +++ b/UniGLTF/Scripts/Format/glTFAnimation.cs @@ -1,210 +1,210 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UniJSON; - - -namespace UniGLTF -{ - [Serializable] - public class glTFAnimationTarget : JsonSerializableBase - { - [JsonSchema(Minimum = 0)] - public int node; - - [JsonSchema(Required = true, EnumValues = new object[] { "translation", "rotation", "scale", "weights" }, EnumSerializationType = EnumSerializationType.AsString)] - public string path; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => node); - if (!string.IsNullOrEmpty(path)) - { - f.KeyValue(() => path); - } - } - - public enum Interpolations - { - LINEAR, - STEP, - CUBICSPLINE - } - - public const string PATH_TRANSLATION = "translation"; - public const string PATH_EULER_ROTATION = "rotation"; - public const string PATH_ROTATION = "rotation"; - public const string PATH_SCALE = "scale"; - public const string PATH_WEIGHT = "weights"; - public const string NOT_IMPLEMENTED = "NotImplemented"; - - public enum AnimationPropertys - { - Translation, - EulerRotation, - Rotation, - Scale, - Weight, - BlendShape, - - NotImplemented - } - - public static string GetPathName(AnimationPropertys property) - { - switch (property) - { - case AnimationPropertys.Translation: - return PATH_TRANSLATION; - case AnimationPropertys.EulerRotation: - case AnimationPropertys.Rotation: - return PATH_ROTATION; - case AnimationPropertys.Scale: - return PATH_SCALE; - case AnimationPropertys.BlendShape: - return PATH_WEIGHT; - default: throw new NotImplementedException(); - } - } - - public static AnimationPropertys GetAnimationProperty(string path) - { - switch (path) - { - case PATH_TRANSLATION: - return AnimationPropertys.Translation; - case PATH_ROTATION: - return AnimationPropertys.Rotation; - case PATH_SCALE: - return AnimationPropertys.Scale; - case PATH_WEIGHT: - return AnimationPropertys.BlendShape; - default: throw new NotImplementedException(); - } - } - - public static int GetElementCount(AnimationPropertys property) - { - switch (property) - { - case AnimationPropertys.Translation: return 3; - case AnimationPropertys.EulerRotation: return 3; - case AnimationPropertys.Rotation: return 4; - case AnimationPropertys.Scale: return 3; - case AnimationPropertys.BlendShape: return 1; - default: throw new NotImplementedException(); - } - } - - public static int GetElementCount(string path) - { - return GetElementCount(GetAnimationProperty(path)); - } - } - - [Serializable] - public class glTFAnimationChannel : JsonSerializableBase - { - [JsonSchema(Required = true, Minimum = 0)] - public int sampler = -1; - - [JsonSchema(Required = true)] - public glTFAnimationTarget target; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => sampler); - f.KeyValue(() => target); - } - } - - [Serializable] - public class glTFAnimationSampler : JsonSerializableBase - { - [JsonSchema(Required = true, Minimum = 0)] - public int input = -1; - - [JsonSchema(EnumValues = new object[] { "LINEAR", "STEP", "CUBICSPLINE" }, EnumSerializationType = EnumSerializationType.AsString)] - public string interpolation; - - [JsonSchema(Required = true, Minimum = 0)] - public int output = -1; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => input); - if (!string.IsNullOrEmpty(interpolation)) - { - f.KeyValue(() => interpolation); - } - f.KeyValue(() => output); - } - } - - [Serializable] - public class glTFAnimation : JsonSerializableBase - { - public string name = ""; - - [JsonSchema(Required = true, MinItems = 1)] - public List channels = new List(); - - [JsonSchema(Required = true, MinItems = 1)] - public List samplers = new List(); - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - if (!string.IsNullOrEmpty(name)) - { - f.KeyValue(() => name); - } - - f.KeyValue(() => channels); - f.KeyValue(() => samplers); - } - - public int AddChannelAndGetSampler(int nodeIndex, glTFAnimationTarget.AnimationPropertys property) - { - // find channel - var channel = channels.FirstOrDefault(x => x.target.node == nodeIndex && x.target.path == glTFAnimationTarget.GetPathName(property)); - if (channel != null) - { - return channel.sampler; - } - - // not found. create new - var samplerIndex = samplers.Count; - var sampler = new glTFAnimationSampler(); - samplers.Add(sampler); - - channel = new glTFAnimationChannel - { - sampler = samplerIndex, - target = new glTFAnimationTarget - { - node = nodeIndex, - path = glTFAnimationTarget.GetPathName(property), - }, - }; - channels.Add(channel); - - return samplerIndex; - } - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using UniJSON; + + +namespace UniGLTF +{ + [Serializable] + public class glTFAnimationTarget : JsonSerializableBase + { + [JsonSchema(Minimum = 0)] + public int node; + + [JsonSchema(Required = true, EnumValues = new object[] { "translation", "rotation", "scale", "weights" }, EnumSerializationType = EnumSerializationType.AsString)] + public string path; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => node); + if (!string.IsNullOrEmpty(path)) + { + f.KeyValue(() => path); + } + } + + public enum Interpolations + { + LINEAR, + STEP, + CUBICSPLINE + } + + public const string PATH_TRANSLATION = "translation"; + public const string PATH_EULER_ROTATION = "rotation"; + public const string PATH_ROTATION = "rotation"; + public const string PATH_SCALE = "scale"; + public const string PATH_WEIGHT = "weights"; + public const string NOT_IMPLEMENTED = "NotImplemented"; + + public enum AnimationPropertys + { + Translation, + EulerRotation, + Rotation, + Scale, + Weight, + BlendShape, + + NotImplemented + } + + public static string GetPathName(AnimationPropertys property) + { + switch (property) + { + case AnimationPropertys.Translation: + return PATH_TRANSLATION; + case AnimationPropertys.EulerRotation: + case AnimationPropertys.Rotation: + return PATH_ROTATION; + case AnimationPropertys.Scale: + return PATH_SCALE; + case AnimationPropertys.BlendShape: + return PATH_WEIGHT; + default: throw new NotImplementedException(); + } + } + + public static AnimationPropertys GetAnimationProperty(string path) + { + switch (path) + { + case PATH_TRANSLATION: + return AnimationPropertys.Translation; + case PATH_ROTATION: + return AnimationPropertys.Rotation; + case PATH_SCALE: + return AnimationPropertys.Scale; + case PATH_WEIGHT: + return AnimationPropertys.BlendShape; + default: throw new NotImplementedException(); + } + } + + public static int GetElementCount(AnimationPropertys property) + { + switch (property) + { + case AnimationPropertys.Translation: return 3; + case AnimationPropertys.EulerRotation: return 3; + case AnimationPropertys.Rotation: return 4; + case AnimationPropertys.Scale: return 3; + case AnimationPropertys.BlendShape: return 1; + default: throw new NotImplementedException(); + } + } + + public static int GetElementCount(string path) + { + return GetElementCount(GetAnimationProperty(path)); + } + } + + [Serializable] + public class glTFAnimationChannel : JsonSerializableBase + { + [JsonSchema(Required = true, Minimum = 0)] + public int sampler = -1; + + [JsonSchema(Required = true)] + public glTFAnimationTarget target; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => sampler); + f.KeyValue(() => target); + } + } + + [Serializable] + public class glTFAnimationSampler : JsonSerializableBase + { + [JsonSchema(Required = true, Minimum = 0)] + public int input = -1; + + [JsonSchema(EnumValues = new object[] { "LINEAR", "STEP", "CUBICSPLINE" }, EnumSerializationType = EnumSerializationType.AsString)] + public string interpolation; + + [JsonSchema(Required = true, Minimum = 0)] + public int output = -1; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => input); + if (!string.IsNullOrEmpty(interpolation)) + { + f.KeyValue(() => interpolation); + } + f.KeyValue(() => output); + } + } + + [Serializable] + public class glTFAnimation : JsonSerializableBase + { + public string name = ""; + + [JsonSchema(Required = true, MinItems = 1)] + public List channels = new List(); + + [JsonSchema(Required = true, MinItems = 1)] + public List samplers = new List(); + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + if (!string.IsNullOrEmpty(name)) + { + f.KeyValue(() => name); + } + + f.KeyValue(() => channels); + f.KeyValue(() => samplers); + } + + public int AddChannelAndGetSampler(int nodeIndex, glTFAnimationTarget.AnimationPropertys property) + { + // find channel + var channel = channels.FirstOrDefault(x => x.target.node == nodeIndex && x.target.path == glTFAnimationTarget.GetPathName(property)); + if (channel != null) + { + return channel.sampler; + } + + // not found. create new + var samplerIndex = samplers.Count; + var sampler = new glTFAnimationSampler(); + samplers.Add(sampler); + + channel = new glTFAnimationChannel + { + sampler = samplerIndex, + target = new glTFAnimationTarget + { + node = nodeIndex, + path = glTFAnimationTarget.GetPathName(property), + }, + }; + channels.Add(channel); + + return samplerIndex; + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFAnimation.cs.meta b/UniGLTF/Scripts/Format/glTFAnimation.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFAnimation.cs.meta rename to UniGLTF/Scripts/Format/glTFAnimation.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFAssets.cs b/UniGLTF/Scripts/Format/glTFAssets.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTFAssets.cs rename to UniGLTF/Scripts/Format/glTFAssets.cs index 74875e6ac..bf691fc82 100644 --- a/UniGLTF/Core/Scripts/Format/glTFAssets.cs +++ b/UniGLTF/Scripts/Format/glTFAssets.cs @@ -1,34 +1,34 @@ -using System; -using UniJSON; - -namespace UniGLTF -{ - [Serializable] - public class glTFAssets : JsonSerializableBase - { - public string generator; - - [JsonSchema(Required = true, Pattern = "^[0-9]+\\.[0-9]+$")] - public string version; - - public string copyright; - - [JsonSchema(Pattern = "^[0-9]+\\.[0-9]+$")] - public string minVersion; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.Key("generator"); f.Value(generator); - f.Key("version"); f.Value(version); - } - - public override string ToString() - { - return string.Format("GLTF-{0} generated by {1}", version, generator); - } - } -} +using System; +using UniJSON; + +namespace UniGLTF +{ + [Serializable] + public class glTFAssets : JsonSerializableBase + { + public string generator; + + [JsonSchema(Required = true, Pattern = "^[0-9]+\\.[0-9]+$")] + public string version; + + public string copyright; + + [JsonSchema(Pattern = "^[0-9]+\\.[0-9]+$")] + public string minVersion; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.Key("generator"); f.Value(generator); + f.Key("version"); f.Value(version); + } + + public override string ToString() + { + return string.Format("GLTF-{0} generated by {1}", version, generator); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFAssets.cs.meta b/UniGLTF/Scripts/Format/glTFAssets.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFAssets.cs.meta rename to UniGLTF/Scripts/Format/glTFAssets.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFBuffer.cs b/UniGLTF/Scripts/Format/glTFBuffer.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTFBuffer.cs rename to UniGLTF/Scripts/Format/glTFBuffer.cs index 2d6c14314..cbe9dc8cf 100644 --- a/UniGLTF/Core/Scripts/Format/glTFBuffer.cs +++ b/UniGLTF/Scripts/Format/glTFBuffer.cs @@ -1,261 +1,261 @@ -using System; -using System.Linq; -using UniJSON; - -namespace UniGLTF -{ - [Serializable] - public class glTFBuffer : JsonSerializableBase - { - IBytesBuffer Storage; - - public void OpenStorage(IStorage storage) - { - Storage = new ArraySegmentByteBuffer(storage.Get(uri)); - /* - if (string.IsNullOrEmpty(uri)) - { - Storage = (glbDataBytes); - } - else - { - Storage = new UriByteBuffer(baseDir, uri); - } - */ - } - - public glTFBuffer(IBytesBuffer storage) - { - Storage = storage; - } - - public string uri; - - [JsonSchema(Required = true, Minimum = 1)] - public int byteLength; - - // empty schemas - public object extensions; - public object extras; - public string name; - - public glTFBufferView Append(T[] array, glBufferTarget target) where T : struct - { - return Append(new ArraySegment(array), target); - } - public glTFBufferView Append(ArraySegment segment, glBufferTarget target) where T : struct - { - var view = Storage.Extend(segment, target); - byteLength = Storage.GetBytes().Count; - return view; - } - - public ArraySegment GetBytes() - { - return Storage.GetBytes(); - } - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - if (!string.IsNullOrEmpty(uri)) - { - f.KeyValue(() => uri); - } - f.KeyValue(() => byteLength); - } - } - - [Serializable] - public class glTFBufferView : JsonSerializableBase - { - [JsonSchema(Required = true, Minimum = 0)] - public int buffer; - - [JsonSchema(Minimum = 0)] - public int byteOffset; - - [JsonSchema(Required = true, Minimum = 1)] - public int byteLength; - - [JsonSchema(Minimum = 4, Maximum = 252, MultipleOf = 4)] - public int byteStride; - - [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, EnumExcludes = new object[] { glBufferTarget.NONE })] - public glBufferTarget target; - - // empty schemas - public object extensions; - public object extras; - public string name; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => buffer); - f.KeyValue(() => byteOffset); - f.KeyValue(() => byteLength); - if (target != glBufferTarget.NONE) - { - f.Key("target"); f.Value((int)target); - } - /* When this is not defined, data is tightly packed. When two or more accessors use the same bufferView, this field must be defined. - if (byteStride >= 4) - { - f.KeyValue(() => byteStride); - } - */ - } - } - - [Serializable] - public class glTFSparseIndices : JsonSerializableBase - { - [JsonSchema(Required = true, Minimum = 0)] - public int bufferView = -1; - - [JsonSchema(Minimum = 0)] - public int byteOffset; - - [JsonSchema(Required = true, EnumValues = new object[] { 5121, 5123, 5125 })] - public glComponentType componentType; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => bufferView); - f.KeyValue(() => byteOffset); - f.Key("componentType"); f.Value((int)componentType); - } - } - - [Serializable] - public class glTFSparseValues : JsonSerializableBase - { - [JsonSchema(Required = true, Minimum = 0)] - public int bufferView = -1; - - [JsonSchema(Minimum = 0)] - public int byteOffset; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => bufferView); - f.KeyValue(() => byteOffset); - } - } - - [Serializable] - public class glTFSparse : JsonSerializableBase - { - [JsonSchema(Required = true, Minimum = 1)] - public int count; - - [JsonSchema(Required = true)] - public glTFSparseIndices indices; - - [JsonSchema(Required = true)] - public glTFSparseValues values; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => count); - f.KeyValue(() => indices); - f.KeyValue(() => values); - } - } - - [Serializable] - public class glTFAccessor : JsonSerializableBase - { - [JsonSchema(Minimum = 0)] - public int bufferView = -1; - - [JsonSchema(Minimum = 0, Dependencies = new string[] { "bufferView" })] - public int byteOffset; - - [JsonSchema(Required = true, EnumValues = new object[] { "SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4" }, EnumSerializationType = EnumSerializationType.AsString)] - public string type; - - public int TypeCount - { - get - { - switch (type) - { - case "SCALAR": - return 1; - case "VEC2": - return 2; - case "VEC3": - return 3; - case "VEC4": - case "MAT2": - return 4; - case "MAT3": - return 9; - case "MAT4": - return 16; - default: - throw new NotImplementedException(); - } - } - } - - [JsonSchema(Required = true, EnumSerializationType = EnumSerializationType.AsInt)] - public glComponentType componentType; - - [JsonSchema(Required = true, Minimum = 1)] - public int count; - - [JsonSchema(MinItems = 1, MaxItems = 16)] - public float[] max; - - [JsonSchema(MinItems = 1, MaxItems = 16)] - public float[] min; - - public bool normalized; - public glTFSparse sparse; - - // empty schemas - public string name; - - public object extensions; - - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => bufferView); - f.KeyValue(() => byteOffset); - f.KeyValue(() => type); - f.Key("componentType"); f.Value((int)componentType); - f.KeyValue(() => count); - if (max != null && max.Any()) - { - f.KeyValue(() => max); - } - if (min != null && min.Any()) - { - f.KeyValue(() => min); - } - - if (sparse != null && sparse.count > 0) - { - f.KeyValue(() => sparse); - } - - f.KeyValue(() => normalized); - f.KeyValue(() => name); - } - } -} +using System; +using System.Linq; +using UniJSON; + +namespace UniGLTF +{ + [Serializable] + public class glTFBuffer : JsonSerializableBase + { + IBytesBuffer Storage; + + public void OpenStorage(IStorage storage) + { + Storage = new ArraySegmentByteBuffer(storage.Get(uri)); + /* + if (string.IsNullOrEmpty(uri)) + { + Storage = (glbDataBytes); + } + else + { + Storage = new UriByteBuffer(baseDir, uri); + } + */ + } + + public glTFBuffer(IBytesBuffer storage) + { + Storage = storage; + } + + public string uri; + + [JsonSchema(Required = true, Minimum = 1)] + public int byteLength; + + // empty schemas + public object extensions; + public object extras; + public string name; + + public glTFBufferView Append(T[] array, glBufferTarget target) where T : struct + { + return Append(new ArraySegment(array), target); + } + public glTFBufferView Append(ArraySegment segment, glBufferTarget target) where T : struct + { + var view = Storage.Extend(segment, target); + byteLength = Storage.GetBytes().Count; + return view; + } + + public ArraySegment GetBytes() + { + return Storage.GetBytes(); + } + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + if (!string.IsNullOrEmpty(uri)) + { + f.KeyValue(() => uri); + } + f.KeyValue(() => byteLength); + } + } + + [Serializable] + public class glTFBufferView : JsonSerializableBase + { + [JsonSchema(Required = true, Minimum = 0)] + public int buffer; + + [JsonSchema(Minimum = 0)] + public int byteOffset; + + [JsonSchema(Required = true, Minimum = 1)] + public int byteLength; + + [JsonSchema(Minimum = 4, Maximum = 252, MultipleOf = 4)] + public int byteStride; + + [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, EnumExcludes = new object[] { glBufferTarget.NONE })] + public glBufferTarget target; + + // empty schemas + public object extensions; + public object extras; + public string name; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => buffer); + f.KeyValue(() => byteOffset); + f.KeyValue(() => byteLength); + if (target != glBufferTarget.NONE) + { + f.Key("target"); f.Value((int)target); + } + /* When this is not defined, data is tightly packed. When two or more accessors use the same bufferView, this field must be defined. + if (byteStride >= 4) + { + f.KeyValue(() => byteStride); + } + */ + } + } + + [Serializable] + public class glTFSparseIndices : JsonSerializableBase + { + [JsonSchema(Required = true, Minimum = 0)] + public int bufferView = -1; + + [JsonSchema(Minimum = 0)] + public int byteOffset; + + [JsonSchema(Required = true, EnumValues = new object[] { 5121, 5123, 5125 })] + public glComponentType componentType; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => bufferView); + f.KeyValue(() => byteOffset); + f.Key("componentType"); f.Value((int)componentType); + } + } + + [Serializable] + public class glTFSparseValues : JsonSerializableBase + { + [JsonSchema(Required = true, Minimum = 0)] + public int bufferView = -1; + + [JsonSchema(Minimum = 0)] + public int byteOffset; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => bufferView); + f.KeyValue(() => byteOffset); + } + } + + [Serializable] + public class glTFSparse : JsonSerializableBase + { + [JsonSchema(Required = true, Minimum = 1)] + public int count; + + [JsonSchema(Required = true)] + public glTFSparseIndices indices; + + [JsonSchema(Required = true)] + public glTFSparseValues values; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => count); + f.KeyValue(() => indices); + f.KeyValue(() => values); + } + } + + [Serializable] + public class glTFAccessor : JsonSerializableBase + { + [JsonSchema(Minimum = 0)] + public int bufferView = -1; + + [JsonSchema(Minimum = 0, Dependencies = new string[] { "bufferView" })] + public int byteOffset; + + [JsonSchema(Required = true, EnumValues = new object[] { "SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4" }, EnumSerializationType = EnumSerializationType.AsString)] + public string type; + + public int TypeCount + { + get + { + switch (type) + { + case "SCALAR": + return 1; + case "VEC2": + return 2; + case "VEC3": + return 3; + case "VEC4": + case "MAT2": + return 4; + case "MAT3": + return 9; + case "MAT4": + return 16; + default: + throw new NotImplementedException(); + } + } + } + + [JsonSchema(Required = true, EnumSerializationType = EnumSerializationType.AsInt)] + public glComponentType componentType; + + [JsonSchema(Required = true, Minimum = 1)] + public int count; + + [JsonSchema(MinItems = 1, MaxItems = 16)] + public float[] max; + + [JsonSchema(MinItems = 1, MaxItems = 16)] + public float[] min; + + public bool normalized; + public glTFSparse sparse; + + // empty schemas + public string name; + + public object extensions; + + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => bufferView); + f.KeyValue(() => byteOffset); + f.KeyValue(() => type); + f.Key("componentType"); f.Value((int)componentType); + f.KeyValue(() => count); + if (max != null && max.Any()) + { + f.KeyValue(() => max); + } + if (min != null && min.Any()) + { + f.KeyValue(() => min); + } + + if (sparse != null && sparse.count > 0) + { + f.KeyValue(() => sparse); + } + + f.KeyValue(() => normalized); + f.KeyValue(() => name); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFBuffer.cs.meta b/UniGLTF/Scripts/Format/glTFBuffer.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFBuffer.cs.meta rename to UniGLTF/Scripts/Format/glTFBuffer.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFCamera.cs b/UniGLTF/Scripts/Format/glTFCamera.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTFCamera.cs rename to UniGLTF/Scripts/Format/glTFCamera.cs index 36dcc9832..87de30c1b 100644 --- a/UniGLTF/Core/Scripts/Format/glTFCamera.cs +++ b/UniGLTF/Scripts/Format/glTFCamera.cs @@ -1,60 +1,60 @@ -using System; -using UniJSON; - -namespace UniGLTF -{ - public enum ProjectionType - { - Perspective, - Orthographic - } - - [Serializable] - public class glTFOrthographic - { - [JsonSchema(Required = true)] - public float xmag; - [JsonSchema(Required = true)] - public float ymag; - [JsonSchema(Required = true, Minimum = 0.0f, ExclusiveMinimum = true)] - public float zfar; - [JsonSchema(Required = true, Minimum = 0.0f)] - public float znear; - - [JsonSchema(MinProperties = 1)] - public glTFOrthographic_extensions extensions; - [JsonSchema(MinProperties = 1)] - public glTFOrthographic_extras extras; - } - - [Serializable] - public class glTFPerspective - { - [JsonSchema(Minimum = 0.0f, ExclusiveMinimum = true)] - public float aspectRatio; - [JsonSchema(Required = true, Minimum = 0.0f, ExclusiveMinimum = true)] - public float yfov; - [JsonSchema(Minimum = 0.0f, ExclusiveMinimum = true)] - public float zfar; - [JsonSchema(Required = true, Minimum = 0.0f, ExclusiveMinimum = true)] - public float znear; - - public glTFPerspective_extensions extensions; - public glTFPerspective_extras extras; - } - - [Serializable] - public class glTFCamera - { - public glTFOrthographic orthographic; - public glTFPerspective perspective; - - [JsonSchema(Required = true, EnumSerializationType = EnumSerializationType.AsLowerString)] - public ProjectionType type; - - public string name; - - public glTFCamera_extensions extensions; - public glTFCamera_extras extras; - } -} +using System; +using UniJSON; + +namespace UniGLTF +{ + public enum ProjectionType + { + Perspective, + Orthographic + } + + [Serializable] + public class glTFOrthographic + { + [JsonSchema(Required = true)] + public float xmag; + [JsonSchema(Required = true)] + public float ymag; + [JsonSchema(Required = true, Minimum = 0.0f, ExclusiveMinimum = true)] + public float zfar; + [JsonSchema(Required = true, Minimum = 0.0f)] + public float znear; + + [JsonSchema(MinProperties = 1)] + public glTFOrthographic_extensions extensions; + [JsonSchema(MinProperties = 1)] + public glTFOrthographic_extras extras; + } + + [Serializable] + public class glTFPerspective + { + [JsonSchema(Minimum = 0.0f, ExclusiveMinimum = true)] + public float aspectRatio; + [JsonSchema(Required = true, Minimum = 0.0f, ExclusiveMinimum = true)] + public float yfov; + [JsonSchema(Minimum = 0.0f, ExclusiveMinimum = true)] + public float zfar; + [JsonSchema(Required = true, Minimum = 0.0f, ExclusiveMinimum = true)] + public float znear; + + public glTFPerspective_extensions extensions; + public glTFPerspective_extras extras; + } + + [Serializable] + public class glTFCamera + { + public glTFOrthographic orthographic; + public glTFPerspective perspective; + + [JsonSchema(Required = true, EnumSerializationType = EnumSerializationType.AsLowerString)] + public ProjectionType type; + + public string name; + + public glTFCamera_extensions extensions; + public glTFCamera_extras extras; + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFCamera.cs.meta b/UniGLTF/Scripts/Format/glTFCamera.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFCamera.cs.meta rename to UniGLTF/Scripts/Format/glTFCamera.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFMaterial.cs b/UniGLTF/Scripts/Format/glTFMaterial.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTFMaterial.cs rename to UniGLTF/Scripts/Format/glTFMaterial.cs index 10c344eaf..8afd5e4df 100644 --- a/UniGLTF/Core/Scripts/Format/glTFMaterial.cs +++ b/UniGLTF/Scripts/Format/glTFMaterial.cs @@ -1,225 +1,225 @@ -using System; -using UniJSON; - -namespace UniGLTF -{ - public enum glTFTextureTypes - { - BaseColor, - Metallic, - Normal, - Occlusion, - Emissive, - Unknown - } - - public interface IglTFTextureinfo - { - glTFTextureTypes TextreType { get; } - } - - [Serializable] - public abstract class glTFTextureInfo : JsonSerializableBase, IglTFTextureinfo - { - [JsonSchema(Required = true, Minimum = 0)] - public int index = -1; - - [JsonSchema(Minimum = 0)] - public int texCoord; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => index); - f.KeyValue(() => texCoord); - } - - public abstract glTFTextureTypes TextreType { get; } - } - - - [Serializable] - public class glTFMaterialBaseColorTextureInfo : glTFTextureInfo - { - public override glTFTextureTypes TextreType - { - get { return glTFTextureTypes.BaseColor; } - } - } - - [Serializable] - public class glTFMaterialMetallicRoughnessTextureInfo : glTFTextureInfo - { - public override glTFTextureTypes TextreType - { - get { return glTFTextureTypes.Metallic; } - } - } - - [Serializable] - public class glTFMaterialNormalTextureInfo : glTFTextureInfo - { - public float scale = 1.0f; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => scale); - base.SerializeMembers(f); - } - - public override glTFTextureTypes TextreType - { - get { return glTFTextureTypes.Normal; } - } - } - - [Serializable] - public class glTFMaterialOcclusionTextureInfo : glTFTextureInfo - { - [JsonSchema(Minimum = 0.0, Maximum = 1.0)] - public float strength = 1.0f; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => strength); - base.SerializeMembers(f); - } - - public override glTFTextureTypes TextreType - { - get { return glTFTextureTypes.Occlusion; } - } - } - - [Serializable] - public class glTFMaterialEmissiveTextureInfo : glTFTextureInfo - { - public override glTFTextureTypes TextreType - { - get { return glTFTextureTypes.Emissive; } - } - } - - [Serializable] - public class glTFPbrMetallicRoughness : JsonSerializableBase - { - public glTFMaterialBaseColorTextureInfo baseColorTexture = null; - - [JsonSchema(MinItems = 4, MaxItems = 4)] - [ItemJsonSchema(Minimum = 0.0, Maximum = 1.0)] - public float[] baseColorFactor; - - public glTFMaterialMetallicRoughnessTextureInfo metallicRoughnessTexture = null; - - [JsonSchema(Minimum = 0.0, Maximum = 1.0)] - public float metallicFactor = 1.0f; - - [JsonSchema(Minimum = 0.0, Maximum = 1.0)] - public float roughnessFactor = 1.0f; - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - if (baseColorTexture != null) - { - f.KeyValue(() => baseColorTexture); - } - if (baseColorFactor != null) - { - f.KeyValue(() => baseColorFactor); - } - if (metallicRoughnessTexture != null) - { - f.KeyValue(() => metallicRoughnessTexture); - } - f.KeyValue(() => metallicFactor); - f.KeyValue(() => roughnessFactor); - } - } - - [Serializable] - public class glTFMaterial : JsonSerializableBase - { - public string name; - public glTFPbrMetallicRoughness pbrMetallicRoughness; - public glTFMaterialNormalTextureInfo normalTexture = null; - - public glTFMaterialOcclusionTextureInfo occlusionTexture = null; - - public glTFMaterialEmissiveTextureInfo emissiveTexture = null; - - [JsonSchema(MinItems = 3, MaxItems = 3)] - [ItemJsonSchema(Minimum = 0.0, Maximum = 1.0)] - public float[] emissiveFactor; - - [JsonSchema(EnumValues = new object[] { "OPAQUE", "MASK", "BLEND" }, EnumSerializationType = EnumSerializationType.AsUpperString)] - public string alphaMode; - - [JsonSchema(Dependencies = new string[] { "alphaMode" }, Minimum = 0.0)] - public float alphaCutoff = 0.5f; - - public bool doubleSided; - - [JsonSchema(SkipSchemaComparison = true)] - public glTFMaterial_extensions extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - if (!String.IsNullOrEmpty(name)) - { - f.Key("name"); f.Value(name); - } - if (pbrMetallicRoughness != null) - { - f.Key("pbrMetallicRoughness"); f.GLTFValue(pbrMetallicRoughness); - } - if (normalTexture != null) - { - f.Key("normalTexture"); f.GLTFValue(normalTexture); - } - if (occlusionTexture != null) - { - f.Key("occlusionTexture"); f.GLTFValue(occlusionTexture); - } - if (emissiveTexture != null) - { - f.Key("emissiveTexture"); f.GLTFValue(emissiveTexture); - } - if (emissiveFactor != null) - { - f.Key("emissiveFactor"); f.Serialize(emissiveFactor); - } - - f.KeyValue(() => doubleSided); - - if (!string.IsNullOrEmpty(alphaMode)) - { - f.KeyValue(() => alphaMode); - } - - if (extensions != null) - { - f.KeyValue(() => extensions); - } - } - - public glTFTextureInfo[] GetTextures() - { - return new glTFTextureInfo[] - { - pbrMetallicRoughness.baseColorTexture, - pbrMetallicRoughness.metallicRoughnessTexture, - normalTexture, - occlusionTexture, - emissiveTexture - }; - } - } -} +using System; +using UniJSON; + +namespace UniGLTF +{ + public enum glTFTextureTypes + { + BaseColor, + Metallic, + Normal, + Occlusion, + Emissive, + Unknown + } + + public interface IglTFTextureinfo + { + glTFTextureTypes TextreType { get; } + } + + [Serializable] + public abstract class glTFTextureInfo : JsonSerializableBase, IglTFTextureinfo + { + [JsonSchema(Required = true, Minimum = 0)] + public int index = -1; + + [JsonSchema(Minimum = 0)] + public int texCoord; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => index); + f.KeyValue(() => texCoord); + } + + public abstract glTFTextureTypes TextreType { get; } + } + + + [Serializable] + public class glTFMaterialBaseColorTextureInfo : glTFTextureInfo + { + public override glTFTextureTypes TextreType + { + get { return glTFTextureTypes.BaseColor; } + } + } + + [Serializable] + public class glTFMaterialMetallicRoughnessTextureInfo : glTFTextureInfo + { + public override glTFTextureTypes TextreType + { + get { return glTFTextureTypes.Metallic; } + } + } + + [Serializable] + public class glTFMaterialNormalTextureInfo : glTFTextureInfo + { + public float scale = 1.0f; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => scale); + base.SerializeMembers(f); + } + + public override glTFTextureTypes TextreType + { + get { return glTFTextureTypes.Normal; } + } + } + + [Serializable] + public class glTFMaterialOcclusionTextureInfo : glTFTextureInfo + { + [JsonSchema(Minimum = 0.0, Maximum = 1.0)] + public float strength = 1.0f; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => strength); + base.SerializeMembers(f); + } + + public override glTFTextureTypes TextreType + { + get { return glTFTextureTypes.Occlusion; } + } + } + + [Serializable] + public class glTFMaterialEmissiveTextureInfo : glTFTextureInfo + { + public override glTFTextureTypes TextreType + { + get { return glTFTextureTypes.Emissive; } + } + } + + [Serializable] + public class glTFPbrMetallicRoughness : JsonSerializableBase + { + public glTFMaterialBaseColorTextureInfo baseColorTexture = null; + + [JsonSchema(MinItems = 4, MaxItems = 4)] + [ItemJsonSchema(Minimum = 0.0, Maximum = 1.0)] + public float[] baseColorFactor; + + public glTFMaterialMetallicRoughnessTextureInfo metallicRoughnessTexture = null; + + [JsonSchema(Minimum = 0.0, Maximum = 1.0)] + public float metallicFactor = 1.0f; + + [JsonSchema(Minimum = 0.0, Maximum = 1.0)] + public float roughnessFactor = 1.0f; + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + if (baseColorTexture != null) + { + f.KeyValue(() => baseColorTexture); + } + if (baseColorFactor != null) + { + f.KeyValue(() => baseColorFactor); + } + if (metallicRoughnessTexture != null) + { + f.KeyValue(() => metallicRoughnessTexture); + } + f.KeyValue(() => metallicFactor); + f.KeyValue(() => roughnessFactor); + } + } + + [Serializable] + public class glTFMaterial : JsonSerializableBase + { + public string name; + public glTFPbrMetallicRoughness pbrMetallicRoughness; + public glTFMaterialNormalTextureInfo normalTexture = null; + + public glTFMaterialOcclusionTextureInfo occlusionTexture = null; + + public glTFMaterialEmissiveTextureInfo emissiveTexture = null; + + [JsonSchema(MinItems = 3, MaxItems = 3)] + [ItemJsonSchema(Minimum = 0.0, Maximum = 1.0)] + public float[] emissiveFactor; + + [JsonSchema(EnumValues = new object[] { "OPAQUE", "MASK", "BLEND" }, EnumSerializationType = EnumSerializationType.AsUpperString)] + public string alphaMode; + + [JsonSchema(Dependencies = new string[] { "alphaMode" }, Minimum = 0.0)] + public float alphaCutoff = 0.5f; + + public bool doubleSided; + + [JsonSchema(SkipSchemaComparison = true)] + public glTFMaterial_extensions extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + if (!String.IsNullOrEmpty(name)) + { + f.Key("name"); f.Value(name); + } + if (pbrMetallicRoughness != null) + { + f.Key("pbrMetallicRoughness"); f.GLTFValue(pbrMetallicRoughness); + } + if (normalTexture != null) + { + f.Key("normalTexture"); f.GLTFValue(normalTexture); + } + if (occlusionTexture != null) + { + f.Key("occlusionTexture"); f.GLTFValue(occlusionTexture); + } + if (emissiveTexture != null) + { + f.Key("emissiveTexture"); f.GLTFValue(emissiveTexture); + } + if (emissiveFactor != null) + { + f.Key("emissiveFactor"); f.Serialize(emissiveFactor); + } + + f.KeyValue(() => doubleSided); + + if (!string.IsNullOrEmpty(alphaMode)) + { + f.KeyValue(() => alphaMode); + } + + if (extensions != null) + { + f.KeyValue(() => extensions); + } + } + + public glTFTextureInfo[] GetTextures() + { + return new glTFTextureInfo[] + { + pbrMetallicRoughness.baseColorTexture, + pbrMetallicRoughness.metallicRoughnessTexture, + normalTexture, + occlusionTexture, + emissiveTexture + }; + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFMaterial.cs.meta b/UniGLTF/Scripts/Format/glTFMaterial.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFMaterial.cs.meta rename to UniGLTF/Scripts/Format/glTFMaterial.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFMesh.cs b/UniGLTF/Scripts/Format/glTFMesh.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTFMesh.cs rename to UniGLTF/Scripts/Format/glTFMesh.cs index 854c1fac5..4c6e85882 100644 --- a/UniGLTF/Core/Scripts/Format/glTFMesh.cs +++ b/UniGLTF/Scripts/Format/glTFMesh.cs @@ -1,168 +1,168 @@ -using System; -using System.Collections.Generic; -using UniJSON; - -namespace UniGLTF -{ - [Serializable] - public class glTFAttributes : JsonSerializableBase - { - [JsonSchema(Minimum = 0)] - public int POSITION = -1; - - [JsonSchema(Minimum = 0)] - public int NORMAL = -1; - - [JsonSchema(Minimum = 0)] - public int TANGENT = -1; - - [JsonSchema(Minimum = 0)] - public int TEXCOORD_0 = -1; - - [JsonSchema(Minimum = 0)] - public int COLOR_0 = -1; - - [JsonSchema(Minimum = 0)] - public int JOINTS_0 = -1; - - [JsonSchema(Minimum = 0)] - public int WEIGHTS_0 = -1; - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override bool Equals(object obj) - { - var rhs = obj as glTFAttributes; - if (rhs == null) - { - return base.Equals(obj); - } - - return POSITION == rhs.POSITION - && NORMAL == rhs.NORMAL - && TANGENT == rhs.TANGENT - && TEXCOORD_0 == rhs.TEXCOORD_0 - && COLOR_0 == rhs.COLOR_0 - && JOINTS_0 == rhs.JOINTS_0 - && WEIGHTS_0 == rhs.WEIGHTS_0 - ; - } - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => POSITION); - if (NORMAL != -1) f.KeyValue(() => NORMAL); - if (TANGENT != -1) f.KeyValue(() => TANGENT); - if (TEXCOORD_0 != -1) f.KeyValue(() => TEXCOORD_0); - if (COLOR_0 != -1) f.KeyValue(() => COLOR_0); - if (JOINTS_0 != -1) f.KeyValue(() => JOINTS_0); - if (WEIGHTS_0 != -1) f.KeyValue(() => WEIGHTS_0); - } - } - - [Serializable] - public class gltfMorphTarget : JsonSerializableBase - { - public int POSITION = -1; - public int NORMAL = -1; - public int TANGENT = -1; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => POSITION); - if (NORMAL >= 0) f.KeyValue(() => NORMAL); - if (TANGENT >= 0) f.KeyValue(() => TANGENT); - } - } - - /// - /// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/schema/mesh.primitive.schema.json - /// - [Serializable] - public class glTFPrimitives : JsonSerializableBase - { - [JsonSchema(EnumValues = new object[] { 0, 1, 2, 3, 4, 5, 6 })] - public int mode; - - [JsonSchema(Minimum = 0)] - public int indices = -1; - - [JsonSchema(Required = true, SkipSchemaComparison = true)] - public glTFAttributes attributes; - - public bool HasVertexColor - { - get - { - return attributes.COLOR_0 != -1; - } - } - - [JsonSchema(Minimum = 0)] - public int material; - - [JsonSchema(MinItems = 1)] - [ItemJsonSchema(SkipSchemaComparison = true)] - public List targets = new List(); - - public glTFPrimitives_extras extras = new glTFPrimitives_extras(); - - [JsonSchema(SkipSchemaComparison = true)] - public glTFPrimitives_extensions extensions = new glTFPrimitives_extensions(); - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => mode); - f.KeyValue(() => indices); - f.Key("attributes"); f.GLTFValue(attributes); - f.KeyValue(() => material); - if (targets != null && targets.Count > 0) - { - f.Key("targets"); f.GLTFValue(targets); - } - if (extensions.KHR_draco_mesh_compression != null) - { - f.KeyValue(() => extensions); - } - if (extras.targetNames.Count > 0) - { - f.KeyValue(() => extras); - } - } - } - - [Serializable] - public class glTFMesh : JsonSerializableBase - { - public string name; - - [JsonSchema(Required = true, MinItems = 1)] - public List primitives; - - [JsonSchema(MinItems = 1)] - public float[] weights; - - // empty schemas - public object extensions; - public object extras; - - public glTFMesh(string _name) - { - name = _name; - primitives = new List(); - } - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => name); - f.Key("primitives"); f.GLTFValue(primitives); - if (weights != null && weights.Length > 0) - { - f.KeyValue(() => weights); - } - } - } -} +using System; +using System.Collections.Generic; +using UniJSON; + +namespace UniGLTF +{ + [Serializable] + public class glTFAttributes : JsonSerializableBase + { + [JsonSchema(Minimum = 0)] + public int POSITION = -1; + + [JsonSchema(Minimum = 0)] + public int NORMAL = -1; + + [JsonSchema(Minimum = 0)] + public int TANGENT = -1; + + [JsonSchema(Minimum = 0)] + public int TEXCOORD_0 = -1; + + [JsonSchema(Minimum = 0)] + public int COLOR_0 = -1; + + [JsonSchema(Minimum = 0)] + public int JOINTS_0 = -1; + + [JsonSchema(Minimum = 0)] + public int WEIGHTS_0 = -1; + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + public override bool Equals(object obj) + { + var rhs = obj as glTFAttributes; + if (rhs == null) + { + return base.Equals(obj); + } + + return POSITION == rhs.POSITION + && NORMAL == rhs.NORMAL + && TANGENT == rhs.TANGENT + && TEXCOORD_0 == rhs.TEXCOORD_0 + && COLOR_0 == rhs.COLOR_0 + && JOINTS_0 == rhs.JOINTS_0 + && WEIGHTS_0 == rhs.WEIGHTS_0 + ; + } + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => POSITION); + if (NORMAL != -1) f.KeyValue(() => NORMAL); + if (TANGENT != -1) f.KeyValue(() => TANGENT); + if (TEXCOORD_0 != -1) f.KeyValue(() => TEXCOORD_0); + if (COLOR_0 != -1) f.KeyValue(() => COLOR_0); + if (JOINTS_0 != -1) f.KeyValue(() => JOINTS_0); + if (WEIGHTS_0 != -1) f.KeyValue(() => WEIGHTS_0); + } + } + + [Serializable] + public class gltfMorphTarget : JsonSerializableBase + { + public int POSITION = -1; + public int NORMAL = -1; + public int TANGENT = -1; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => POSITION); + if (NORMAL >= 0) f.KeyValue(() => NORMAL); + if (TANGENT >= 0) f.KeyValue(() => TANGENT); + } + } + + /// + /// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/schema/mesh.primitive.schema.json + /// + [Serializable] + public class glTFPrimitives : JsonSerializableBase + { + [JsonSchema(EnumValues = new object[] { 0, 1, 2, 3, 4, 5, 6 })] + public int mode; + + [JsonSchema(Minimum = 0)] + public int indices = -1; + + [JsonSchema(Required = true, SkipSchemaComparison = true)] + public glTFAttributes attributes; + + public bool HasVertexColor + { + get + { + return attributes.COLOR_0 != -1; + } + } + + [JsonSchema(Minimum = 0)] + public int material; + + [JsonSchema(MinItems = 1)] + [ItemJsonSchema(SkipSchemaComparison = true)] + public List targets = new List(); + + public glTFPrimitives_extras extras = new glTFPrimitives_extras(); + + [JsonSchema(SkipSchemaComparison = true)] + public glTFPrimitives_extensions extensions = new glTFPrimitives_extensions(); + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => mode); + f.KeyValue(() => indices); + f.Key("attributes"); f.GLTFValue(attributes); + f.KeyValue(() => material); + if (targets != null && targets.Count > 0) + { + f.Key("targets"); f.GLTFValue(targets); + } + if (extensions.KHR_draco_mesh_compression != null) + { + f.KeyValue(() => extensions); + } + if (extras.targetNames.Count > 0) + { + f.KeyValue(() => extras); + } + } + } + + [Serializable] + public class glTFMesh : JsonSerializableBase + { + public string name; + + [JsonSchema(Required = true, MinItems = 1)] + public List primitives; + + [JsonSchema(MinItems = 1)] + public float[] weights; + + // empty schemas + public object extensions; + public object extras; + + public glTFMesh(string _name) + { + name = _name; + primitives = new List(); + } + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => name); + f.Key("primitives"); f.GLTFValue(primitives); + if (weights != null && weights.Length > 0) + { + f.KeyValue(() => weights); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFMesh.cs.meta b/UniGLTF/Scripts/Format/glTFMesh.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFMesh.cs.meta rename to UniGLTF/Scripts/Format/glTFMesh.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFNode.cs b/UniGLTF/Scripts/Format/glTFNode.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTFNode.cs rename to UniGLTF/Scripts/Format/glTFNode.cs index e21dc10f0..4228f4e7b 100644 --- a/UniGLTF/Core/Scripts/Format/glTFNode.cs +++ b/UniGLTF/Scripts/Format/glTFNode.cs @@ -1,76 +1,76 @@ -using System; -using System.Linq; -using UniJSON; - -namespace UniGLTF -{ - [Serializable] - public class glTFNode : JsonSerializableBase - { - public string name = ""; - - [JsonSchema(MinItems = 1)] - [ItemJsonSchema(Minimum = 0)] - public int[] children; - - [JsonSchema(MinItems = 16, MaxItems = 16)] - public float[] matrix; - - [JsonSchema(MinItems = 3, MaxItems = 3)] - public float[] translation; - - [JsonSchema(MinItems = 4, MaxItems = 4)] - [ItemJsonSchema(Minimum = -1.0, Maximum = 1.0)] - public float[] rotation; - - [JsonSchema(MinItems = 3, MaxItems = 3)] - public float[] scale; - - [JsonSchema(Minimum = 0)] - public int mesh = -1; - - [JsonSchema(Dependencies = new string[] { "mesh" }, Minimum = 0)] - public int skin = -1; - - [JsonSchema(Dependencies = new string[] { "mesh" }, MinItems = 1)] - public float[] weights; - - [JsonSchema(Minimum = 0)] - public int camera = -1; - - // empty schemas - public glTFNode_extensions extensions; - public glTFNode_extra extras = new glTFNode_extra(); - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - if (children != null && children.Any()) - { - f.Key("children"); f.BeginList(); - foreach (var child in children) - { - f.Value(child); - } - f.EndList(); - } - - if (!string.IsNullOrEmpty(name)) f.KeyValue(() => name); - if (matrix != null) f.KeyValue(() => matrix); - if (translation != null) f.KeyValue(() => translation); - if (rotation != null) f.KeyValue(() => rotation); - if (scale != null) f.KeyValue(() => scale); - - if (mesh >= 0) f.KeyValue(() => mesh); - if (camera >= 0) f.KeyValue(() => camera); - if (skin >= 0) - { - f.KeyValue(() => skin); - - if (extras.__count > 0) - { - f.KeyValue(() => extras); - } - } - } - } -} +using System; +using System.Linq; +using UniJSON; + +namespace UniGLTF +{ + [Serializable] + public class glTFNode : JsonSerializableBase + { + public string name = ""; + + [JsonSchema(MinItems = 1)] + [ItemJsonSchema(Minimum = 0)] + public int[] children; + + [JsonSchema(MinItems = 16, MaxItems = 16)] + public float[] matrix; + + [JsonSchema(MinItems = 3, MaxItems = 3)] + public float[] translation; + + [JsonSchema(MinItems = 4, MaxItems = 4)] + [ItemJsonSchema(Minimum = -1.0, Maximum = 1.0)] + public float[] rotation; + + [JsonSchema(MinItems = 3, MaxItems = 3)] + public float[] scale; + + [JsonSchema(Minimum = 0)] + public int mesh = -1; + + [JsonSchema(Dependencies = new string[] { "mesh" }, Minimum = 0)] + public int skin = -1; + + [JsonSchema(Dependencies = new string[] { "mesh" }, MinItems = 1)] + public float[] weights; + + [JsonSchema(Minimum = 0)] + public int camera = -1; + + // empty schemas + public glTFNode_extensions extensions; + public glTFNode_extra extras = new glTFNode_extra(); + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + if (children != null && children.Any()) + { + f.Key("children"); f.BeginList(); + foreach (var child in children) + { + f.Value(child); + } + f.EndList(); + } + + if (!string.IsNullOrEmpty(name)) f.KeyValue(() => name); + if (matrix != null) f.KeyValue(() => matrix); + if (translation != null) f.KeyValue(() => translation); + if (rotation != null) f.KeyValue(() => rotation); + if (scale != null) f.KeyValue(() => scale); + + if (mesh >= 0) f.KeyValue(() => mesh); + if (camera >= 0) f.KeyValue(() => camera); + if (skin >= 0) + { + f.KeyValue(() => skin); + + if (extras.__count > 0) + { + f.KeyValue(() => extras); + } + } + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFNode.cs.meta b/UniGLTF/Scripts/Format/glTFNode.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFNode.cs.meta rename to UniGLTF/Scripts/Format/glTFNode.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFSkin.cs b/UniGLTF/Scripts/Format/glTFSkin.cs similarity index 95% rename from UniGLTF/Core/Scripts/Format/glTFSkin.cs rename to UniGLTF/Scripts/Format/glTFSkin.cs index c66e1e977..fefad7259 100644 --- a/UniGLTF/Core/Scripts/Format/glTFSkin.cs +++ b/UniGLTF/Scripts/Format/glTFSkin.cs @@ -1,34 +1,34 @@ -using System; -using UniJSON; - -namespace UniGLTF -{ - [Serializable] - public class glTFSkin : JsonSerializableBase - { - [JsonSchema(Minimum = 0)] - public int inverseBindMatrices = -1; - - [JsonSchema(Required = true, MinItems = 1)] - [ItemJsonSchema(Minimum = 0)] - public int[] joints; - - [JsonSchema(Minimum = 0)] - public int skeleton = -1; - - // empty schemas - public object extensions; - public object extras; - public string name; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => inverseBindMatrices); - f.KeyValue(() => joints); - if (skeleton >= 0) - { - f.KeyValue(() => skeleton); - } - } - } -} +using System; +using UniJSON; + +namespace UniGLTF +{ + [Serializable] + public class glTFSkin : JsonSerializableBase + { + [JsonSchema(Minimum = 0)] + public int inverseBindMatrices = -1; + + [JsonSchema(Required = true, MinItems = 1)] + [ItemJsonSchema(Minimum = 0)] + public int[] joints; + + [JsonSchema(Minimum = 0)] + public int skeleton = -1; + + // empty schemas + public object extensions; + public object extras; + public string name; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => inverseBindMatrices); + f.KeyValue(() => joints); + if (skeleton >= 0) + { + f.KeyValue(() => skeleton); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFSkin.cs.meta b/UniGLTF/Scripts/Format/glTFSkin.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFSkin.cs.meta rename to UniGLTF/Scripts/Format/glTFSkin.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glTFTexture.cs b/UniGLTF/Scripts/Format/glTFTexture.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glTFTexture.cs rename to UniGLTF/Scripts/Format/glTFTexture.cs index a8ef58995..199846b9e 100644 --- a/UniGLTF/Core/Scripts/Format/glTFTexture.cs +++ b/UniGLTF/Scripts/Format/glTFTexture.cs @@ -1,123 +1,123 @@ -using System; -using System.IO; -using UniJSON; - -namespace UniGLTF -{ - [Serializable] - public class glTFTextureSampler : JsonSerializableBase - { - [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, - EnumExcludes = new object[] { - glFilter.NONE, - glFilter.NEAREST_MIPMAP_NEAREST, - glFilter.LINEAR_MIPMAP_NEAREST, - glFilter.NEAREST_MIPMAP_LINEAR, - glFilter.LINEAR_MIPMAP_LINEAR, - })] - public glFilter magFilter = glFilter.NEAREST; - - [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, - EnumExcludes = new object[] { glFilter.NONE })] - public glFilter minFilter = glFilter.NEAREST; - - [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, - EnumExcludes = new object[] { glWrap.NONE })] - public glWrap wrapS = glWrap.REPEAT; - - [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, - EnumExcludes = new object[] { glWrap.NONE })] - public glWrap wrapT = glWrap.REPEAT; - - // empty schemas - public object extensions; - public object extras; - public string name; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.Key("magFilter"); f.Value((int)magFilter); - f.Key("minFilter"); f.Value((int)minFilter); - f.Key("wrapS"); f.Value((int)wrapS); - f.Key("wrapT"); f.Value((int)wrapT); - } - } - - [Serializable] - public class glTFImage : JsonSerializableBase - { - public string name; - public string uri; - - [JsonSchema(Dependencies = new string[] { "mimeType" }, Minimum = 0)] - public int bufferView; - - [JsonSchema(EnumValues = new object[] { "image/jpeg", "image/png" }, EnumSerializationType =EnumSerializationType.AsString)] - public string mimeType; - - public string GetExt() - { - switch (mimeType) - { - case "image/png": - return ".png"; - - case "image/jpeg": - return ".jpg"; - - default: - if (uri.StartsWith("data:image/jpeg;")) - { - return ".jpg"; - } - else if (uri.StartsWith("data:image/png;")) - { - return ".png"; - } - else - { - return Path.GetExtension(uri).ToLower(); - } - } - } - - // empty schemas - public object extensions; - public object extras; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => name); - if (!string.IsNullOrEmpty(uri)) - { - f.KeyValue(() => uri); - } - else - { - f.KeyValue(() => bufferView); - f.KeyValue(() => mimeType); - } - } - } - - [Serializable] - public class glTFTexture : JsonSerializableBase - { - [JsonSchema(Minimum = 0)] - public int sampler; - - [JsonSchema(Minimum = 0)] - public int source; - - // empty schemas - public object extensions; - public object extras; - public string name; - - protected override void SerializeMembers(GLTFJsonFormatter f) - { - f.KeyValue(() => sampler); - f.KeyValue(() => source); - } - } -} +using System; +using System.IO; +using UniJSON; + +namespace UniGLTF +{ + [Serializable] + public class glTFTextureSampler : JsonSerializableBase + { + [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, + EnumExcludes = new object[] { + glFilter.NONE, + glFilter.NEAREST_MIPMAP_NEAREST, + glFilter.LINEAR_MIPMAP_NEAREST, + glFilter.NEAREST_MIPMAP_LINEAR, + glFilter.LINEAR_MIPMAP_LINEAR, + })] + public glFilter magFilter = glFilter.NEAREST; + + [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, + EnumExcludes = new object[] { glFilter.NONE })] + public glFilter minFilter = glFilter.NEAREST; + + [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, + EnumExcludes = new object[] { glWrap.NONE })] + public glWrap wrapS = glWrap.REPEAT; + + [JsonSchema(EnumSerializationType = EnumSerializationType.AsInt, + EnumExcludes = new object[] { glWrap.NONE })] + public glWrap wrapT = glWrap.REPEAT; + + // empty schemas + public object extensions; + public object extras; + public string name; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.Key("magFilter"); f.Value((int)magFilter); + f.Key("minFilter"); f.Value((int)minFilter); + f.Key("wrapS"); f.Value((int)wrapS); + f.Key("wrapT"); f.Value((int)wrapT); + } + } + + [Serializable] + public class glTFImage : JsonSerializableBase + { + public string name; + public string uri; + + [JsonSchema(Dependencies = new string[] { "mimeType" }, Minimum = 0)] + public int bufferView; + + [JsonSchema(EnumValues = new object[] { "image/jpeg", "image/png" }, EnumSerializationType =EnumSerializationType.AsString)] + public string mimeType; + + public string GetExt() + { + switch (mimeType) + { + case "image/png": + return ".png"; + + case "image/jpeg": + return ".jpg"; + + default: + if (uri.StartsWith("data:image/jpeg;")) + { + return ".jpg"; + } + else if (uri.StartsWith("data:image/png;")) + { + return ".png"; + } + else + { + return Path.GetExtension(uri).ToLower(); + } + } + } + + // empty schemas + public object extensions; + public object extras; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => name); + if (!string.IsNullOrEmpty(uri)) + { + f.KeyValue(() => uri); + } + else + { + f.KeyValue(() => bufferView); + f.KeyValue(() => mimeType); + } + } + } + + [Serializable] + public class glTFTexture : JsonSerializableBase + { + [JsonSchema(Minimum = 0)] + public int sampler; + + [JsonSchema(Minimum = 0)] + public int source; + + // empty schemas + public object extensions; + public object extras; + public string name; + + protected override void SerializeMembers(GLTFJsonFormatter f) + { + f.KeyValue(() => sampler); + f.KeyValue(() => source); + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glTFTexture.cs.meta b/UniGLTF/Scripts/Format/glTFTexture.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glTFTexture.cs.meta rename to UniGLTF/Scripts/Format/glTFTexture.cs.meta diff --git a/UniGLTF/Core/Scripts/Format/glbTypes.cs b/UniGLTF/Scripts/Format/glbTypes.cs similarity index 96% rename from UniGLTF/Core/Scripts/Format/glbTypes.cs rename to UniGLTF/Scripts/Format/glbTypes.cs index 74ae03374..088f4c3d6 100644 --- a/UniGLTF/Core/Scripts/Format/glbTypes.cs +++ b/UniGLTF/Scripts/Format/glbTypes.cs @@ -1,142 +1,142 @@ -using System; -using System.IO; -using System.Text; - -namespace UniGLTF -{ - public enum GlbChunkType : UInt32 - { - JSON = 0x4E4F534A, - BIN = 0x004E4942, - } - - public struct GlbHeader - { - public static void WriteTo(Stream s) - { - s.WriteByte((Byte)'g'); - s.WriteByte((Byte)'l'); - s.WriteByte((Byte)'T'); - s.WriteByte((Byte)'F'); - var bytes = BitConverter.GetBytes((UInt32)2); - s.Write(bytes, 0, bytes.Length); - } - } - - public struct GlbChunk - { - public GlbChunkType ChunkType; - public ArraySegment Bytes; - - public GlbChunk(string json) : this( - GlbChunkType.JSON, - new ArraySegment(Encoding.UTF8.GetBytes(json)) - ) - { - } - - public GlbChunk(ArraySegment bytes) : this( - GlbChunkType.BIN, - bytes - ) - { - } - - public GlbChunk(GlbChunkType type, ArraySegment bytes) - { - ChunkType = type; - Bytes = bytes; - } - - byte GetPaddingByte() - { - // chunk type - switch (ChunkType) - { - case GlbChunkType.JSON: - return 0x20; - - case GlbChunkType.BIN: - return 0x00; - - default: - throw new Exception("unknown chunk type: " + ChunkType); - } - } - - public int WriteTo(Stream s) - { - // padding - var paddingValue = Bytes.Count % 4; - var padding = (paddingValue > 0) ? 4 - paddingValue : 0; - - // size - var bytes = BitConverter.GetBytes((int)(Bytes.Count + padding)); - s.Write(bytes, 0, bytes.Length); - - // chunk type - switch (ChunkType) - { - case GlbChunkType.JSON: - s.WriteByte((byte)'J'); - s.WriteByte((byte)'S'); - s.WriteByte((byte)'O'); - s.WriteByte((byte)'N'); - break; - - case GlbChunkType.BIN: - s.WriteByte((byte)'B'); - s.WriteByte((byte)'I'); - s.WriteByte((byte)'N'); - s.WriteByte((byte)0); - break; - - default: - throw new Exception("unknown chunk type: " + ChunkType); - } - - // body - s.Write(Bytes.Array, Bytes.Offset, Bytes.Count); - - // 4byte align - var pad = GetPaddingByte(); - for(int i=0; i body) - { - using (var s = new MemoryStream()) - { - GlbHeader.WriteTo(s); - - var pos = s.Position; - s.Position += 4; // skip total size - - int size = 12; - - { - var chunk = new GlbChunk(json); - size += chunk.WriteTo(s); - } - { - var chunk = new GlbChunk(body); - size += chunk.WriteTo(s); - } - - s.Position = pos; - var bytes = BitConverter.GetBytes(size); - s.Write(bytes, 0, bytes.Length); - - return s.ToArray(); - } - } - } -} +using System; +using System.IO; +using System.Text; + +namespace UniGLTF +{ + public enum GlbChunkType : UInt32 + { + JSON = 0x4E4F534A, + BIN = 0x004E4942, + } + + public struct GlbHeader + { + public static void WriteTo(Stream s) + { + s.WriteByte((Byte)'g'); + s.WriteByte((Byte)'l'); + s.WriteByte((Byte)'T'); + s.WriteByte((Byte)'F'); + var bytes = BitConverter.GetBytes((UInt32)2); + s.Write(bytes, 0, bytes.Length); + } + } + + public struct GlbChunk + { + public GlbChunkType ChunkType; + public ArraySegment Bytes; + + public GlbChunk(string json) : this( + GlbChunkType.JSON, + new ArraySegment(Encoding.UTF8.GetBytes(json)) + ) + { + } + + public GlbChunk(ArraySegment bytes) : this( + GlbChunkType.BIN, + bytes + ) + { + } + + public GlbChunk(GlbChunkType type, ArraySegment bytes) + { + ChunkType = type; + Bytes = bytes; + } + + byte GetPaddingByte() + { + // chunk type + switch (ChunkType) + { + case GlbChunkType.JSON: + return 0x20; + + case GlbChunkType.BIN: + return 0x00; + + default: + throw new Exception("unknown chunk type: " + ChunkType); + } + } + + public int WriteTo(Stream s) + { + // padding + var paddingValue = Bytes.Count % 4; + var padding = (paddingValue > 0) ? 4 - paddingValue : 0; + + // size + var bytes = BitConverter.GetBytes((int)(Bytes.Count + padding)); + s.Write(bytes, 0, bytes.Length); + + // chunk type + switch (ChunkType) + { + case GlbChunkType.JSON: + s.WriteByte((byte)'J'); + s.WriteByte((byte)'S'); + s.WriteByte((byte)'O'); + s.WriteByte((byte)'N'); + break; + + case GlbChunkType.BIN: + s.WriteByte((byte)'B'); + s.WriteByte((byte)'I'); + s.WriteByte((byte)'N'); + s.WriteByte((byte)0); + break; + + default: + throw new Exception("unknown chunk type: " + ChunkType); + } + + // body + s.Write(Bytes.Array, Bytes.Offset, Bytes.Count); + + // 4byte align + var pad = GetPaddingByte(); + for(int i=0; i body) + { + using (var s = new MemoryStream()) + { + GlbHeader.WriteTo(s); + + var pos = s.Position; + s.Position += 4; // skip total size + + int size = 12; + + { + var chunk = new GlbChunk(json); + size += chunk.WriteTo(s); + } + { + var chunk = new GlbChunk(body); + size += chunk.WriteTo(s); + } + + s.Position = pos; + var bytes = BitConverter.GetBytes(size); + s.Write(bytes, 0, bytes.Length); + + return s.ToArray(); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/Format/glbTypes.cs.meta b/UniGLTF/Scripts/Format/glbTypes.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/Format/glbTypes.cs.meta rename to UniGLTF/Scripts/Format/glbTypes.cs.meta diff --git a/UniGLTF/Core/Scripts/IO.meta b/UniGLTF/Scripts/IO.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO.meta rename to UniGLTF/Scripts/IO.meta diff --git a/UniGLTF/Core/Scripts/IO/AnimationCurveData.cs b/UniGLTF/Scripts/IO/AnimationCurveData.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/AnimationCurveData.cs rename to UniGLTF/Scripts/IO/AnimationCurveData.cs index 7b31e2bc2..cb082288b 100644 --- a/UniGLTF/Core/Scripts/IO/AnimationCurveData.cs +++ b/UniGLTF/Scripts/IO/AnimationCurveData.cs @@ -1,121 +1,121 @@ -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - class AnimationCurveData - { -#if UNITY_EDITOR - public AnimationUtility.TangentMode TangentMode { get; private set; } - public glTFAnimationTarget.AnimationPropertys AnimationProperty { get; private set; } - public int SamplerIndex { get; private set; } - public int ElementCount { get; private set; } - public readonly List Keyframes = new List(); - - public AnimationCurveData(AnimationUtility.TangentMode tangentMode, glTFAnimationTarget.AnimationPropertys property, int samplerIndex, int elementCount) - { - TangentMode = tangentMode; - AnimationProperty = property; - SamplerIndex = samplerIndex; - ElementCount = elementCount; - } - - public string GetInterpolation() - { - switch (TangentMode) - { - case AnimationUtility.TangentMode.Linear: - return glTFAnimationTarget.Interpolations.LINEAR.ToString(); - case AnimationUtility.TangentMode.Constant: - return glTFAnimationTarget.Interpolations.STEP.ToString(); - default: - return glTFAnimationTarget.Interpolations.LINEAR.ToString(); - } - } - - /// - /// キーフレームのデータを入力する - /// - /// - /// - /// - public void SetKeyframeData(float time, float value, int valueOffset) - { - var existKeyframe = Keyframes.FirstOrDefault(x => x.Time == time); - if (existKeyframe != null) - { - existKeyframe.SetValue(value, valueOffset); - } - else - { - var newKeyframe = GetKeyframeData(AnimationProperty, ElementCount); - newKeyframe.Time = time; - newKeyframe.SetValue(value, valueOffset); - Keyframes.Add(newKeyframe); - } - } - - /// - /// キー情報がなかった要素に対して直前のキーの値を入力する - /// - public void RecountEmptyKeyframe() - { - if (Keyframes.Count == 0) - { - return; - } - - Keyframes.Sort((x, y) => (x.Time < y.Time) ? -1 : 1); - - for (int i = 1; i < Keyframes.Count; i++) - { - var current = Keyframes[i]; - var last = Keyframes[i - 1]; - for (int j = 0; j < current.EnterValues.Length; j++) - { - if (!current.EnterValues[j]) - { - Keyframes[i].SetValue(last.Values[j], j); - } - } - - } - } - - /// - /// アニメーションプロパティに対応したキーフレームを挿入する - /// - /// - /// - private static AnimationKeyframeData GetKeyframeData(glTFAnimationTarget.AnimationPropertys property, int elementCount) - { - switch (property) - { - case glTFAnimationTarget.AnimationPropertys.Translation: - return new AnimationKeyframeData(elementCount, (values) => - { - var temp = new Vector3(values[0], values[1], values[2]); - return temp.ReverseZ().ToArray(); - }); - case glTFAnimationTarget.AnimationPropertys.Rotation: - return new AnimationKeyframeData(elementCount, (values) => - { - var temp = new Quaternion(values[0], values[1], values[2], values[3]); - return temp.ReverseZ().ToArray(); - }); - case glTFAnimationTarget.AnimationPropertys.Scale: - return new AnimationKeyframeData(elementCount, null); - case glTFAnimationTarget.AnimationPropertys.BlendShape: - return new AnimationKeyframeData(elementCount, null); - default: - return null; - } - } -#endif - } +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + class AnimationCurveData + { +#if UNITY_EDITOR + public AnimationUtility.TangentMode TangentMode { get; private set; } + public glTFAnimationTarget.AnimationPropertys AnimationProperty { get; private set; } + public int SamplerIndex { get; private set; } + public int ElementCount { get; private set; } + public readonly List Keyframes = new List(); + + public AnimationCurveData(AnimationUtility.TangentMode tangentMode, glTFAnimationTarget.AnimationPropertys property, int samplerIndex, int elementCount) + { + TangentMode = tangentMode; + AnimationProperty = property; + SamplerIndex = samplerIndex; + ElementCount = elementCount; + } + + public string GetInterpolation() + { + switch (TangentMode) + { + case AnimationUtility.TangentMode.Linear: + return glTFAnimationTarget.Interpolations.LINEAR.ToString(); + case AnimationUtility.TangentMode.Constant: + return glTFAnimationTarget.Interpolations.STEP.ToString(); + default: + return glTFAnimationTarget.Interpolations.LINEAR.ToString(); + } + } + + /// + /// キーフレームのデータを入力する + /// + /// + /// + /// + public void SetKeyframeData(float time, float value, int valueOffset) + { + var existKeyframe = Keyframes.FirstOrDefault(x => x.Time == time); + if (existKeyframe != null) + { + existKeyframe.SetValue(value, valueOffset); + } + else + { + var newKeyframe = GetKeyframeData(AnimationProperty, ElementCount); + newKeyframe.Time = time; + newKeyframe.SetValue(value, valueOffset); + Keyframes.Add(newKeyframe); + } + } + + /// + /// キー情報がなかった要素に対して直前のキーの値を入力する + /// + public void RecountEmptyKeyframe() + { + if (Keyframes.Count == 0) + { + return; + } + + Keyframes.Sort((x, y) => (x.Time < y.Time) ? -1 : 1); + + for (int i = 1; i < Keyframes.Count; i++) + { + var current = Keyframes[i]; + var last = Keyframes[i - 1]; + for (int j = 0; j < current.EnterValues.Length; j++) + { + if (!current.EnterValues[j]) + { + Keyframes[i].SetValue(last.Values[j], j); + } + } + + } + } + + /// + /// アニメーションプロパティに対応したキーフレームを挿入する + /// + /// + /// + private static AnimationKeyframeData GetKeyframeData(glTFAnimationTarget.AnimationPropertys property, int elementCount) + { + switch (property) + { + case glTFAnimationTarget.AnimationPropertys.Translation: + return new AnimationKeyframeData(elementCount, (values) => + { + var temp = new Vector3(values[0], values[1], values[2]); + return temp.ReverseZ().ToArray(); + }); + case glTFAnimationTarget.AnimationPropertys.Rotation: + return new AnimationKeyframeData(elementCount, (values) => + { + var temp = new Quaternion(values[0], values[1], values[2], values[3]); + return temp.ReverseZ().ToArray(); + }); + case glTFAnimationTarget.AnimationPropertys.Scale: + return new AnimationKeyframeData(elementCount, null); + case glTFAnimationTarget.AnimationPropertys.BlendShape: + return new AnimationKeyframeData(elementCount, null); + default: + return null; + } + } +#endif + } } \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/AnimationCurveData.cs.meta b/UniGLTF/Scripts/IO/AnimationCurveData.cs.meta similarity index 71% rename from UniGLTF/Core/Scripts/IO/AnimationCurveData.cs.meta rename to UniGLTF/Scripts/IO/AnimationCurveData.cs.meta index 1efa99190..a6b2101b9 100644 --- a/UniGLTF/Core/Scripts/IO/AnimationCurveData.cs.meta +++ b/UniGLTF/Scripts/IO/AnimationCurveData.cs.meta @@ -1,3 +1,3 @@ -fileFormatVersion: 2 -guid: 1af21722605d44f58deebfcfca642b32 +fileFormatVersion: 2 +guid: 1af21722605d44f58deebfcfca642b32 timeCreated: 1537442711 \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/AnimationExporter.cs b/UniGLTF/Scripts/IO/AnimationExporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/AnimationExporter.cs rename to UniGLTF/Scripts/IO/AnimationExporter.cs index fc52ad963..b3cda06c0 100644 --- a/UniGLTF/Core/Scripts/IO/AnimationExporter.cs +++ b/UniGLTF/Scripts/IO/AnimationExporter.cs @@ -1,222 +1,222 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - - public static class AnimationExporter - { - public class InputOutputValues - { - public float[] Input; - public float[] Output; - } - - public class AnimationWithSampleCurves - { - public glTFAnimation Animation; - public Dictionary SamplerMap = new Dictionary(); - } - -#if UNITY_EDITOR - public static List GetAnimationClips(Animation animation) - { - var clips = new List(); - foreach (AnimationState state in animation) - { - clips.Add(state.clip); - } - return clips; - } - - public static List GetAnimationClips(Animator animator) - { - var clips = new List(); - - RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController; - UnityEditor.Animations.AnimatorController animationController = runtimeAnimatorController as UnityEditor.Animations.AnimatorController; - - if (animationController == null) - { - return clips; - } - - foreach (var layer in animationController.layers) - { - foreach (var state in layer.stateMachine.states) - { - clips.Add(state.state.motion as AnimationClip); - } - } - return clips; - } - - static int GetNodeIndex(Transform root, List nodes, string path) - { - var descendant = root.GetFromPath(path); - return nodes.IndexOf(descendant); - } - - public static glTFAnimationTarget.AnimationPropertys PropertyToTarget(string property) - { - if (property.StartsWith("m_LocalPosition.")) - { - return glTFAnimationTarget.AnimationPropertys.Translation; - } - else if (property.StartsWith("localEulerAnglesRaw.")) - { - return glTFAnimationTarget.AnimationPropertys.EulerRotation; - } - else if (property.StartsWith("m_LocalRotation.")) - { - return glTFAnimationTarget.AnimationPropertys.Rotation; - } - else if (property.StartsWith("m_LocalScale.")) - { - return glTFAnimationTarget.AnimationPropertys.Scale; - } - else if (property.StartsWith("blendShape.")) - { - return glTFAnimationTarget.AnimationPropertys.BlendShape; - } - else - { - return glTFAnimationTarget.AnimationPropertys.NotImplemented; - } - } - - public static int GetElementOffset(string property) - { - if (property.EndsWith(".x")) - { - return 0; - } - if (property.EndsWith(".y") || property.StartsWith("blendShape.")) - { - return 1; - } - if (property.EndsWith(".z")) - { - return 2; - } - if (property.EndsWith(".w")) - { - return 3; - } - else - { - throw new NotImplementedException(); - } - } - - public static AnimationWithSampleCurves Export(AnimationClip clip, Transform root, List nodes) - { - var animation = new AnimationWithSampleCurves - { - Animation = new glTFAnimation(), - }; - -#if UNITY_5_6_OR_NEWER - List curveDatas = new List(); - - foreach (var binding in AnimationUtility.GetCurveBindings(clip)) - { - var curve = AnimationUtility.GetEditorCurve(clip, binding); - - var property = AnimationExporter.PropertyToTarget(binding.propertyName); - if (property == glTFAnimationTarget.AnimationPropertys.NotImplemented) - { - Debug.LogWarning("Not Implemented keyframe property : " + binding.propertyName); - continue; - } - if (property == glTFAnimationTarget.AnimationPropertys.EulerRotation) - { - Debug.LogWarning("Interpolation setting of AnimationClip should be Quaternion"); - continue; - } - - var nodeIndex = GetNodeIndex(root, nodes, binding.path); - var samplerIndex = animation.Animation.AddChannelAndGetSampler(nodeIndex, property); - var elementCount = 0; - if (property == glTFAnimationTarget.AnimationPropertys.BlendShape) - { - var mesh = nodes[nodeIndex].GetComponent().sharedMesh; - elementCount = mesh.blendShapeCount; - } - else - { - elementCount = glTFAnimationTarget.GetElementCount(property); - } - - // 同一のsamplerIndexが割り当てられているcurveDataがある場合はそれを使用し、無ければ作る - var curveData = curveDatas.FirstOrDefault(x => x.SamplerIndex == samplerIndex); - if (curveData == null) - { - curveData = new AnimationCurveData(AnimationUtility.GetKeyRightTangentMode(curve, 0), property, samplerIndex, elementCount); - curveDatas.Add(curveData); - } - - // 全てのキーフレームを回収 - int elementOffset = 0; - float valueFactor = 1.0f; - if (property == glTFAnimationTarget.AnimationPropertys.BlendShape) - { - var mesh = nodes[nodeIndex].GetComponent().sharedMesh; - var blendShapeName = binding.propertyName.Replace("blendShape.", ""); - elementOffset = mesh.GetBlendShapeIndex(blendShapeName); - valueFactor = 0.01f; - } - else - { - elementOffset = AnimationExporter.GetElementOffset(binding.propertyName); - } - - if (elementOffset >= 0 && elementOffset < elementCount) - { - for (int i = 0; i < curve.keys.Length; i++) - { - curveData.SetKeyframeData(curve.keys[i].time, curve.keys[i].value * valueFactor, elementOffset); - } - } - } - - //キー挿入 - foreach (var curve in curveDatas) - { - if (curve.Keyframes.Count == 0) - continue; - - curve.RecountEmptyKeyframe(); - - var elementNum = curve.Keyframes.First().Values.Length; - var values = default(InputOutputValues); - if (!animation.SamplerMap.TryGetValue(curve.SamplerIndex, out values)) - { - values = new InputOutputValues(); - values.Input = new float[curve.Keyframes.Count]; - values.Output = new float[curve.Keyframes.Count * elementNum]; - animation.SamplerMap[curve.SamplerIndex] = values; - animation.Animation.samplers[curve.SamplerIndex].interpolation = curve.GetInterpolation(); - } - - int keyframeIndex = 0; - foreach (var keyframe in curve.Keyframes) - { - values.Input[keyframeIndex] = keyframe.Time; - Buffer.BlockCopy(keyframe.GetRightHandCoordinate(), 0, values.Output, keyframeIndex * elementNum * sizeof(float), elementNum * sizeof(float)); - keyframeIndex++; - } - } -#endif - - return animation; - } -#endif - } +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + + public static class AnimationExporter + { + public class InputOutputValues + { + public float[] Input; + public float[] Output; + } + + public class AnimationWithSampleCurves + { + public glTFAnimation Animation; + public Dictionary SamplerMap = new Dictionary(); + } + +#if UNITY_EDITOR + public static List GetAnimationClips(Animation animation) + { + var clips = new List(); + foreach (AnimationState state in animation) + { + clips.Add(state.clip); + } + return clips; + } + + public static List GetAnimationClips(Animator animator) + { + var clips = new List(); + + RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController; + UnityEditor.Animations.AnimatorController animationController = runtimeAnimatorController as UnityEditor.Animations.AnimatorController; + + if (animationController == null) + { + return clips; + } + + foreach (var layer in animationController.layers) + { + foreach (var state in layer.stateMachine.states) + { + clips.Add(state.state.motion as AnimationClip); + } + } + return clips; + } + + static int GetNodeIndex(Transform root, List nodes, string path) + { + var descendant = root.GetFromPath(path); + return nodes.IndexOf(descendant); + } + + public static glTFAnimationTarget.AnimationPropertys PropertyToTarget(string property) + { + if (property.StartsWith("m_LocalPosition.")) + { + return glTFAnimationTarget.AnimationPropertys.Translation; + } + else if (property.StartsWith("localEulerAnglesRaw.")) + { + return glTFAnimationTarget.AnimationPropertys.EulerRotation; + } + else if (property.StartsWith("m_LocalRotation.")) + { + return glTFAnimationTarget.AnimationPropertys.Rotation; + } + else if (property.StartsWith("m_LocalScale.")) + { + return glTFAnimationTarget.AnimationPropertys.Scale; + } + else if (property.StartsWith("blendShape.")) + { + return glTFAnimationTarget.AnimationPropertys.BlendShape; + } + else + { + return glTFAnimationTarget.AnimationPropertys.NotImplemented; + } + } + + public static int GetElementOffset(string property) + { + if (property.EndsWith(".x")) + { + return 0; + } + if (property.EndsWith(".y") || property.StartsWith("blendShape.")) + { + return 1; + } + if (property.EndsWith(".z")) + { + return 2; + } + if (property.EndsWith(".w")) + { + return 3; + } + else + { + throw new NotImplementedException(); + } + } + + public static AnimationWithSampleCurves Export(AnimationClip clip, Transform root, List nodes) + { + var animation = new AnimationWithSampleCurves + { + Animation = new glTFAnimation(), + }; + +#if UNITY_5_6_OR_NEWER + List curveDatas = new List(); + + foreach (var binding in AnimationUtility.GetCurveBindings(clip)) + { + var curve = AnimationUtility.GetEditorCurve(clip, binding); + + var property = AnimationExporter.PropertyToTarget(binding.propertyName); + if (property == glTFAnimationTarget.AnimationPropertys.NotImplemented) + { + Debug.LogWarning("Not Implemented keyframe property : " + binding.propertyName); + continue; + } + if (property == glTFAnimationTarget.AnimationPropertys.EulerRotation) + { + Debug.LogWarning("Interpolation setting of AnimationClip should be Quaternion"); + continue; + } + + var nodeIndex = GetNodeIndex(root, nodes, binding.path); + var samplerIndex = animation.Animation.AddChannelAndGetSampler(nodeIndex, property); + var elementCount = 0; + if (property == glTFAnimationTarget.AnimationPropertys.BlendShape) + { + var mesh = nodes[nodeIndex].GetComponent().sharedMesh; + elementCount = mesh.blendShapeCount; + } + else + { + elementCount = glTFAnimationTarget.GetElementCount(property); + } + + // 同一のsamplerIndexが割り当てられているcurveDataがある場合はそれを使用し、無ければ作る + var curveData = curveDatas.FirstOrDefault(x => x.SamplerIndex == samplerIndex); + if (curveData == null) + { + curveData = new AnimationCurveData(AnimationUtility.GetKeyRightTangentMode(curve, 0), property, samplerIndex, elementCount); + curveDatas.Add(curveData); + } + + // 全てのキーフレームを回収 + int elementOffset = 0; + float valueFactor = 1.0f; + if (property == glTFAnimationTarget.AnimationPropertys.BlendShape) + { + var mesh = nodes[nodeIndex].GetComponent().sharedMesh; + var blendShapeName = binding.propertyName.Replace("blendShape.", ""); + elementOffset = mesh.GetBlendShapeIndex(blendShapeName); + valueFactor = 0.01f; + } + else + { + elementOffset = AnimationExporter.GetElementOffset(binding.propertyName); + } + + if (elementOffset >= 0 && elementOffset < elementCount) + { + for (int i = 0; i < curve.keys.Length; i++) + { + curveData.SetKeyframeData(curve.keys[i].time, curve.keys[i].value * valueFactor, elementOffset); + } + } + } + + //キー挿入 + foreach (var curve in curveDatas) + { + if (curve.Keyframes.Count == 0) + continue; + + curve.RecountEmptyKeyframe(); + + var elementNum = curve.Keyframes.First().Values.Length; + var values = default(InputOutputValues); + if (!animation.SamplerMap.TryGetValue(curve.SamplerIndex, out values)) + { + values = new InputOutputValues(); + values.Input = new float[curve.Keyframes.Count]; + values.Output = new float[curve.Keyframes.Count * elementNum]; + animation.SamplerMap[curve.SamplerIndex] = values; + animation.Animation.samplers[curve.SamplerIndex].interpolation = curve.GetInterpolation(); + } + + int keyframeIndex = 0; + foreach (var keyframe in curve.Keyframes) + { + values.Input[keyframeIndex] = keyframe.Time; + Buffer.BlockCopy(keyframe.GetRightHandCoordinate(), 0, values.Output, keyframeIndex * elementNum * sizeof(float), elementNum * sizeof(float)); + keyframeIndex++; + } + } +#endif + + return animation; + } +#endif + } } \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/AnimationExporter.cs.meta b/UniGLTF/Scripts/IO/AnimationExporter.cs.meta similarity index 71% rename from UniGLTF/Core/Scripts/IO/AnimationExporter.cs.meta rename to UniGLTF/Scripts/IO/AnimationExporter.cs.meta index d92b7028c..6603cc132 100644 --- a/UniGLTF/Core/Scripts/IO/AnimationExporter.cs.meta +++ b/UniGLTF/Scripts/IO/AnimationExporter.cs.meta @@ -1,3 +1,3 @@ -fileFormatVersion: 2 -guid: 015ae41bf6cb4428b8257ead79772908 +fileFormatVersion: 2 +guid: 015ae41bf6cb4428b8257ead79772908 timeCreated: 1537443293 \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/AnimationImporter.cs b/UniGLTF/Scripts/IO/AnimationImporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/AnimationImporter.cs rename to UniGLTF/Scripts/IO/AnimationImporter.cs index e792cfc76..cab07ee3d 100644 --- a/UniGLTF/Core/Scripts/IO/AnimationImporter.cs +++ b/UniGLTF/Scripts/IO/AnimationImporter.cs @@ -1,330 +1,330 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEngine; - -namespace UniGLTF -{ - public static class AnimationImporter - { - private enum TangentMode - { - Linear, - Constant, - Cubicspline - } - - private static TangentMode GetTangentMode(string interpolation) - { - if (interpolation == glTFAnimationTarget.Interpolations.LINEAR.ToString()) - { - return TangentMode.Linear; - } - else if (interpolation == glTFAnimationTarget.Interpolations.STEP.ToString()) - { - return TangentMode.Constant; - } - else if (interpolation == glTFAnimationTarget.Interpolations.CUBICSPLINE.ToString()) - { - return TangentMode.Cubicspline; - } - else - { - throw new NotImplementedException(); - } - } - - private static void CalculateTanget(List keyframes, int current) - { - int back = current - 1; - if (back < 0) - { - return; - } - if (current < keyframes.Count) - { - var rightTangent = (keyframes[current].value - keyframes[back].value) / (keyframes[current].time - keyframes[back].time); - keyframes[back] = new Keyframe(keyframes[back].time, keyframes[back].value, keyframes[back].inTangent, rightTangent); - - var leftTangent = (keyframes[back].value - keyframes[current].value) / (keyframes[back].time - keyframes[current].time); - keyframes[current] = new Keyframe(keyframes[current].time, keyframes[current].value, leftTangent, 0); - } - } - - public static Quaternion GetShortest(Quaternion last, Quaternion rot) - { - if (Quaternion.Dot(last, rot) > 0.0) - { - return rot; - } - else - { - return new Quaternion(-rot.x, -rot.y, -rot.z, -rot.w); - } - - } - - public delegate float[] ReverseZ(float[] current, float[] last); - public static void SetAnimationCurve( - AnimationClip targetClip, - string relativePath, - string[] propertyNames, - float[] input, - float[] output, - string interpolation, - Type curveType, - ReverseZ reverse) - { - var tangentMode = GetTangentMode(interpolation); - - var curveCount = propertyNames.Length; - AnimationCurve[] curves = new AnimationCurve[curveCount]; - List[] keyframes = new List[curveCount]; - - int elementNum = curveCount; - int inputIndex = 0; - //Quaternion用 - float[] last = new float[curveCount]; - if (last.Length == 4) - { - last[3] = 1.0f; - } - for (inputIndex = 0; inputIndex < input.Length; ++inputIndex) - { - var time = input[inputIndex]; - var outputIndex = 0; - if (tangentMode == TangentMode.Cubicspline) - { - outputIndex = inputIndex * elementNum * 3; - var value = new float[curveCount]; - for (int i = 0; i < value.Length; i++) - { - value[i] = output[outputIndex + elementNum + i]; - } - var reversed = reverse(value, last); - last = reversed; - for (int i = 0; i < keyframes.Length; i++) - { - if (keyframes[i] == null) - keyframes[i] = new List(); - keyframes[i].Add(new Keyframe( - time, - reversed[i], - output[outputIndex + i], - output[outputIndex + i + elementNum * 2])); - } - } - else - { - outputIndex = inputIndex * elementNum; - var value = new float[curveCount]; - for (int i = 0; i < value.Length; i++) - { - value[i] = output[outputIndex + i]; - } - var reversed = reverse(value, last); - last = reversed; - - for (int i = 0; i < keyframes.Length; i++) - { - if (keyframes[i] == null) - keyframes[i] = new List(); - if (tangentMode == TangentMode.Linear) - { - keyframes[i].Add(new Keyframe(time, reversed[i], 0, 0)); - if (keyframes[i].Count > 0) - { - CalculateTanget(keyframes[i], keyframes[i].Count - 1); - } - } - else if (tangentMode == TangentMode.Constant) - keyframes[i].Add(new Keyframe(time, reversed[i], 0, float.PositiveInfinity)); - } - } - } - - for (int i = 0; i < curves.Length; i++) - { - curves[i] = new AnimationCurve(); - for (int j = 0; j < keyframes[i].Count; j++) - { - curves[i].AddKey(keyframes[i][j]); - } - - targetClip.SetCurve(relativePath, curveType, propertyNames[i], curves[i]); - } - } - - public static List ImportAnimationClip(ImporterContext ctx) - { - List animasionClips = new List(); - for (int i = 0; i < ctx.GLTF.animations.Count; ++i) - { - var clip = new AnimationClip(); - clip.ClearCurves(); - clip.legacy = true; - clip.name = ctx.GLTF.animations[i].name; - if (string.IsNullOrEmpty(clip.name)) - { - clip.name = "legacy_" + i; - } - clip.wrapMode = WrapMode.Loop; - - var animation = ctx.GLTF.animations[i]; - if (string.IsNullOrEmpty(animation.name)) - { - animation.name = string.Format("animation:{0}", i); - } - - foreach (var channel in animation.channels) - { - var targetTransform = ctx.Nodes[channel.target.node]; - var relativePath = targetTransform.RelativePathFrom(ctx.Root.transform); - switch (channel.target.path) - { - case glTFAnimationTarget.PATH_TRANSLATION: - { - var sampler = animation.samplers[channel.sampler]; - var input = ctx.GLTF.GetArrayFromAccessor(sampler.input); - var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); - - AnimationImporter.SetAnimationCurve( - clip, - relativePath, - new string[] { "localPosition.x", "localPosition.y", "localPosition.z" }, - input, - output, - sampler.interpolation, - typeof(Transform), - (values, last) => - { - Vector3 temp = new Vector3(values[0], values[1], values[2]); - return temp.ReverseZ().ToArray(); - } - ); - } - break; - - case glTFAnimationTarget.PATH_ROTATION: - { - var sampler = animation.samplers[channel.sampler]; - var input = ctx.GLTF.GetArrayFromAccessor(sampler.input); - var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); - - AnimationImporter.SetAnimationCurve( - clip, - relativePath, - new string[] { "localRotation.x", "localRotation.y", "localRotation.z", "localRotation.w" }, - input, - output, - sampler.interpolation, - typeof(Transform), - (values, last) => - { - Quaternion currentQuaternion = new Quaternion(values[0], values[1], values[2], values[3]); - Quaternion lastQuaternion = new Quaternion(last[0], last[1], last[2], last[3]); - return AnimationImporter.GetShortest(lastQuaternion, currentQuaternion.ReverseZ()).ToArray(); - } - ); - - clip.EnsureQuaternionContinuity(); - } - break; - - case glTFAnimationTarget.PATH_SCALE: - { - var sampler = animation.samplers[channel.sampler]; - var input = ctx.GLTF.GetArrayFromAccessor(sampler.input); - var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); - - AnimationImporter.SetAnimationCurve( - clip, - relativePath, - new string[] { "localScale.x", "localScale.y", "localScale.z" }, - input, - output, - sampler.interpolation, - typeof(Transform), - (values, last) => values); - } - break; - - case glTFAnimationTarget.PATH_WEIGHT: - { - var node = ctx.GLTF.nodes[channel.target.node]; - var mesh = ctx.GLTF.meshes[node.mesh]; - //var primitive = mesh.primitives.FirstOrDefault(); - //var targets = primitive.targets; - - List blendShapeNames = new List(); - var transform = ctx.Nodes[channel.target.node]; - var skinnedMeshRenderer = transform.GetComponent(); - if (skinnedMeshRenderer == null) - { - continue; - } - - for (int j = 0; j < skinnedMeshRenderer.sharedMesh.blendShapeCount; j++) - { - blendShapeNames.Add(skinnedMeshRenderer.sharedMesh.GetBlendShapeName(j)); - } - - var keyNames = blendShapeNames - .Where(x => !string.IsNullOrEmpty(x)) - .Select(x => "blendShape." + x) - .ToArray(); - - var sampler = animation.samplers[channel.sampler]; - var input = ctx.GLTF.GetArrayFromAccessor(sampler.input); - var output = ctx.GLTF.GetArrayFromAccessor(sampler.output); - AnimationImporter.SetAnimationCurve( - clip, - relativePath, - keyNames, - input, - output, - sampler.interpolation, - typeof(SkinnedMeshRenderer), - (values, last) => - { - for (int j = 0; j < values.Length; j++) - { - values[j] *= 100.0f; - } - return values; - }); - - } - break; - - default: - Debug.LogWarningFormat("unknown path: {0}", channel.target.path); - break; - } - } - animasionClips.Add(clip); - } - - return animasionClips; - } - - public static void ImportAnimation(ImporterContext ctx) - { - // animation - if (ctx.GLTF.animations != null && ctx.GLTF.animations.Any()) - { - var animation = ctx.Root.AddComponent(); - ctx.AnimationClips = ImportAnimationClip(ctx); - foreach (var clip in ctx.AnimationClips) - { - animation.AddClip(clip, clip.name); - } - if (ctx.AnimationClips.Count > 0) - { - animation.clip = ctx.AnimationClips.First(); - } - } - } - - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; + +namespace UniGLTF +{ + public static class AnimationImporter + { + private enum TangentMode + { + Linear, + Constant, + Cubicspline + } + + private static TangentMode GetTangentMode(string interpolation) + { + if (interpolation == glTFAnimationTarget.Interpolations.LINEAR.ToString()) + { + return TangentMode.Linear; + } + else if (interpolation == glTFAnimationTarget.Interpolations.STEP.ToString()) + { + return TangentMode.Constant; + } + else if (interpolation == glTFAnimationTarget.Interpolations.CUBICSPLINE.ToString()) + { + return TangentMode.Cubicspline; + } + else + { + throw new NotImplementedException(); + } + } + + private static void CalculateTanget(List keyframes, int current) + { + int back = current - 1; + if (back < 0) + { + return; + } + if (current < keyframes.Count) + { + var rightTangent = (keyframes[current].value - keyframes[back].value) / (keyframes[current].time - keyframes[back].time); + keyframes[back] = new Keyframe(keyframes[back].time, keyframes[back].value, keyframes[back].inTangent, rightTangent); + + var leftTangent = (keyframes[back].value - keyframes[current].value) / (keyframes[back].time - keyframes[current].time); + keyframes[current] = new Keyframe(keyframes[current].time, keyframes[current].value, leftTangent, 0); + } + } + + public static Quaternion GetShortest(Quaternion last, Quaternion rot) + { + if (Quaternion.Dot(last, rot) > 0.0) + { + return rot; + } + else + { + return new Quaternion(-rot.x, -rot.y, -rot.z, -rot.w); + } + + } + + public delegate float[] ReverseZ(float[] current, float[] last); + public static void SetAnimationCurve( + AnimationClip targetClip, + string relativePath, + string[] propertyNames, + float[] input, + float[] output, + string interpolation, + Type curveType, + ReverseZ reverse) + { + var tangentMode = GetTangentMode(interpolation); + + var curveCount = propertyNames.Length; + AnimationCurve[] curves = new AnimationCurve[curveCount]; + List[] keyframes = new List[curveCount]; + + int elementNum = curveCount; + int inputIndex = 0; + //Quaternion用 + float[] last = new float[curveCount]; + if (last.Length == 4) + { + last[3] = 1.0f; + } + for (inputIndex = 0; inputIndex < input.Length; ++inputIndex) + { + var time = input[inputIndex]; + var outputIndex = 0; + if (tangentMode == TangentMode.Cubicspline) + { + outputIndex = inputIndex * elementNum * 3; + var value = new float[curveCount]; + for (int i = 0; i < value.Length; i++) + { + value[i] = output[outputIndex + elementNum + i]; + } + var reversed = reverse(value, last); + last = reversed; + for (int i = 0; i < keyframes.Length; i++) + { + if (keyframes[i] == null) + keyframes[i] = new List(); + keyframes[i].Add(new Keyframe( + time, + reversed[i], + output[outputIndex + i], + output[outputIndex + i + elementNum * 2])); + } + } + else + { + outputIndex = inputIndex * elementNum; + var value = new float[curveCount]; + for (int i = 0; i < value.Length; i++) + { + value[i] = output[outputIndex + i]; + } + var reversed = reverse(value, last); + last = reversed; + + for (int i = 0; i < keyframes.Length; i++) + { + if (keyframes[i] == null) + keyframes[i] = new List(); + if (tangentMode == TangentMode.Linear) + { + keyframes[i].Add(new Keyframe(time, reversed[i], 0, 0)); + if (keyframes[i].Count > 0) + { + CalculateTanget(keyframes[i], keyframes[i].Count - 1); + } + } + else if (tangentMode == TangentMode.Constant) + keyframes[i].Add(new Keyframe(time, reversed[i], 0, float.PositiveInfinity)); + } + } + } + + for (int i = 0; i < curves.Length; i++) + { + curves[i] = new AnimationCurve(); + for (int j = 0; j < keyframes[i].Count; j++) + { + curves[i].AddKey(keyframes[i][j]); + } + + targetClip.SetCurve(relativePath, curveType, propertyNames[i], curves[i]); + } + } + + public static List ImportAnimationClip(ImporterContext ctx) + { + List animasionClips = new List(); + for (int i = 0; i < ctx.GLTF.animations.Count; ++i) + { + var clip = new AnimationClip(); + clip.ClearCurves(); + clip.legacy = true; + clip.name = ctx.GLTF.animations[i].name; + if (string.IsNullOrEmpty(clip.name)) + { + clip.name = "legacy_" + i; + } + clip.wrapMode = WrapMode.Loop; + + var animation = ctx.GLTF.animations[i]; + if (string.IsNullOrEmpty(animation.name)) + { + animation.name = string.Format("animation:{0}", i); + } + + foreach (var channel in animation.channels) + { + var targetTransform = ctx.Nodes[channel.target.node]; + var relativePath = targetTransform.RelativePathFrom(ctx.Root.transform); + switch (channel.target.path) + { + case glTFAnimationTarget.PATH_TRANSLATION: + { + var sampler = animation.samplers[channel.sampler]; + var input = ctx.GLTF.GetArrayFromAccessor(sampler.input); + var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); + + AnimationImporter.SetAnimationCurve( + clip, + relativePath, + new string[] { "localPosition.x", "localPosition.y", "localPosition.z" }, + input, + output, + sampler.interpolation, + typeof(Transform), + (values, last) => + { + Vector3 temp = new Vector3(values[0], values[1], values[2]); + return temp.ReverseZ().ToArray(); + } + ); + } + break; + + case glTFAnimationTarget.PATH_ROTATION: + { + var sampler = animation.samplers[channel.sampler]; + var input = ctx.GLTF.GetArrayFromAccessor(sampler.input); + var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); + + AnimationImporter.SetAnimationCurve( + clip, + relativePath, + new string[] { "localRotation.x", "localRotation.y", "localRotation.z", "localRotation.w" }, + input, + output, + sampler.interpolation, + typeof(Transform), + (values, last) => + { + Quaternion currentQuaternion = new Quaternion(values[0], values[1], values[2], values[3]); + Quaternion lastQuaternion = new Quaternion(last[0], last[1], last[2], last[3]); + return AnimationImporter.GetShortest(lastQuaternion, currentQuaternion.ReverseZ()).ToArray(); + } + ); + + clip.EnsureQuaternionContinuity(); + } + break; + + case glTFAnimationTarget.PATH_SCALE: + { + var sampler = animation.samplers[channel.sampler]; + var input = ctx.GLTF.GetArrayFromAccessor(sampler.input); + var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); + + AnimationImporter.SetAnimationCurve( + clip, + relativePath, + new string[] { "localScale.x", "localScale.y", "localScale.z" }, + input, + output, + sampler.interpolation, + typeof(Transform), + (values, last) => values); + } + break; + + case glTFAnimationTarget.PATH_WEIGHT: + { + var node = ctx.GLTF.nodes[channel.target.node]; + var mesh = ctx.GLTF.meshes[node.mesh]; + //var primitive = mesh.primitives.FirstOrDefault(); + //var targets = primitive.targets; + + List blendShapeNames = new List(); + var transform = ctx.Nodes[channel.target.node]; + var skinnedMeshRenderer = transform.GetComponent(); + if (skinnedMeshRenderer == null) + { + continue; + } + + for (int j = 0; j < skinnedMeshRenderer.sharedMesh.blendShapeCount; j++) + { + blendShapeNames.Add(skinnedMeshRenderer.sharedMesh.GetBlendShapeName(j)); + } + + var keyNames = blendShapeNames + .Where(x => !string.IsNullOrEmpty(x)) + .Select(x => "blendShape." + x) + .ToArray(); + + var sampler = animation.samplers[channel.sampler]; + var input = ctx.GLTF.GetArrayFromAccessor(sampler.input); + var output = ctx.GLTF.GetArrayFromAccessor(sampler.output); + AnimationImporter.SetAnimationCurve( + clip, + relativePath, + keyNames, + input, + output, + sampler.interpolation, + typeof(SkinnedMeshRenderer), + (values, last) => + { + for (int j = 0; j < values.Length; j++) + { + values[j] *= 100.0f; + } + return values; + }); + + } + break; + + default: + Debug.LogWarningFormat("unknown path: {0}", channel.target.path); + break; + } + } + animasionClips.Add(clip); + } + + return animasionClips; + } + + public static void ImportAnimation(ImporterContext ctx) + { + // animation + if (ctx.GLTF.animations != null && ctx.GLTF.animations.Any()) + { + var animation = ctx.Root.AddComponent(); + ctx.AnimationClips = ImportAnimationClip(ctx); + foreach (var clip in ctx.AnimationClips) + { + animation.AddClip(clip, clip.name); + } + if (ctx.AnimationClips.Count > 0) + { + animation.clip = ctx.AnimationClips.First(); + } + } + } + + } +} diff --git a/UniGLTF/Core/Scripts/IO/AnimationImporter.cs.meta b/UniGLTF/Scripts/IO/AnimationImporter.cs.meta similarity index 71% rename from UniGLTF/Core/Scripts/IO/AnimationImporter.cs.meta rename to UniGLTF/Scripts/IO/AnimationImporter.cs.meta index 0b1497bed..8f83fec20 100644 --- a/UniGLTF/Core/Scripts/IO/AnimationImporter.cs.meta +++ b/UniGLTF/Scripts/IO/AnimationImporter.cs.meta @@ -1,3 +1,3 @@ -fileFormatVersion: 2 -guid: d602384685dd4f179350052013659720 +fileFormatVersion: 2 +guid: d602384685dd4f179350052013659720 timeCreated: 1537445972 \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/AnimationKeyframeData.cs b/UniGLTF/Scripts/IO/AnimationKeyframeData.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/AnimationKeyframeData.cs rename to UniGLTF/Scripts/IO/AnimationKeyframeData.cs index 9e5997963..1de683bf2 100644 --- a/UniGLTF/Core/Scripts/IO/AnimationKeyframeData.cs +++ b/UniGLTF/Scripts/IO/AnimationKeyframeData.cs @@ -1,54 +1,54 @@ -namespace UniGLTF -{ - class AnimationKeyframeData - { -#if UNITY_EDITOR - public float Time { get; set; } - public delegate float[] ConverterFunc(float[] values); - private ConverterFunc _converter; - private float[] _values; - public float[] Values - { - get { return _values; } - } - - private bool[] _enterValues; - public bool[] EnterValues - { - get { return _enterValues; } - } - - public AnimationKeyframeData(int elementCount, ConverterFunc converter) - { - _values = new float[elementCount]; - _enterValues = new bool[elementCount]; - for (int i = 0; i < _enterValues.Length; i++) - { - _enterValues[i] = false; - } - _converter = converter; - } - - public void SetValue(float src, int offset) - { - if (_values.Length > offset) - { - _values[offset] = src; - _enterValues[offset] = true; - } - } - - public virtual float[] GetRightHandCoordinate() - { - if (_converter != null) - { - return _converter(_values); - } - else - { - return _values; - } - } -#endif - } +namespace UniGLTF +{ + class AnimationKeyframeData + { +#if UNITY_EDITOR + public float Time { get; set; } + public delegate float[] ConverterFunc(float[] values); + private ConverterFunc _converter; + private float[] _values; + public float[] Values + { + get { return _values; } + } + + private bool[] _enterValues; + public bool[] EnterValues + { + get { return _enterValues; } + } + + public AnimationKeyframeData(int elementCount, ConverterFunc converter) + { + _values = new float[elementCount]; + _enterValues = new bool[elementCount]; + for (int i = 0; i < _enterValues.Length; i++) + { + _enterValues[i] = false; + } + _converter = converter; + } + + public void SetValue(float src, int offset) + { + if (_values.Length > offset) + { + _values[offset] = src; + _enterValues[offset] = true; + } + } + + public virtual float[] GetRightHandCoordinate() + { + if (_converter != null) + { + return _converter(_values); + } + else + { + return _values; + } + } +#endif + } } \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/AnimationKeyframeData.cs.meta b/UniGLTF/Scripts/IO/AnimationKeyframeData.cs.meta similarity index 71% rename from UniGLTF/Core/Scripts/IO/AnimationKeyframeData.cs.meta rename to UniGLTF/Scripts/IO/AnimationKeyframeData.cs.meta index 21154c77b..06d8ca4ad 100644 --- a/UniGLTF/Core/Scripts/IO/AnimationKeyframeData.cs.meta +++ b/UniGLTF/Scripts/IO/AnimationKeyframeData.cs.meta @@ -1,3 +1,3 @@ -fileFormatVersion: 2 -guid: e27ef4fb768e49f591c2bb5eadd3b19b +fileFormatVersion: 2 +guid: e27ef4fb768e49f591c2bb5eadd3b19b timeCreated: 1537442737 \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/BytesReader.cs b/UniGLTF/Scripts/IO/BytesReader.cs similarity index 95% rename from UniGLTF/Core/Scripts/IO/BytesReader.cs rename to UniGLTF/Scripts/IO/BytesReader.cs index f0bf32cb6..249c08671 100644 --- a/UniGLTF/Core/Scripts/IO/BytesReader.cs +++ b/UniGLTF/Scripts/IO/BytesReader.cs @@ -1,81 +1,81 @@ -using System; -using System.Runtime.InteropServices; -using System.Text; - - -namespace UniGLTF -{ - public class BytesReader - { - Byte[] m_bytes; - int m_pos; - - public BytesReader(Byte[] bytes, int pos=0) - { - m_bytes = bytes; - m_pos = pos; - } - - public string ReadString(int count, Encoding encoding) - { - var s = encoding.GetString(m_bytes, m_pos, count); - m_pos += count; - return s; - } - - public float ReadSingle() - { - var n = BitConverter.ToSingle(m_bytes, m_pos); - m_pos += 4; - return n; - } - - public byte ReadUInt8() - { - return m_bytes[m_pos++]; - } - - public UInt16 ReadUInt16() - { - var n = BitConverter.ToUInt16(m_bytes, m_pos); - m_pos += 2; - return n; - } - - public sbyte ReadInt8() - { - return (sbyte)m_bytes[m_pos++]; - } - - public Int16 ReadInt16() - { - var n = BitConverter.ToInt16(m_bytes, m_pos); - m_pos += 2; - return n; - } - - public int ReadInt32() - { - var n = BitConverter.ToInt32(m_bytes, m_pos); - m_pos += 4; - return n; - } - - public void ReadToArray(T[] dst) where T : struct - { - var size = new ArraySegment(m_bytes, m_pos, m_bytes.Length - m_pos).MarshalCoyTo(dst); - m_pos += size; - } - - public T ReadStruct() where T : struct - { - var size = Marshal.SizeOf(typeof(T)); - using (var pin = Pin.Create(new ArraySegment(m_bytes, m_pos, m_bytes.Length - m_pos))) - { - var s = (T)Marshal.PtrToStructure(pin.Ptr, typeof(T)); - m_pos += size; - return s; - } - } - } -} +using System; +using System.Runtime.InteropServices; +using System.Text; + + +namespace UniGLTF +{ + public class BytesReader + { + Byte[] m_bytes; + int m_pos; + + public BytesReader(Byte[] bytes, int pos=0) + { + m_bytes = bytes; + m_pos = pos; + } + + public string ReadString(int count, Encoding encoding) + { + var s = encoding.GetString(m_bytes, m_pos, count); + m_pos += count; + return s; + } + + public float ReadSingle() + { + var n = BitConverter.ToSingle(m_bytes, m_pos); + m_pos += 4; + return n; + } + + public byte ReadUInt8() + { + return m_bytes[m_pos++]; + } + + public UInt16 ReadUInt16() + { + var n = BitConverter.ToUInt16(m_bytes, m_pos); + m_pos += 2; + return n; + } + + public sbyte ReadInt8() + { + return (sbyte)m_bytes[m_pos++]; + } + + public Int16 ReadInt16() + { + var n = BitConverter.ToInt16(m_bytes, m_pos); + m_pos += 2; + return n; + } + + public int ReadInt32() + { + var n = BitConverter.ToInt32(m_bytes, m_pos); + m_pos += 4; + return n; + } + + public void ReadToArray(T[] dst) where T : struct + { + var size = new ArraySegment(m_bytes, m_pos, m_bytes.Length - m_pos).MarshalCoyTo(dst); + m_pos += size; + } + + public T ReadStruct() where T : struct + { + var size = Marshal.SizeOf(typeof(T)); + using (var pin = Pin.Create(new ArraySegment(m_bytes, m_pos, m_bytes.Length - m_pos))) + { + var s = (T)Marshal.PtrToStructure(pin.Ptr, typeof(T)); + m_pos += size; + return s; + } + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/BytesReader.cs.meta b/UniGLTF/Scripts/IO/BytesReader.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/BytesReader.cs.meta rename to UniGLTF/Scripts/IO/BytesReader.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/IStorage.cs b/UniGLTF/Scripts/IO/IStorage.cs similarity index 95% rename from UniGLTF/Core/Scripts/IO/IStorage.cs rename to UniGLTF/Scripts/IO/IStorage.cs index f61787eef..42cbc4fae 100644 --- a/UniGLTF/Core/Scripts/IO/IStorage.cs +++ b/UniGLTF/Scripts/IO/IStorage.cs @@ -1,74 +1,74 @@ -using System; -using System.IO; - - -namespace UniGLTF -{ - public interface IStorage - { - ArraySegment Get(string url); - - /// - /// Get original filepath if exists - /// - /// - /// - string GetPath(string url); - } - - public class SimpleStorage : IStorage - { - ArraySegment m_bytes; - - public SimpleStorage():this(new ArraySegment()) - { - } - - public SimpleStorage(ArraySegment bytes) - { - m_bytes = bytes; - } - - public ArraySegment Get(string url) - { - return m_bytes; - } - - public string GetPath(string url) - { - return null; - } - } - - public class FileSystemStorage : IStorage - { - string m_root; - - public FileSystemStorage(string root) - { - m_root = Path.GetFullPath(root); - } - - public ArraySegment Get(string url) - { - var bytes = - (url.StartsWith("data:")) - ? UriByteBuffer.ReadEmbeded(url) - : File.ReadAllBytes(Path.Combine(m_root, url)) - ; - return new ArraySegment(bytes); - } - - public string GetPath(string url) - { - if (url.StartsWith("data:")) - { - return null; - } - else - { - return Path.Combine(m_root, url).Replace("\\", "/"); - } - } - } -} +using System; +using System.IO; + + +namespace UniGLTF +{ + public interface IStorage + { + ArraySegment Get(string url); + + /// + /// Get original filepath if exists + /// + /// + /// + string GetPath(string url); + } + + public class SimpleStorage : IStorage + { + ArraySegment m_bytes; + + public SimpleStorage():this(new ArraySegment()) + { + } + + public SimpleStorage(ArraySegment bytes) + { + m_bytes = bytes; + } + + public ArraySegment Get(string url) + { + return m_bytes; + } + + public string GetPath(string url) + { + return null; + } + } + + public class FileSystemStorage : IStorage + { + string m_root; + + public FileSystemStorage(string root) + { + m_root = Path.GetFullPath(root); + } + + public ArraySegment Get(string url) + { + var bytes = + (url.StartsWith("data:")) + ? UriByteBuffer.ReadEmbeded(url) + : File.ReadAllBytes(Path.Combine(m_root, url)) + ; + return new ArraySegment(bytes); + } + + public string GetPath(string url) + { + if (url.StartsWith("data:")) + { + return null; + } + else + { + return Path.Combine(m_root, url).Replace("\\", "/"); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/IStorage.cs.meta b/UniGLTF/Scripts/IO/IStorage.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/IStorage.cs.meta rename to UniGLTF/Scripts/IO/IStorage.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/ImporterContext.cs b/UniGLTF/Scripts/IO/ImporterContext.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/ImporterContext.cs rename to UniGLTF/Scripts/IO/ImporterContext.cs index 24b4d41b8..0f4d3b4d9 100644 --- a/UniGLTF/Core/Scripts/IO/ImporterContext.cs +++ b/UniGLTF/Scripts/IO/ImporterContext.cs @@ -1,999 +1,999 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEngine; -using System.IO; -using System.Text; -using System.Collections; -using DepthFirstScheduler; -#if UNITY_EDITOR -using UnityEditor; -#endif -#if ((NET_4_6 || NET_STANDARD_2_0) && UNITY_2017_1_OR_NEWER) -using System.Threading.Tasks; -#endif - - -namespace UniGLTF -{ - /// - /// GLTF importer - /// - public class ImporterContext: IDisposable - { - #region MeasureTime - bool m_showSpeedLog -#if UNIGLTF_DEVELOP - = true -#endif - ; - public bool ShowSpeedLog - { - set { m_showSpeedLog = value; } - } - - public struct KeyElapsed - { - public string Key; - public TimeSpan Elapsed; - public KeyElapsed(string key, TimeSpan elapsed) - { - Key = key; - Elapsed = elapsed; - } - } - - public struct MeasureScope : IDisposable - { - Action m_onDispose; - public MeasureScope(Action onDispose) - { - m_onDispose = onDispose; - } - public void Dispose() - { - m_onDispose(); - } - } - - public List m_speedReports = new List(); - - public IDisposable MeasureTime(string key) - { - var sw = System.Diagnostics.Stopwatch.StartNew(); - return new MeasureScope(() => - { - m_speedReports.Add(new KeyElapsed(key, sw.Elapsed)); - }); - } - - public string GetSpeedLog() - { - var total = TimeSpan.Zero; - - var sb = new StringBuilder(); - sb.AppendLine("【SpeedLog】"); - foreach (var kv in m_speedReports) - { - sb.AppendLine(string.Format("{0}: {1}ms", kv.Key, (int)kv.Elapsed.TotalMilliseconds)); - total += kv.Elapsed; - } - sb.AppendLine(string.Format("total: {0}ms", (int)total.TotalMilliseconds)); - - return sb.ToString(); - } - #endregion - - IShaderStore m_shaderStore; - public IShaderStore ShaderStore - { - get - { - if (m_shaderStore == null) - { - m_shaderStore = new ShaderStore(this); - } - return m_shaderStore; - } - } - - IMaterialImporter m_materialImporter; - protected void SetMaterialImporter(IMaterialImporter importer) - { - m_materialImporter = importer; - } - public IMaterialImporter MaterialImporter - { - get - { - if (m_materialImporter == null) - { - m_materialImporter = new MaterialImporter(ShaderStore, this); - } - return m_materialImporter; - } - } - - public ImporterContext(IShaderStore shaderStore) - { - m_shaderStore = shaderStore; - } - - public ImporterContext(IMaterialImporter materialImporter) - { - m_materialImporter = materialImporter; - } - - public ImporterContext() - { - } - - #region Source - - /// - /// JSON source - /// - public String Json; - - /// - /// GLTF parsed from JSON - /// - public glTF GLTF; // parsed - - public static bool IsGeneratedUniGLTFAndOlderThan(string generatorVersion, int major, int minor) - { - if (string.IsNullOrEmpty(generatorVersion)) return false; - if (generatorVersion == "UniGLTF") return true; - if (!generatorVersion.StartsWith("UniGLTF-")) return false; - - try - { - var index = generatorVersion.IndexOf('.'); - var generatorMajor = int.Parse(generatorVersion.Substring(8, index - 8)); - var generatorMinor = int.Parse(generatorVersion.Substring(index + 1)); - - if (generatorMajor < major) - { - return true; - } - else - { - if (generatorMinor >= minor) - { - return false; - } - else - { - return true; - } - } - } - catch (Exception ex) - { - Debug.LogWarningFormat("{0}: {1}", generatorVersion, ex); - return false; - } - } - - public bool IsGeneratedUniGLTFAndOlder(int major, int minor) - { - if (GLTF == null) return false; - if (GLTF.asset == null) return false; - return IsGeneratedUniGLTFAndOlderThan(GLTF.asset.generator, major, minor); - } - - /// - /// URI access - /// - public IStorage Storage; - #endregion - - #region Parse - public void Parse(string path) - { - Parse(path, File.ReadAllBytes(path)); - } - - /// - /// Parse gltf json or Parse json chunk of glb - /// - /// - /// - public virtual void Parse(string path, Byte[] bytes) - { - var ext = Path.GetExtension(path).ToLower(); - switch (ext) - { - case ".gltf": - ParseJson(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path))); - break; - - case ".zip": - { - var zipArchive = Zip.ZipArchiveStorage.Parse(bytes); - var gltf = zipArchive.Entries.FirstOrDefault(x => x.FileName.ToLower().EndsWith(".gltf")); - if (gltf == null) - { - throw new Exception("no gltf in archive"); - } - var jsonBytes = zipArchive.Extract(gltf); - var json = Encoding.UTF8.GetString(jsonBytes); - ParseJson(json, zipArchive); - } - break; - - case ".glb": - ParseGlb(bytes); - break; - - default: - throw new NotImplementedException(); - } - } - - /// - /// - /// - /// - public void ParseGlb(Byte[] bytes) - { - var chunks = glbImporter.ParseGlbChanks(bytes); - - if (chunks.Count != 2) - { - throw new Exception("unknown chunk count: " + chunks.Count); - } - - if (chunks[0].ChunkType != GlbChunkType.JSON) - { - throw new Exception("chunk 0 is not JSON"); - } - - if (chunks[1].ChunkType != GlbChunkType.BIN) - { - throw new Exception("chunk 1 is not BIN"); - } - - var jsonBytes = chunks[0].Bytes; - ParseJson(Encoding.UTF8.GetString(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count), - new SimpleStorage(chunks[1].Bytes)); - } - - public virtual void ParseJson(string json, IStorage storage) - { - Json = json; - Storage = storage; - - GLTF = JsonUtility.FromJson(Json); - if (GLTF.asset.version != "2.0") - { - throw new UniGLTFException("unknown gltf version {0}", GLTF.asset.version); - } - - // Version Compatibility - RestoreOlderVersionValues(); - - // parepare byte buffer - //GLTF.baseDir = System.IO.Path.GetDirectoryName(Path); - foreach (var buffer in GLTF.buffers) - { - buffer.OpenStorage(storage); - } - } - - void RestoreOlderVersionValues() - { - var parsed = UniJSON.JsonParser.Parse(Json); - for (int i = 0; i < GLTF.images.Count; ++i) - { - if (string.IsNullOrEmpty(GLTF.images[i].name)) - { - try - { - var extraName = parsed["images"][i]["extra"]["name"].Value.GetString(); - if (!string.IsNullOrEmpty(extraName)) - { - //Debug.LogFormat("restore texturename: {0}", extraName); - GLTF.images[i].name = extraName; - } - } - catch (Exception) - { - // do nothing - } - } - } - for (int i = 0; i < GLTF.meshes.Count; ++i) - { - var mesh = GLTF.meshes[i]; - try - { - for (int j = 0; j < mesh.primitives.Count; ++j) - { - var primitive = mesh.primitives[j]; - for (int k = 0; k < primitive.targets.Count; ++k) - { - var extraName = parsed["meshes"][i]["primitives"][j]["targets"][k]["extra"]["name"].Value.GetString(); - //Debug.LogFormat("restore morphName: {0}", extraName); - primitive.extras.targetNames.Add(extraName); - } - } - } - catch (Exception) - { - // do nothing - } - } -#if false - for (int i = 0; i < GLTF.nodes.Count; ++i) - { - var node = GLTF.nodes[i]; - try - { - var extra = parsed["nodes"][i]["extra"]["skinRootBone"].AsInt; - //Debug.LogFormat("restore extra: {0}", extra); - //node.extras.skinRootBone = extra; - } - catch (Exception) - { - // do nothing - } - } -#endif - } - #endregion - - #region Load. Build unity objects - /// - /// ReadAllBytes, Parse, Create GameObject - /// - /// allbytes - public void Load(string path) - { - var bytes = File.ReadAllBytes(path); - Load(path, bytes); - } - - /// - /// Parse, Create GameObject - /// - /// gltf or glb path - /// allbytes - public void Load(string path, byte[] bytes) - { - Parse(path, bytes); - Load(); - Root.name = Path.GetFileNameWithoutExtension(path); - } - - public void CreateTextureItems(UnityPath imageBaseDir = default(UnityPath)) - { - if (m_textures.Any()) - { - return; - } - - for (int i = 0; i < GLTF.textures.Count; ++i) - { - var image = GLTF.GetImageFromTextureIndex(i); - - TextureItem item = null; -#if UNITY_EDITOR - if (imageBaseDir.IsUnderAssetsFolder - && !string.IsNullOrEmpty(image.uri) - && !image.uri.StartsWith("data:") - ) - { - /// - /// required SaveTexturesAsPng or SetTextureBaseDir - /// - var assetPath = imageBaseDir.Child(image.uri); - var textureName = !string.IsNullOrEmpty(image.name) ? image.name : Path.GetFileNameWithoutExtension(image.uri); - item = new TextureItem(i, assetPath, textureName); - } - else -#endif - { - item = new TextureItem(i); - } - - AddTexture(item); - } - } - - /// - /// Build unity objects from parsed gltf - /// - public void Load() - { - var schedulable = LoadAsync(); - schedulable.ExecuteAll(); - } - - [Obsolete("Action to Action")] - public IEnumerator LoadCoroutine(Action onLoaded, Action onError = null) - { - return LoadCoroutine(() => onLoaded(Unit.Default), onError); - } - - public IEnumerator LoadCoroutine(Action onError = null) - { - return LoadCoroutine(() => { }, onError); - } - - public IEnumerator LoadCoroutine(Action onLoaded, Action onError = null) - { - if (onLoaded == null) - { - onLoaded = () => { }; - } - - if (onError == null) - { - onError = Debug.LogError; - } - - var schedulable = LoadAsync(); - foreach (var x in schedulable.GetRoot().Traverse()) - { - while (true) - { - var status = x.Execute(); - if (status != ExecutionStatus.Continue) - { - break; - } - yield return null; - } - } - - onLoaded(); - } - - [Obsolete("Action to Action")] - public void LoadAsync(Action onLoaded, Action onError = null) - { - LoadAsync(() => onLoaded(Unit.Default), onError); - } - - public void LoadAsync(Action onLoaded, Action onError = null) - { - if (onError == null) - { - onError = Debug.LogError; - } - - LoadAsync() - .Subscribe(Scheduler.MainThread, - _ => onLoaded(), - onError - ); - } - -#if ((NET_4_6 || NET_STANDARD_2_0) && UNITY_2017_1_OR_NEWER) - public async Task LoadAsyncTask() - { - await LoadAsync().ToTask(); - return Root; - } -#endif - - protected virtual Schedulable LoadAsync() - { - return - Schedulable.Create() - .AddTask(Scheduler.ThreadPool, () => - { - if (m_textures.Count == 0) - { - // - // runtime - // - CreateTextureItems(); - } - else - { - // - // already CreateTextures(by assetPostProcessor or editor menu) - // - } - }) - .ContinueWithCoroutine(Scheduler.ThreadPool, TexturesProcessOnAnyThread) - .ContinueWithCoroutine(Scheduler.MainThread, TexturesProcessOnMainThread) - .ContinueWithCoroutine(Scheduler.MainThread, LoadMaterials) - .OnExecute(Scheduler.ThreadPool, parent => - { - if (GLTF.meshes - .SelectMany(x => x.primitives) - .Any(x => x.extensions.KHR_draco_mesh_compression != null)) - { - throw new UniGLTFNotSupportedException("draco is not supported"); - } - - // meshes - var meshImporter = new MeshImporter(); - for (int i = 0; i < GLTF.meshes.Count; ++i) - { - var index = i; - parent.AddTask(Scheduler.ThreadPool, - () => - { - using (MeasureTime("ReadMesh")) - { - return meshImporter.ReadMesh(this, index); - } - }) - .ContinueWith(Scheduler.MainThread, x => - { - using (MeasureTime("BuildMesh")) - { - var meshWithMaterials = MeshImporter.BuildMesh(this, x); - - var mesh = meshWithMaterials.Mesh; - - // mesh name - if (string.IsNullOrEmpty(mesh.name)) - { - mesh.name = string.Format("UniGLTF import#{0}", i); - } - var originalName = mesh.name; - for (int j = 1; Meshes.Any(y => y.Mesh.name == mesh.name); ++j) - { - mesh.name = string.Format("{0}({1})", originalName, j); - } - - return meshWithMaterials; - } - }) - .ContinueWith(Scheduler.ThreadPool, x => Meshes.Add(x)) - ; - } - }) - .ContinueWithCoroutine(Scheduler.MainThread, LoadNodes) - .ContinueWithCoroutine(Scheduler.MainThread, BuildHierarchy) - .ContinueWith(Scheduler.MainThread, _ => - { - using (MeasureTime("AnimationImporter")) - { - AnimationImporter.ImportAnimation(this); - } - }) - .ContinueWith(Scheduler.CurrentThread, - _ => - { - OnLoadModel(); - if (m_showSpeedLog) - { - Debug.Log(GetSpeedLog()); - } - return Unit.Default; - }); - } - - protected virtual void OnLoadModel() - { - Root.name = "GLTF"; - } - - IEnumerator TexturesProcessOnAnyThread() - { - using (MeasureTime("TexturesProcessOnAnyThread")) - { - foreach (var x in GetTextures()) - { - x.ProcessOnAnyThread(GLTF, Storage); - yield return null; - } - } - } - - IEnumerator TexturesProcessOnMainThread() - { - using (MeasureTime("TexturesProcessOnMainThread")) - { - foreach (var x in GetTextures()) - { - yield return x.ProcessOnMainThreadCoroutine(GLTF); - } - } - } - - IEnumerator LoadMaterials() - { - using (MeasureTime("LoadMaterials")) - { - if (GLTF.materials == null || !GLTF.materials.Any()) - { - AddMaterial(MaterialImporter.CreateMaterial(0, null)); - } - else - { - for (int i = 0; i < GLTF.materials.Count; ++i) - { - AddMaterial(MaterialImporter.CreateMaterial(i, GLTF.materials[i])); - } - } - } - yield return null; - } - - IEnumerator LoadMeshes() - { - var meshImporter = new MeshImporter(); - for (int i = 0; i < GLTF.meshes.Count; ++i) - { - var meshContext = meshImporter.ReadMesh(this, i); - var meshWithMaterials = MeshImporter.BuildMesh(this, meshContext); - var mesh = meshWithMaterials.Mesh; - if (string.IsNullOrEmpty(mesh.name)) - { - mesh.name = string.Format("UniGLTF import#{0}", i); - } - Meshes.Add(meshWithMaterials); - - yield return null; - } - } - - IEnumerator LoadNodes() - { - using (MeasureTime("LoadNodes")) - { - foreach (var x in GLTF.nodes) - { - Nodes.Add(NodeImporter.ImportNode(x).transform); - } - } - - yield return null; - } - - IEnumerator BuildHierarchy() - { - using (MeasureTime("BuildHierarchy")) - { - var nodes = new List(); - for (int i = 0; i < Nodes.Count; ++i) - { - nodes.Add(NodeImporter.BuildHierarchy(this, i)); - } - - NodeImporter.FixCoordinate(this, nodes); - - // skinning - for (int i = 0; i < nodes.Count; ++i) - { - NodeImporter.SetupSkinning(this, nodes, i); - } - - // connect root - Root = new GameObject("_root_"); - foreach (var x in GLTF.rootnodes) - { - var t = nodes[x].Transform; - t.SetParent(Root.transform, false); - } - } - - yield return null; - } -#endregion - -#region Imported - public GameObject Root; - public List Nodes = new List(); - - List m_textures = new List(); - public IList GetTextures() - { - return m_textures; - } - public TextureItem GetTexture(int i) - { - if (i < 0 || i >= m_textures.Count) - { - return null; - } - return m_textures[i]; - } - public void AddTexture(TextureItem item) - { - m_textures.Add(item); - } - - List m_materials = new List(); - public void AddMaterial(Material material) - { - var originalName = material.name; - int j = 2; - while (m_materials.Any(x => x.name == material.name)) - { - material.name = string.Format("{0}({1})", originalName, j++); - } - m_materials.Add(material); - } - public IList GetMaterials() - { - return m_materials; - } - public Material GetMaterial(int index) - { - if (index < 0) return null; - if (index >= m_materials.Count) return null; - return m_materials[index]; - } - - public List Meshes = new List(); - public void ShowMeshes() - { - foreach (var x in Meshes) - { - foreach(var y in x.Renderers) - { - y.enabled = true; - } - } - } - - public void EnableUpdateWhenOffscreen() - { - foreach (var x in Meshes) - { - foreach (var r in x.Renderers) - { - var skinnedMeshRenderer = r as SkinnedMeshRenderer; - if (skinnedMeshRenderer != null) - { - skinnedMeshRenderer.updateWhenOffscreen = true; - } - } - } - } - - public List AnimationClips = new List(); - #endregion - - protected virtual IEnumerable ObjectsForSubAsset() - { - HashSet textures = new HashSet(); - foreach (var x in m_textures.SelectMany(y => y.GetTexturesForSaveAssets())) - { - if (!textures.Contains(x)) - { - textures.Add(x); - } - } - foreach (var x in textures) { yield return x; } - foreach (var x in m_materials) { yield return x; } - foreach (var x in Meshes) { yield return x.Mesh; } - foreach (var x in AnimationClips) { yield return x; } - } - -#if UNITY_EDITOR - #region Assets - public bool MeshAsSubAsset = false; - - protected virtual UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o) - { - if (o is Material) - { - var materialDir = prefabPath.GetAssetFolder(".Materials"); - var materialPath = materialDir.Child(o.name.EscapeFilePath() + ".asset"); - return materialPath; - } - else if (o is Texture2D) - { - var textureDir = prefabPath.GetAssetFolder(".Textures"); - var texturePath = textureDir.Child(o.name.EscapeFilePath() + ".asset"); - return texturePath; - } - else if (o is Mesh && !MeshAsSubAsset) - { - var meshDir = prefabPath.GetAssetFolder(".Meshes"); - var meshPath = meshDir.Child(o.name.EscapeFilePath() + ".asset"); - return meshPath; - } - else - { - return default(UnityPath); - } - } - - public virtual bool IsOverwrite(UnityEngine.Object o) - { - if(o is Material) - { - return false; - } - - return true; - } - - public void SaveAsAsset(UnityPath prefabPath) - { - ShowMeshes(); - - //var prefabPath = PrefabPath; - if (prefabPath.IsFileExists) - { - // clear SubAssets - foreach (var x in prefabPath.GetSubAssets().Where(x => !(x is GameObject) && !(x is Component))) - { - GameObject.DestroyImmediate(x, true); - } - } - - // - // save sub assets - // - var paths = new List(){ - prefabPath - }; - foreach (var o in ObjectsForSubAsset()) - { - if (o == null) continue; - - var assetPath = GetAssetPath(prefabPath, o); - if (!assetPath.IsNull) - { - if (assetPath.IsFileExists) - { - if (!IsOverwrite(o)) - { - // 上書きしない - Debug.LogWarningFormat("already exists. skip {0}", assetPath); - continue; - } - } - assetPath.Parent.EnsureFolder(); - assetPath.CreateAsset(o); - paths.Add(assetPath); - } - else - { - // save as subasset - prefabPath.AddObjectToAsset(o); - } - } - - // Create or upate Main Asset - if (prefabPath.IsFileExists) - { - Debug.LogFormat("replace prefab: {0}", prefabPath); - var prefab = prefabPath.LoadAsset(); - PrefabUtility.ReplacePrefab(Root, prefab, ReplacePrefabOptions.ReplaceNameBased); - } - else - { - Debug.LogFormat("create prefab: {0}", prefabPath); - PrefabUtility.CreatePrefab(prefabPath.Value, Root); - } - foreach (var x in paths) - { - x.ImportAsset(); - } - } - - /// - /// Extract images from glb or gltf out of Assets folder. - /// - /// - public void ExtranctImages(UnityPath prefabPath) - { - var prefabParentDir = prefabPath.Parent; - - // glb buffer - var folder = prefabPath.GetAssetFolder(".Textures"); - - // - // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html - // - int created = 0; - //for (int i = 0; i < GLTF.textures.Count; ++i) - for (int i = 0; i < GLTF.images.Count; ++i) - { - folder.EnsureFolder(); - - //var x = GLTF.textures[i]; - var image = GLTF.images[i]; - var src = Storage.GetPath(image.uri); - if (UnityPath.FromFullpath(src).IsUnderAssetsFolder) - { - // asset is exists. - } - else - { - string textureName; - var byteSegment = GLTF.GetImageBytes(Storage, i, out textureName); - - // path - var dst = folder.Child(textureName + image.GetExt()); - File.WriteAllBytes(dst.FullPath, byteSegment.ToArray()); - dst.ImportAsset(); - - // make relative path from PrefabParentDir - image.uri = dst.Value.Substring(prefabParentDir.Value.Length + 1); - ++created; - } - } - - if (created > 0) - { - AssetDatabase.Refresh(); - } - - CreateTextureItems(prefabParentDir); - } - #endregion -#endif - - /// - /// This function is used for clean up after create assets. - /// - /// Ambiguous arguments - [Obsolete("Use Dispose for runtime loader resource management")] - public void Destroy(bool destroySubAssets) - { - if (Root != null) GameObject.DestroyImmediate(Root); - if (destroySubAssets) - { -#if UNITY_EDITOR - foreach (var o in ObjectsForSubAsset()) - { - UnityEngine.Object.DestroyImmediate(o, true); - } -#endif - } - } - - public void Dispose() - { - DestroyRootAndResources(); - } - - /// - /// Destroy resources that created ImporterContext for runtime load. - /// - public void DestroyRootAndResources() - { - if (!Application.isPlaying) - { - Debug.LogWarningFormat("Dispose called in editor mode. This function is for runtime"); - } - - // Remove hierarchy - if (Root != null) GameObject.Destroy(Root); - - // Remove resources. materials, textures meshes etc... - foreach (var o in ObjectsForSubAsset()) - { - UnityEngine.Object.DestroyImmediate(o, true); - } - } - -#if UNITY_EDITOR - /// - /// Destroy the GameObject that became the basis of Prefab - /// - public void EditorDestroyRoot() - { - if (Root != null) GameObject.DestroyImmediate(Root); - } - - /// - /// Destroy assets that created ImporterContext. This function is clean up for imoprter error. - /// - public void EditorDestroyRootAndAssets() - { - // Remove hierarchy - if (Root != null) GameObject.DestroyImmediate(Root); - - // Remove resources. materials, textures meshes etc... - foreach (var o in ObjectsForSubAsset()) - { - UnityEngine.Object.DestroyImmediate(o, true); - } - } -#endif - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; +using System.IO; +using System.Text; +using System.Collections; +using DepthFirstScheduler; +#if UNITY_EDITOR +using UnityEditor; +#endif +#if ((NET_4_6 || NET_STANDARD_2_0) && UNITY_2017_1_OR_NEWER) +using System.Threading.Tasks; +#endif + + +namespace UniGLTF +{ + /// + /// GLTF importer + /// + public class ImporterContext: IDisposable + { + #region MeasureTime + bool m_showSpeedLog +#if UNIGLTF_DEVELOP + = true +#endif + ; + public bool ShowSpeedLog + { + set { m_showSpeedLog = value; } + } + + public struct KeyElapsed + { + public string Key; + public TimeSpan Elapsed; + public KeyElapsed(string key, TimeSpan elapsed) + { + Key = key; + Elapsed = elapsed; + } + } + + public struct MeasureScope : IDisposable + { + Action m_onDispose; + public MeasureScope(Action onDispose) + { + m_onDispose = onDispose; + } + public void Dispose() + { + m_onDispose(); + } + } + + public List m_speedReports = new List(); + + public IDisposable MeasureTime(string key) + { + var sw = System.Diagnostics.Stopwatch.StartNew(); + return new MeasureScope(() => + { + m_speedReports.Add(new KeyElapsed(key, sw.Elapsed)); + }); + } + + public string GetSpeedLog() + { + var total = TimeSpan.Zero; + + var sb = new StringBuilder(); + sb.AppendLine("【SpeedLog】"); + foreach (var kv in m_speedReports) + { + sb.AppendLine(string.Format("{0}: {1}ms", kv.Key, (int)kv.Elapsed.TotalMilliseconds)); + total += kv.Elapsed; + } + sb.AppendLine(string.Format("total: {0}ms", (int)total.TotalMilliseconds)); + + return sb.ToString(); + } + #endregion + + IShaderStore m_shaderStore; + public IShaderStore ShaderStore + { + get + { + if (m_shaderStore == null) + { + m_shaderStore = new ShaderStore(this); + } + return m_shaderStore; + } + } + + IMaterialImporter m_materialImporter; + protected void SetMaterialImporter(IMaterialImporter importer) + { + m_materialImporter = importer; + } + public IMaterialImporter MaterialImporter + { + get + { + if (m_materialImporter == null) + { + m_materialImporter = new MaterialImporter(ShaderStore, this); + } + return m_materialImporter; + } + } + + public ImporterContext(IShaderStore shaderStore) + { + m_shaderStore = shaderStore; + } + + public ImporterContext(IMaterialImporter materialImporter) + { + m_materialImporter = materialImporter; + } + + public ImporterContext() + { + } + + #region Source + + /// + /// JSON source + /// + public String Json; + + /// + /// GLTF parsed from JSON + /// + public glTF GLTF; // parsed + + public static bool IsGeneratedUniGLTFAndOlderThan(string generatorVersion, int major, int minor) + { + if (string.IsNullOrEmpty(generatorVersion)) return false; + if (generatorVersion == "UniGLTF") return true; + if (!generatorVersion.StartsWith("UniGLTF-")) return false; + + try + { + var index = generatorVersion.IndexOf('.'); + var generatorMajor = int.Parse(generatorVersion.Substring(8, index - 8)); + var generatorMinor = int.Parse(generatorVersion.Substring(index + 1)); + + if (generatorMajor < major) + { + return true; + } + else + { + if (generatorMinor >= minor) + { + return false; + } + else + { + return true; + } + } + } + catch (Exception ex) + { + Debug.LogWarningFormat("{0}: {1}", generatorVersion, ex); + return false; + } + } + + public bool IsGeneratedUniGLTFAndOlder(int major, int minor) + { + if (GLTF == null) return false; + if (GLTF.asset == null) return false; + return IsGeneratedUniGLTFAndOlderThan(GLTF.asset.generator, major, minor); + } + + /// + /// URI access + /// + public IStorage Storage; + #endregion + + #region Parse + public void Parse(string path) + { + Parse(path, File.ReadAllBytes(path)); + } + + /// + /// Parse gltf json or Parse json chunk of glb + /// + /// + /// + public virtual void Parse(string path, Byte[] bytes) + { + var ext = Path.GetExtension(path).ToLower(); + switch (ext) + { + case ".gltf": + ParseJson(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path))); + break; + + case ".zip": + { + var zipArchive = Zip.ZipArchiveStorage.Parse(bytes); + var gltf = zipArchive.Entries.FirstOrDefault(x => x.FileName.ToLower().EndsWith(".gltf")); + if (gltf == null) + { + throw new Exception("no gltf in archive"); + } + var jsonBytes = zipArchive.Extract(gltf); + var json = Encoding.UTF8.GetString(jsonBytes); + ParseJson(json, zipArchive); + } + break; + + case ".glb": + ParseGlb(bytes); + break; + + default: + throw new NotImplementedException(); + } + } + + /// + /// + /// + /// + public void ParseGlb(Byte[] bytes) + { + var chunks = glbImporter.ParseGlbChanks(bytes); + + if (chunks.Count != 2) + { + throw new Exception("unknown chunk count: " + chunks.Count); + } + + if (chunks[0].ChunkType != GlbChunkType.JSON) + { + throw new Exception("chunk 0 is not JSON"); + } + + if (chunks[1].ChunkType != GlbChunkType.BIN) + { + throw new Exception("chunk 1 is not BIN"); + } + + var jsonBytes = chunks[0].Bytes; + ParseJson(Encoding.UTF8.GetString(jsonBytes.Array, jsonBytes.Offset, jsonBytes.Count), + new SimpleStorage(chunks[1].Bytes)); + } + + public virtual void ParseJson(string json, IStorage storage) + { + Json = json; + Storage = storage; + + GLTF = JsonUtility.FromJson(Json); + if (GLTF.asset.version != "2.0") + { + throw new UniGLTFException("unknown gltf version {0}", GLTF.asset.version); + } + + // Version Compatibility + RestoreOlderVersionValues(); + + // parepare byte buffer + //GLTF.baseDir = System.IO.Path.GetDirectoryName(Path); + foreach (var buffer in GLTF.buffers) + { + buffer.OpenStorage(storage); + } + } + + void RestoreOlderVersionValues() + { + var parsed = UniJSON.JsonParser.Parse(Json); + for (int i = 0; i < GLTF.images.Count; ++i) + { + if (string.IsNullOrEmpty(GLTF.images[i].name)) + { + try + { + var extraName = parsed["images"][i]["extra"]["name"].Value.GetString(); + if (!string.IsNullOrEmpty(extraName)) + { + //Debug.LogFormat("restore texturename: {0}", extraName); + GLTF.images[i].name = extraName; + } + } + catch (Exception) + { + // do nothing + } + } + } + for (int i = 0; i < GLTF.meshes.Count; ++i) + { + var mesh = GLTF.meshes[i]; + try + { + for (int j = 0; j < mesh.primitives.Count; ++j) + { + var primitive = mesh.primitives[j]; + for (int k = 0; k < primitive.targets.Count; ++k) + { + var extraName = parsed["meshes"][i]["primitives"][j]["targets"][k]["extra"]["name"].Value.GetString(); + //Debug.LogFormat("restore morphName: {0}", extraName); + primitive.extras.targetNames.Add(extraName); + } + } + } + catch (Exception) + { + // do nothing + } + } +#if false + for (int i = 0; i < GLTF.nodes.Count; ++i) + { + var node = GLTF.nodes[i]; + try + { + var extra = parsed["nodes"][i]["extra"]["skinRootBone"].AsInt; + //Debug.LogFormat("restore extra: {0}", extra); + //node.extras.skinRootBone = extra; + } + catch (Exception) + { + // do nothing + } + } +#endif + } + #endregion + + #region Load. Build unity objects + /// + /// ReadAllBytes, Parse, Create GameObject + /// + /// allbytes + public void Load(string path) + { + var bytes = File.ReadAllBytes(path); + Load(path, bytes); + } + + /// + /// Parse, Create GameObject + /// + /// gltf or glb path + /// allbytes + public void Load(string path, byte[] bytes) + { + Parse(path, bytes); + Load(); + Root.name = Path.GetFileNameWithoutExtension(path); + } + + public void CreateTextureItems(UnityPath imageBaseDir = default(UnityPath)) + { + if (m_textures.Any()) + { + return; + } + + for (int i = 0; i < GLTF.textures.Count; ++i) + { + var image = GLTF.GetImageFromTextureIndex(i); + + TextureItem item = null; +#if UNITY_EDITOR + if (imageBaseDir.IsUnderAssetsFolder + && !string.IsNullOrEmpty(image.uri) + && !image.uri.StartsWith("data:") + ) + { + /// + /// required SaveTexturesAsPng or SetTextureBaseDir + /// + var assetPath = imageBaseDir.Child(image.uri); + var textureName = !string.IsNullOrEmpty(image.name) ? image.name : Path.GetFileNameWithoutExtension(image.uri); + item = new TextureItem(i, assetPath, textureName); + } + else +#endif + { + item = new TextureItem(i); + } + + AddTexture(item); + } + } + + /// + /// Build unity objects from parsed gltf + /// + public void Load() + { + var schedulable = LoadAsync(); + schedulable.ExecuteAll(); + } + + [Obsolete("Action to Action")] + public IEnumerator LoadCoroutine(Action onLoaded, Action onError = null) + { + return LoadCoroutine(() => onLoaded(Unit.Default), onError); + } + + public IEnumerator LoadCoroutine(Action onError = null) + { + return LoadCoroutine(() => { }, onError); + } + + public IEnumerator LoadCoroutine(Action onLoaded, Action onError = null) + { + if (onLoaded == null) + { + onLoaded = () => { }; + } + + if (onError == null) + { + onError = Debug.LogError; + } + + var schedulable = LoadAsync(); + foreach (var x in schedulable.GetRoot().Traverse()) + { + while (true) + { + var status = x.Execute(); + if (status != ExecutionStatus.Continue) + { + break; + } + yield return null; + } + } + + onLoaded(); + } + + [Obsolete("Action to Action")] + public void LoadAsync(Action onLoaded, Action onError = null) + { + LoadAsync(() => onLoaded(Unit.Default), onError); + } + + public void LoadAsync(Action onLoaded, Action onError = null) + { + if (onError == null) + { + onError = Debug.LogError; + } + + LoadAsync() + .Subscribe(Scheduler.MainThread, + _ => onLoaded(), + onError + ); + } + +#if ((NET_4_6 || NET_STANDARD_2_0) && UNITY_2017_1_OR_NEWER) + public async Task LoadAsyncTask() + { + await LoadAsync().ToTask(); + return Root; + } +#endif + + protected virtual Schedulable LoadAsync() + { + return + Schedulable.Create() + .AddTask(Scheduler.ThreadPool, () => + { + if (m_textures.Count == 0) + { + // + // runtime + // + CreateTextureItems(); + } + else + { + // + // already CreateTextures(by assetPostProcessor or editor menu) + // + } + }) + .ContinueWithCoroutine(Scheduler.ThreadPool, TexturesProcessOnAnyThread) + .ContinueWithCoroutine(Scheduler.MainThread, TexturesProcessOnMainThread) + .ContinueWithCoroutine(Scheduler.MainThread, LoadMaterials) + .OnExecute(Scheduler.ThreadPool, parent => + { + if (GLTF.meshes + .SelectMany(x => x.primitives) + .Any(x => x.extensions.KHR_draco_mesh_compression != null)) + { + throw new UniGLTFNotSupportedException("draco is not supported"); + } + + // meshes + var meshImporter = new MeshImporter(); + for (int i = 0; i < GLTF.meshes.Count; ++i) + { + var index = i; + parent.AddTask(Scheduler.ThreadPool, + () => + { + using (MeasureTime("ReadMesh")) + { + return meshImporter.ReadMesh(this, index); + } + }) + .ContinueWith(Scheduler.MainThread, x => + { + using (MeasureTime("BuildMesh")) + { + var meshWithMaterials = MeshImporter.BuildMesh(this, x); + + var mesh = meshWithMaterials.Mesh; + + // mesh name + if (string.IsNullOrEmpty(mesh.name)) + { + mesh.name = string.Format("UniGLTF import#{0}", i); + } + var originalName = mesh.name; + for (int j = 1; Meshes.Any(y => y.Mesh.name == mesh.name); ++j) + { + mesh.name = string.Format("{0}({1})", originalName, j); + } + + return meshWithMaterials; + } + }) + .ContinueWith(Scheduler.ThreadPool, x => Meshes.Add(x)) + ; + } + }) + .ContinueWithCoroutine(Scheduler.MainThread, LoadNodes) + .ContinueWithCoroutine(Scheduler.MainThread, BuildHierarchy) + .ContinueWith(Scheduler.MainThread, _ => + { + using (MeasureTime("AnimationImporter")) + { + AnimationImporter.ImportAnimation(this); + } + }) + .ContinueWith(Scheduler.CurrentThread, + _ => + { + OnLoadModel(); + if (m_showSpeedLog) + { + Debug.Log(GetSpeedLog()); + } + return Unit.Default; + }); + } + + protected virtual void OnLoadModel() + { + Root.name = "GLTF"; + } + + IEnumerator TexturesProcessOnAnyThread() + { + using (MeasureTime("TexturesProcessOnAnyThread")) + { + foreach (var x in GetTextures()) + { + x.ProcessOnAnyThread(GLTF, Storage); + yield return null; + } + } + } + + IEnumerator TexturesProcessOnMainThread() + { + using (MeasureTime("TexturesProcessOnMainThread")) + { + foreach (var x in GetTextures()) + { + yield return x.ProcessOnMainThreadCoroutine(GLTF); + } + } + } + + IEnumerator LoadMaterials() + { + using (MeasureTime("LoadMaterials")) + { + if (GLTF.materials == null || !GLTF.materials.Any()) + { + AddMaterial(MaterialImporter.CreateMaterial(0, null)); + } + else + { + for (int i = 0; i < GLTF.materials.Count; ++i) + { + AddMaterial(MaterialImporter.CreateMaterial(i, GLTF.materials[i])); + } + } + } + yield return null; + } + + IEnumerator LoadMeshes() + { + var meshImporter = new MeshImporter(); + for (int i = 0; i < GLTF.meshes.Count; ++i) + { + var meshContext = meshImporter.ReadMesh(this, i); + var meshWithMaterials = MeshImporter.BuildMesh(this, meshContext); + var mesh = meshWithMaterials.Mesh; + if (string.IsNullOrEmpty(mesh.name)) + { + mesh.name = string.Format("UniGLTF import#{0}", i); + } + Meshes.Add(meshWithMaterials); + + yield return null; + } + } + + IEnumerator LoadNodes() + { + using (MeasureTime("LoadNodes")) + { + foreach (var x in GLTF.nodes) + { + Nodes.Add(NodeImporter.ImportNode(x).transform); + } + } + + yield return null; + } + + IEnumerator BuildHierarchy() + { + using (MeasureTime("BuildHierarchy")) + { + var nodes = new List(); + for (int i = 0; i < Nodes.Count; ++i) + { + nodes.Add(NodeImporter.BuildHierarchy(this, i)); + } + + NodeImporter.FixCoordinate(this, nodes); + + // skinning + for (int i = 0; i < nodes.Count; ++i) + { + NodeImporter.SetupSkinning(this, nodes, i); + } + + // connect root + Root = new GameObject("_root_"); + foreach (var x in GLTF.rootnodes) + { + var t = nodes[x].Transform; + t.SetParent(Root.transform, false); + } + } + + yield return null; + } +#endregion + +#region Imported + public GameObject Root; + public List Nodes = new List(); + + List m_textures = new List(); + public IList GetTextures() + { + return m_textures; + } + public TextureItem GetTexture(int i) + { + if (i < 0 || i >= m_textures.Count) + { + return null; + } + return m_textures[i]; + } + public void AddTexture(TextureItem item) + { + m_textures.Add(item); + } + + List m_materials = new List(); + public void AddMaterial(Material material) + { + var originalName = material.name; + int j = 2; + while (m_materials.Any(x => x.name == material.name)) + { + material.name = string.Format("{0}({1})", originalName, j++); + } + m_materials.Add(material); + } + public IList GetMaterials() + { + return m_materials; + } + public Material GetMaterial(int index) + { + if (index < 0) return null; + if (index >= m_materials.Count) return null; + return m_materials[index]; + } + + public List Meshes = new List(); + public void ShowMeshes() + { + foreach (var x in Meshes) + { + foreach(var y in x.Renderers) + { + y.enabled = true; + } + } + } + + public void EnableUpdateWhenOffscreen() + { + foreach (var x in Meshes) + { + foreach (var r in x.Renderers) + { + var skinnedMeshRenderer = r as SkinnedMeshRenderer; + if (skinnedMeshRenderer != null) + { + skinnedMeshRenderer.updateWhenOffscreen = true; + } + } + } + } + + public List AnimationClips = new List(); + #endregion + + protected virtual IEnumerable ObjectsForSubAsset() + { + HashSet textures = new HashSet(); + foreach (var x in m_textures.SelectMany(y => y.GetTexturesForSaveAssets())) + { + if (!textures.Contains(x)) + { + textures.Add(x); + } + } + foreach (var x in textures) { yield return x; } + foreach (var x in m_materials) { yield return x; } + foreach (var x in Meshes) { yield return x.Mesh; } + foreach (var x in AnimationClips) { yield return x; } + } + +#if UNITY_EDITOR + #region Assets + public bool MeshAsSubAsset = false; + + protected virtual UnityPath GetAssetPath(UnityPath prefabPath, UnityEngine.Object o) + { + if (o is Material) + { + var materialDir = prefabPath.GetAssetFolder(".Materials"); + var materialPath = materialDir.Child(o.name.EscapeFilePath() + ".asset"); + return materialPath; + } + else if (o is Texture2D) + { + var textureDir = prefabPath.GetAssetFolder(".Textures"); + var texturePath = textureDir.Child(o.name.EscapeFilePath() + ".asset"); + return texturePath; + } + else if (o is Mesh && !MeshAsSubAsset) + { + var meshDir = prefabPath.GetAssetFolder(".Meshes"); + var meshPath = meshDir.Child(o.name.EscapeFilePath() + ".asset"); + return meshPath; + } + else + { + return default(UnityPath); + } + } + + public virtual bool IsOverwrite(UnityEngine.Object o) + { + if(o is Material) + { + return false; + } + + return true; + } + + public void SaveAsAsset(UnityPath prefabPath) + { + ShowMeshes(); + + //var prefabPath = PrefabPath; + if (prefabPath.IsFileExists) + { + // clear SubAssets + foreach (var x in prefabPath.GetSubAssets().Where(x => !(x is GameObject) && !(x is Component))) + { + GameObject.DestroyImmediate(x, true); + } + } + + // + // save sub assets + // + var paths = new List(){ + prefabPath + }; + foreach (var o in ObjectsForSubAsset()) + { + if (o == null) continue; + + var assetPath = GetAssetPath(prefabPath, o); + if (!assetPath.IsNull) + { + if (assetPath.IsFileExists) + { + if (!IsOverwrite(o)) + { + // 上書きしない + Debug.LogWarningFormat("already exists. skip {0}", assetPath); + continue; + } + } + assetPath.Parent.EnsureFolder(); + assetPath.CreateAsset(o); + paths.Add(assetPath); + } + else + { + // save as subasset + prefabPath.AddObjectToAsset(o); + } + } + + // Create or upate Main Asset + if (prefabPath.IsFileExists) + { + Debug.LogFormat("replace prefab: {0}", prefabPath); + var prefab = prefabPath.LoadAsset(); + PrefabUtility.ReplacePrefab(Root, prefab, ReplacePrefabOptions.ReplaceNameBased); + } + else + { + Debug.LogFormat("create prefab: {0}", prefabPath); + PrefabUtility.CreatePrefab(prefabPath.Value, Root); + } + foreach (var x in paths) + { + x.ImportAsset(); + } + } + + /// + /// Extract images from glb or gltf out of Assets folder. + /// + /// + public void ExtranctImages(UnityPath prefabPath) + { + var prefabParentDir = prefabPath.Parent; + + // glb buffer + var folder = prefabPath.GetAssetFolder(".Textures"); + + // + // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html + // + int created = 0; + //for (int i = 0; i < GLTF.textures.Count; ++i) + for (int i = 0; i < GLTF.images.Count; ++i) + { + folder.EnsureFolder(); + + //var x = GLTF.textures[i]; + var image = GLTF.images[i]; + var src = Storage.GetPath(image.uri); + if (UnityPath.FromFullpath(src).IsUnderAssetsFolder) + { + // asset is exists. + } + else + { + string textureName; + var byteSegment = GLTF.GetImageBytes(Storage, i, out textureName); + + // path + var dst = folder.Child(textureName + image.GetExt()); + File.WriteAllBytes(dst.FullPath, byteSegment.ToArray()); + dst.ImportAsset(); + + // make relative path from PrefabParentDir + image.uri = dst.Value.Substring(prefabParentDir.Value.Length + 1); + ++created; + } + } + + if (created > 0) + { + AssetDatabase.Refresh(); + } + + CreateTextureItems(prefabParentDir); + } + #endregion +#endif + + /// + /// This function is used for clean up after create assets. + /// + /// Ambiguous arguments + [Obsolete("Use Dispose for runtime loader resource management")] + public void Destroy(bool destroySubAssets) + { + if (Root != null) GameObject.DestroyImmediate(Root); + if (destroySubAssets) + { +#if UNITY_EDITOR + foreach (var o in ObjectsForSubAsset()) + { + UnityEngine.Object.DestroyImmediate(o, true); + } +#endif + } + } + + public void Dispose() + { + DestroyRootAndResources(); + } + + /// + /// Destroy resources that created ImporterContext for runtime load. + /// + public void DestroyRootAndResources() + { + if (!Application.isPlaying) + { + Debug.LogWarningFormat("Dispose called in editor mode. This function is for runtime"); + } + + // Remove hierarchy + if (Root != null) GameObject.Destroy(Root); + + // Remove resources. materials, textures meshes etc... + foreach (var o in ObjectsForSubAsset()) + { + UnityEngine.Object.DestroyImmediate(o, true); + } + } + +#if UNITY_EDITOR + /// + /// Destroy the GameObject that became the basis of Prefab + /// + public void EditorDestroyRoot() + { + if (Root != null) GameObject.DestroyImmediate(Root); + } + + /// + /// Destroy assets that created ImporterContext. This function is clean up for imoprter error. + /// + public void EditorDestroyRootAndAssets() + { + // Remove hierarchy + if (Root != null) GameObject.DestroyImmediate(Root); + + // Remove resources. materials, textures meshes etc... + foreach (var o in ObjectsForSubAsset()) + { + UnityEngine.Object.DestroyImmediate(o, true); + } + } +#endif + } +} diff --git a/UniGLTF/Core/Scripts/IO/ImporterContext.cs.meta b/UniGLTF/Scripts/IO/ImporterContext.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/ImporterContext.cs.meta rename to UniGLTF/Scripts/IO/ImporterContext.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/MaterialExporter.cs b/UniGLTF/Scripts/IO/MaterialExporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/MaterialExporter.cs rename to UniGLTF/Scripts/IO/MaterialExporter.cs index 142406809..3d2df3235 100644 --- a/UniGLTF/Core/Scripts/IO/MaterialExporter.cs +++ b/UniGLTF/Scripts/IO/MaterialExporter.cs @@ -1,268 +1,268 @@ -using System; -using System.Collections.Generic; -using UniGLTF.UniUnlit; -using UnityEngine; -using UnityEngine.Rendering; - - -namespace UniGLTF -{ - public enum glTFBlendMode - { - OPAQUE, - MASK, - BLEND - } - - public interface IMaterialExporter - { - glTFMaterial ExportMaterial(Material m, TextureExportManager textureManager); - } - - public class MaterialExporter : IMaterialExporter - { - public virtual glTFMaterial ExportMaterial(Material m, TextureExportManager textureManager) - { - var material = CreateMaterial(m); - - // common params - material.name = m.name; - Export_Color(m, textureManager, material); - Export_Metallic(m, textureManager, material); - Export_Normal(m, textureManager, material); - Export_Occlusion(m, textureManager, material); - Export_Emission(m, textureManager, material); - - return material; - } - - static void Export_Color(Material m, TextureExportManager textureManager, glTFMaterial material) - { - if (m.HasProperty("_Color")) - { - material.pbrMetallicRoughness.baseColorFactor = m.color.ToArray(); - } - - if (m.HasProperty("_MainTex")) - { - var index = textureManager.CopyAndGetIndex(m.GetTexture("_MainTex"), RenderTextureReadWrite.sRGB); - if (index != -1) - { - material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo() - { - index = index, - }; - } - } - } - - static void Export_Metallic(Material m, TextureExportManager textureManager, glTFMaterial material) - { - int index = -1; - if (m.HasProperty("_MetallicGlossMap")) - { - index = textureManager.ConvertAndGetIndex(m.GetTexture("_MetallicGlossMap"), new MetallicRoughnessConverter()); - if (index != -1) - { - material.pbrMetallicRoughness.metallicRoughnessTexture = new glTFMaterialMetallicRoughnessTextureInfo() - { - index = index, - }; - } - } - - if (index != -1 && m.HasProperty("_GlossMapScale")) - { - material.pbrMetallicRoughness.metallicFactor = 1.0f; - material.pbrMetallicRoughness.roughnessFactor = 1.0f - m.GetFloat("_GlossMapScale"); - } - else - { - if (m.HasProperty("_Metallic")) - { - material.pbrMetallicRoughness.metallicFactor = m.GetFloat("_Metallic"); - } - if (m.HasProperty("_Glossiness")) - { - material.pbrMetallicRoughness.roughnessFactor = 1.0f - m.GetFloat("_Glossiness"); - } - - } - } - - static void Export_Normal(Material m, TextureExportManager textureManager, glTFMaterial material) - { - if (m.HasProperty("_BumpMap")) - { - var index = textureManager.ConvertAndGetIndex(m.GetTexture("_BumpMap"), new NormalConverter()); - if (index != -1) - { - material.normalTexture = new glTFMaterialNormalTextureInfo() - { - index = index, - }; - } - - if (index != -1 && m.HasProperty("_BumpScale")) - { - material.normalTexture.scale = m.GetFloat("_BumpScale"); - } - } - } - - static void Export_Occlusion(Material m, TextureExportManager textureManager, glTFMaterial material) - { - if (m.HasProperty("_OcclusionMap")) - { - var index = textureManager.ConvertAndGetIndex(m.GetTexture("_OcclusionMap"), new OcclusionConverter()); - if (index != -1) - { - material.occlusionTexture = new glTFMaterialOcclusionTextureInfo() - { - index = index, - }; - } - - if (index != -1 && m.HasProperty("_OcclusionStrength")) - { - material.occlusionTexture.strength = m.GetFloat("_OcclusionStrength"); - } - } - } - - static void Export_Emission(Material m, TextureExportManager textureManager, glTFMaterial material) - { - if (m.HasProperty("_EmissionColor")) - { - var color = m.GetColor("_EmissionColor"); - material.emissiveFactor = new float[] { color.r, color.g, color.b }; - } - - if (m.HasProperty("_EmissionMap")) - { - var index = textureManager.CopyAndGetIndex(m.GetTexture("_EmissionMap"), RenderTextureReadWrite.sRGB); - if (index != -1) - { - material.emissiveTexture = new glTFMaterialEmissiveTextureInfo() - { - index = index, - }; - } - } - } - - protected virtual glTFMaterial CreateMaterial(Material m) - { - switch (m.shader.name) - { - case "Unlit/Color": - return Export_UnlitColor(m); - - case "Unlit/Texture": - return Export_UnlitTexture(m); - - case "Unlit/Transparent": - return Export_UnlitTransparent(m); - - case "Unlit/Transparent Cutout": - return Export_UnlitCutout(m); - - case "UniGLTF/UniUnlit": - return Export_UniUnlit(m); - - default: - return Export_Standard(m); - } - } - - static glTFMaterial Export_UnlitColor(Material m) - { - var material = glTF_KHR_materials_unlit.CreateDefault(); - material.alphaMode = glTFBlendMode.OPAQUE.ToString(); - return material; - } - - static glTFMaterial Export_UnlitTexture(Material m) - { - var material = glTF_KHR_materials_unlit.CreateDefault(); - material.alphaMode = glTFBlendMode.OPAQUE.ToString(); - return material; - } - - static glTFMaterial Export_UnlitTransparent(Material m) - { - var material = glTF_KHR_materials_unlit.CreateDefault(); - material.alphaMode = glTFBlendMode.BLEND.ToString(); - return material; - } - - static glTFMaterial Export_UnlitCutout(Material m) - { - var material = glTF_KHR_materials_unlit.CreateDefault(); - material.alphaMode = glTFBlendMode.MASK.ToString(); - material.alphaCutoff = m.GetFloat("_Cutoff"); - return material; - } - - private glTFMaterial Export_UniUnlit(Material m) - { - var material = glTF_KHR_materials_unlit.CreateDefault(); - - var renderMode = UniUnlit.Utils.GetRenderMode(m); - if (renderMode == UniUnlitRenderMode.Opaque) - { - material.alphaMode = glTFBlendMode.OPAQUE.ToString(); - } - else if (renderMode == UniUnlitRenderMode.Transparent) - { - material.alphaMode = glTFBlendMode.BLEND.ToString(); - } - else if (renderMode == UniUnlitRenderMode.Cutout) - { - material.alphaMode = glTFBlendMode.MASK.ToString(); - } - else - { - material.alphaMode = glTFBlendMode.OPAQUE.ToString(); - } - - var cullMode = UniUnlit.Utils.GetCullMode(m); - if (cullMode == UniUnlitCullMode.Off) - { - material.doubleSided = true; - } - else - { - material.doubleSided = false; - } - - return material; - } - - static glTFMaterial Export_Standard(Material m) - { - var material = new glTFMaterial - { - pbrMetallicRoughness = new glTFPbrMetallicRoughness(), - }; - - switch (m.GetTag("RenderType", true)) - { - case "Transparent": - material.alphaMode = glTFBlendMode.BLEND.ToString(); - break; - - case "TransparentCutout": - material.alphaMode = glTFBlendMode.MASK.ToString(); - material.alphaCutoff = m.GetFloat("_Cutoff"); - break; - - default: - material.alphaMode = glTFBlendMode.OPAQUE.ToString(); - break; - } - - return material; - } - } -} +using System; +using System.Collections.Generic; +using UniGLTF.UniUnlit; +using UnityEngine; +using UnityEngine.Rendering; + + +namespace UniGLTF +{ + public enum glTFBlendMode + { + OPAQUE, + MASK, + BLEND + } + + public interface IMaterialExporter + { + glTFMaterial ExportMaterial(Material m, TextureExportManager textureManager); + } + + public class MaterialExporter : IMaterialExporter + { + public virtual glTFMaterial ExportMaterial(Material m, TextureExportManager textureManager) + { + var material = CreateMaterial(m); + + // common params + material.name = m.name; + Export_Color(m, textureManager, material); + Export_Metallic(m, textureManager, material); + Export_Normal(m, textureManager, material); + Export_Occlusion(m, textureManager, material); + Export_Emission(m, textureManager, material); + + return material; + } + + static void Export_Color(Material m, TextureExportManager textureManager, glTFMaterial material) + { + if (m.HasProperty("_Color")) + { + material.pbrMetallicRoughness.baseColorFactor = m.color.ToArray(); + } + + if (m.HasProperty("_MainTex")) + { + var index = textureManager.CopyAndGetIndex(m.GetTexture("_MainTex"), RenderTextureReadWrite.sRGB); + if (index != -1) + { + material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo() + { + index = index, + }; + } + } + } + + static void Export_Metallic(Material m, TextureExportManager textureManager, glTFMaterial material) + { + int index = -1; + if (m.HasProperty("_MetallicGlossMap")) + { + index = textureManager.ConvertAndGetIndex(m.GetTexture("_MetallicGlossMap"), new MetallicRoughnessConverter()); + if (index != -1) + { + material.pbrMetallicRoughness.metallicRoughnessTexture = new glTFMaterialMetallicRoughnessTextureInfo() + { + index = index, + }; + } + } + + if (index != -1 && m.HasProperty("_GlossMapScale")) + { + material.pbrMetallicRoughness.metallicFactor = 1.0f; + material.pbrMetallicRoughness.roughnessFactor = 1.0f - m.GetFloat("_GlossMapScale"); + } + else + { + if (m.HasProperty("_Metallic")) + { + material.pbrMetallicRoughness.metallicFactor = m.GetFloat("_Metallic"); + } + if (m.HasProperty("_Glossiness")) + { + material.pbrMetallicRoughness.roughnessFactor = 1.0f - m.GetFloat("_Glossiness"); + } + + } + } + + static void Export_Normal(Material m, TextureExportManager textureManager, glTFMaterial material) + { + if (m.HasProperty("_BumpMap")) + { + var index = textureManager.ConvertAndGetIndex(m.GetTexture("_BumpMap"), new NormalConverter()); + if (index != -1) + { + material.normalTexture = new glTFMaterialNormalTextureInfo() + { + index = index, + }; + } + + if (index != -1 && m.HasProperty("_BumpScale")) + { + material.normalTexture.scale = m.GetFloat("_BumpScale"); + } + } + } + + static void Export_Occlusion(Material m, TextureExportManager textureManager, glTFMaterial material) + { + if (m.HasProperty("_OcclusionMap")) + { + var index = textureManager.ConvertAndGetIndex(m.GetTexture("_OcclusionMap"), new OcclusionConverter()); + if (index != -1) + { + material.occlusionTexture = new glTFMaterialOcclusionTextureInfo() + { + index = index, + }; + } + + if (index != -1 && m.HasProperty("_OcclusionStrength")) + { + material.occlusionTexture.strength = m.GetFloat("_OcclusionStrength"); + } + } + } + + static void Export_Emission(Material m, TextureExportManager textureManager, glTFMaterial material) + { + if (m.HasProperty("_EmissionColor")) + { + var color = m.GetColor("_EmissionColor"); + material.emissiveFactor = new float[] { color.r, color.g, color.b }; + } + + if (m.HasProperty("_EmissionMap")) + { + var index = textureManager.CopyAndGetIndex(m.GetTexture("_EmissionMap"), RenderTextureReadWrite.sRGB); + if (index != -1) + { + material.emissiveTexture = new glTFMaterialEmissiveTextureInfo() + { + index = index, + }; + } + } + } + + protected virtual glTFMaterial CreateMaterial(Material m) + { + switch (m.shader.name) + { + case "Unlit/Color": + return Export_UnlitColor(m); + + case "Unlit/Texture": + return Export_UnlitTexture(m); + + case "Unlit/Transparent": + return Export_UnlitTransparent(m); + + case "Unlit/Transparent Cutout": + return Export_UnlitCutout(m); + + case "UniGLTF/UniUnlit": + return Export_UniUnlit(m); + + default: + return Export_Standard(m); + } + } + + static glTFMaterial Export_UnlitColor(Material m) + { + var material = glTF_KHR_materials_unlit.CreateDefault(); + material.alphaMode = glTFBlendMode.OPAQUE.ToString(); + return material; + } + + static glTFMaterial Export_UnlitTexture(Material m) + { + var material = glTF_KHR_materials_unlit.CreateDefault(); + material.alphaMode = glTFBlendMode.OPAQUE.ToString(); + return material; + } + + static glTFMaterial Export_UnlitTransparent(Material m) + { + var material = glTF_KHR_materials_unlit.CreateDefault(); + material.alphaMode = glTFBlendMode.BLEND.ToString(); + return material; + } + + static glTFMaterial Export_UnlitCutout(Material m) + { + var material = glTF_KHR_materials_unlit.CreateDefault(); + material.alphaMode = glTFBlendMode.MASK.ToString(); + material.alphaCutoff = m.GetFloat("_Cutoff"); + return material; + } + + private glTFMaterial Export_UniUnlit(Material m) + { + var material = glTF_KHR_materials_unlit.CreateDefault(); + + var renderMode = UniUnlit.Utils.GetRenderMode(m); + if (renderMode == UniUnlitRenderMode.Opaque) + { + material.alphaMode = glTFBlendMode.OPAQUE.ToString(); + } + else if (renderMode == UniUnlitRenderMode.Transparent) + { + material.alphaMode = glTFBlendMode.BLEND.ToString(); + } + else if (renderMode == UniUnlitRenderMode.Cutout) + { + material.alphaMode = glTFBlendMode.MASK.ToString(); + } + else + { + material.alphaMode = glTFBlendMode.OPAQUE.ToString(); + } + + var cullMode = UniUnlit.Utils.GetCullMode(m); + if (cullMode == UniUnlitCullMode.Off) + { + material.doubleSided = true; + } + else + { + material.doubleSided = false; + } + + return material; + } + + static glTFMaterial Export_Standard(Material m) + { + var material = new glTFMaterial + { + pbrMetallicRoughness = new glTFPbrMetallicRoughness(), + }; + + switch (m.GetTag("RenderType", true)) + { + case "Transparent": + material.alphaMode = glTFBlendMode.BLEND.ToString(); + break; + + case "TransparentCutout": + material.alphaMode = glTFBlendMode.MASK.ToString(); + material.alphaCutoff = m.GetFloat("_Cutoff"); + break; + + default: + material.alphaMode = glTFBlendMode.OPAQUE.ToString(); + break; + } + + return material; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/MaterialExporter.cs.meta b/UniGLTF/Scripts/IO/MaterialExporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/MaterialExporter.cs.meta rename to UniGLTF/Scripts/IO/MaterialExporter.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/MaterialImporter.cs b/UniGLTF/Scripts/IO/MaterialImporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/MaterialImporter.cs rename to UniGLTF/Scripts/IO/MaterialImporter.cs index 96f061f4b..1ba34b519 100644 --- a/UniGLTF/Core/Scripts/IO/MaterialImporter.cs +++ b/UniGLTF/Scripts/IO/MaterialImporter.cs @@ -1,262 +1,262 @@ -using UnityEngine; -using System; -using UnityEngine.Rendering; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public interface IMaterialImporter - { - Material CreateMaterial(int i, glTFMaterial src); - } - - public class MaterialImporter : IMaterialImporter - { - IShaderStore m_shaderStore; - - ImporterContext m_context; - protected ImporterContext Context - { - get { return m_context; } - } - - public MaterialImporter(IShaderStore shaderStore, ImporterContext context) - { - m_shaderStore = shaderStore; - m_context = context; - } - - private enum BlendMode - { - Opaque, - Cutout, - Fade, - Transparent - } - - /// StandardShader vaiables - /// - /// _Color - /// _MainTex - /// _Cutoff - /// _Glossiness - /// _Metallic - /// _MetallicGlossMap - /// _BumpScale - /// _BumpMap - /// _Parallax - /// _ParallaxMap - /// _OcclusionStrength - /// _OcclusionMap - /// _EmissionColor - /// _EmissionMap - /// _DetailMask - /// _DetailAlbedoMap - /// _DetailNormalMapScale - /// _DetailNormalMap - /// _UVSec - /// _EmissionScaleUI - /// _EmissionColorUI - /// _Mode - /// _SrcBlend - /// _DstBlend - /// _ZWrite - public virtual Material CreateMaterial(int i, glTFMaterial x) - { - var shader = m_shaderStore.GetShader(x); - //Debug.LogFormat("[{0}]{1}", i, shader.name); - var material = new Material(shader); -#if UNITY_EDITOR - // textureImporter.SaveAndReimport(); may destory this material - material.hideFlags = HideFlags.DontUnloadUnusedAsset; -#endif - - material.name = (x == null || string.IsNullOrEmpty(x.name)) - ? string.Format("material_{0:00}", i) - : x.name - ; - - if (x == null) - { - Debug.LogWarning("glTFMaterial is empty"); - return material; - } - - // unlit material - if (x.extensions != null && x.extensions.KHR_materials_unlit != null) - { - // texture - var texture = m_context.GetTexture(x.pbrMetallicRoughness.baseColorTexture.index); - if (texture != null) - { - material.mainTexture = texture.Texture; - } - - // color - if (x.pbrMetallicRoughness.baseColorFactor != null && x.pbrMetallicRoughness.baseColorFactor.Length == 4) - { - var color = x.pbrMetallicRoughness.baseColorFactor; - material.color = new Color(color[0], color[1], color[2], color[3]); - } - - //renderMode - if (x.alphaMode == "OPAQUE") - { - UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); - } - else if (x.alphaMode == "BLEND") - { - UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Transparent); - } - else if(x.alphaMode == "MASK") - { - UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Cutout); - } - else - { - // default OPAQUE - UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); - } - - // culling - if (x.doubleSided) - { - UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Off); - } - else - { - UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Back); - } - - UniUnlit.Utils.ValidateProperties(material, true); - - return material; - } - - // PBR material - if (x.pbrMetallicRoughness != null) - { - if (x.pbrMetallicRoughness.baseColorFactor != null && x.pbrMetallicRoughness.baseColorFactor.Length == 4) - { - var color = x.pbrMetallicRoughness.baseColorFactor; - material.color = new Color(color[0], color[1], color[2], color[3]); - } - - if (x.pbrMetallicRoughness.baseColorTexture != null && x.pbrMetallicRoughness.baseColorTexture.index != -1) - { - var texture = m_context.GetTexture(x.pbrMetallicRoughness.baseColorTexture.index); - if (texture != null) - { - material.mainTexture = texture.Texture; - } - } - - if (x.pbrMetallicRoughness.metallicRoughnessTexture != null && x.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) - { - material.EnableKeyword("_METALLICGLOSSMAP"); - var texture = Context.GetTexture(x.pbrMetallicRoughness.metallicRoughnessTexture.index); - if (texture != null) - { - var prop = "_MetallicGlossMap"; - material.SetTexture(prop, texture.ConvertTexture(prop)); - } - } - - material.SetFloat("_Metallic", x.pbrMetallicRoughness.metallicFactor); - material.SetFloat("_Glossiness", 1.0f - x.pbrMetallicRoughness.roughnessFactor); - } - - if (x.normalTexture != null && x.normalTexture.index != -1) - { - material.EnableKeyword("_NORMALMAP"); - var texture = Context.GetTexture(x.normalTexture.index); - if (texture != null) - { - var prop = "_BumpMap"; - material.SetTexture(prop, texture.ConvertTexture(prop)); - material.SetFloat("_BumpScale", x.normalTexture.scale); - } - } - - if (x.occlusionTexture != null && x.occlusionTexture.index != -1) - { - var texture = Context.GetTexture(x.occlusionTexture.index); - if (texture != null) - { - var prop = "_OcclusionMap"; - material.SetTexture(prop, texture.ConvertTexture(prop)); - material.SetFloat("_OcclusionStrength", x.occlusionTexture.strength); - } - } - - if (x.emissiveFactor != null - || (x.emissiveTexture != null && x.emissiveTexture.index != -1)) - { - material.EnableKeyword("_EMISSION"); - material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; - - if (x.emissiveFactor != null && x.emissiveFactor.Length == 3) - { - material.SetColor("_EmissionColor", new Color(x.emissiveFactor[0], x.emissiveFactor[1], x.emissiveFactor[2])); - } - - if (x.emissiveTexture.index != -1) - { - var texture = Context.GetTexture(x.emissiveTexture.index); - if (texture != null) - { - material.SetTexture("_EmissionMap", texture.Texture); - } - } - } - - BlendMode blendMode = BlendMode.Opaque; - // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 - switch (x.alphaMode) - { - case "BLEND": - blendMode = BlendMode.Fade; - material.SetOverrideTag("RenderType", "Transparent"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); - material.SetInt("_ZWrite", 0); - material.DisableKeyword("_ALPHATEST_ON"); - material.EnableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = 3000; - break; - - case "MASK": - blendMode = BlendMode.Cutout; - material.SetOverrideTag("RenderType", "TransparentCutout"); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.EnableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = 2450; - - break; - - default: // OPAQUE - blendMode = BlendMode.Opaque; - material.SetOverrideTag("RenderType", ""); - material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); - material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); - material.SetInt("_ZWrite", 1); - material.DisableKeyword("_ALPHATEST_ON"); - material.DisableKeyword("_ALPHABLEND_ON"); - material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); - material.renderQueue = -1; - break; - } - - material.SetFloat("_Mode", (float)blendMode); - return material; - } - } -} +using UnityEngine; +using System; +using UnityEngine.Rendering; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + public interface IMaterialImporter + { + Material CreateMaterial(int i, glTFMaterial src); + } + + public class MaterialImporter : IMaterialImporter + { + IShaderStore m_shaderStore; + + ImporterContext m_context; + protected ImporterContext Context + { + get { return m_context; } + } + + public MaterialImporter(IShaderStore shaderStore, ImporterContext context) + { + m_shaderStore = shaderStore; + m_context = context; + } + + private enum BlendMode + { + Opaque, + Cutout, + Fade, + Transparent + } + + /// StandardShader vaiables + /// + /// _Color + /// _MainTex + /// _Cutoff + /// _Glossiness + /// _Metallic + /// _MetallicGlossMap + /// _BumpScale + /// _BumpMap + /// _Parallax + /// _ParallaxMap + /// _OcclusionStrength + /// _OcclusionMap + /// _EmissionColor + /// _EmissionMap + /// _DetailMask + /// _DetailAlbedoMap + /// _DetailNormalMapScale + /// _DetailNormalMap + /// _UVSec + /// _EmissionScaleUI + /// _EmissionColorUI + /// _Mode + /// _SrcBlend + /// _DstBlend + /// _ZWrite + public virtual Material CreateMaterial(int i, glTFMaterial x) + { + var shader = m_shaderStore.GetShader(x); + //Debug.LogFormat("[{0}]{1}", i, shader.name); + var material = new Material(shader); +#if UNITY_EDITOR + // textureImporter.SaveAndReimport(); may destory this material + material.hideFlags = HideFlags.DontUnloadUnusedAsset; +#endif + + material.name = (x == null || string.IsNullOrEmpty(x.name)) + ? string.Format("material_{0:00}", i) + : x.name + ; + + if (x == null) + { + Debug.LogWarning("glTFMaterial is empty"); + return material; + } + + // unlit material + if (x.extensions != null && x.extensions.KHR_materials_unlit != null) + { + // texture + var texture = m_context.GetTexture(x.pbrMetallicRoughness.baseColorTexture.index); + if (texture != null) + { + material.mainTexture = texture.Texture; + } + + // color + if (x.pbrMetallicRoughness.baseColorFactor != null && x.pbrMetallicRoughness.baseColorFactor.Length == 4) + { + var color = x.pbrMetallicRoughness.baseColorFactor; + material.color = new Color(color[0], color[1], color[2], color[3]); + } + + //renderMode + if (x.alphaMode == "OPAQUE") + { + UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); + } + else if (x.alphaMode == "BLEND") + { + UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Transparent); + } + else if(x.alphaMode == "MASK") + { + UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Cutout); + } + else + { + // default OPAQUE + UniUnlit.Utils.SetRenderMode(material, UniUnlit.UniUnlitRenderMode.Opaque); + } + + // culling + if (x.doubleSided) + { + UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Off); + } + else + { + UniUnlit.Utils.SetCullMode(material, UniUnlit.UniUnlitCullMode.Back); + } + + UniUnlit.Utils.ValidateProperties(material, true); + + return material; + } + + // PBR material + if (x.pbrMetallicRoughness != null) + { + if (x.pbrMetallicRoughness.baseColorFactor != null && x.pbrMetallicRoughness.baseColorFactor.Length == 4) + { + var color = x.pbrMetallicRoughness.baseColorFactor; + material.color = new Color(color[0], color[1], color[2], color[3]); + } + + if (x.pbrMetallicRoughness.baseColorTexture != null && x.pbrMetallicRoughness.baseColorTexture.index != -1) + { + var texture = m_context.GetTexture(x.pbrMetallicRoughness.baseColorTexture.index); + if (texture != null) + { + material.mainTexture = texture.Texture; + } + } + + if (x.pbrMetallicRoughness.metallicRoughnessTexture != null && x.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) + { + material.EnableKeyword("_METALLICGLOSSMAP"); + var texture = Context.GetTexture(x.pbrMetallicRoughness.metallicRoughnessTexture.index); + if (texture != null) + { + var prop = "_MetallicGlossMap"; + material.SetTexture(prop, texture.ConvertTexture(prop)); + } + } + + material.SetFloat("_Metallic", x.pbrMetallicRoughness.metallicFactor); + material.SetFloat("_Glossiness", 1.0f - x.pbrMetallicRoughness.roughnessFactor); + } + + if (x.normalTexture != null && x.normalTexture.index != -1) + { + material.EnableKeyword("_NORMALMAP"); + var texture = Context.GetTexture(x.normalTexture.index); + if (texture != null) + { + var prop = "_BumpMap"; + material.SetTexture(prop, texture.ConvertTexture(prop)); + material.SetFloat("_BumpScale", x.normalTexture.scale); + } + } + + if (x.occlusionTexture != null && x.occlusionTexture.index != -1) + { + var texture = Context.GetTexture(x.occlusionTexture.index); + if (texture != null) + { + var prop = "_OcclusionMap"; + material.SetTexture(prop, texture.ConvertTexture(prop)); + material.SetFloat("_OcclusionStrength", x.occlusionTexture.strength); + } + } + + if (x.emissiveFactor != null + || (x.emissiveTexture != null && x.emissiveTexture.index != -1)) + { + material.EnableKeyword("_EMISSION"); + material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; + + if (x.emissiveFactor != null && x.emissiveFactor.Length == 3) + { + material.SetColor("_EmissionColor", new Color(x.emissiveFactor[0], x.emissiveFactor[1], x.emissiveFactor[2])); + } + + if (x.emissiveTexture.index != -1) + { + var texture = Context.GetTexture(x.emissiveTexture.index); + if (texture != null) + { + material.SetTexture("_EmissionMap", texture.Texture); + } + } + } + + BlendMode blendMode = BlendMode.Opaque; + // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 + switch (x.alphaMode) + { + case "BLEND": + blendMode = BlendMode.Fade; + material.SetOverrideTag("RenderType", "Transparent"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + material.SetInt("_ZWrite", 0); + material.DisableKeyword("_ALPHATEST_ON"); + material.EnableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = 3000; + break; + + case "MASK": + blendMode = BlendMode.Cutout; + material.SetOverrideTag("RenderType", "TransparentCutout"); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_ZWrite", 1); + material.EnableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = 2450; + + break; + + default: // OPAQUE + blendMode = BlendMode.Opaque; + material.SetOverrideTag("RenderType", ""); + material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); + material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); + material.SetInt("_ZWrite", 1); + material.DisableKeyword("_ALPHATEST_ON"); + material.DisableKeyword("_ALPHABLEND_ON"); + material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); + material.renderQueue = -1; + break; + } + + material.SetFloat("_Mode", (float)blendMode); + return material; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/MaterialImporter.cs.meta b/UniGLTF/Scripts/IO/MaterialImporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/MaterialImporter.cs.meta rename to UniGLTF/Scripts/IO/MaterialImporter.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/MeshExporter.cs b/UniGLTF/Scripts/IO/MeshExporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/MeshExporter.cs rename to UniGLTF/Scripts/IO/MeshExporter.cs index a7e01769d..56d9a326c 100644 --- a/UniGLTF/Core/Scripts/IO/MeshExporter.cs +++ b/UniGLTF/Scripts/IO/MeshExporter.cs @@ -1,261 +1,261 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace UniGLTF -{ - public struct MeshWithRenderer - { - public Mesh Mesh; - public Renderer Rendererer; - } - - public static class MeshExporter - { - static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex, - string rendererName, - Mesh mesh, Material[] materials, - List unityMaterials) - { - var positions = mesh.vertices.Select(y => y.ReverseZ()).ToArray(); - var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, glBufferTarget.ARRAY_BUFFER); - gltf.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray(); - gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray(); - - var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); -#if GLTF_EXPORT_TANGENTS - var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); -#endif - var uvAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER); - var colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.ARRAY_BUFFER); - - var boneweights = mesh.boneWeights; - var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new Vector4(y.weight0, y.weight1, y.weight2, y.weight3)).ToArray(), glBufferTarget.ARRAY_BUFFER); - var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new UShort4((ushort)y.boneIndex0, (ushort)y.boneIndex1, (ushort)y.boneIndex2, (ushort)y.boneIndex3)).ToArray(), glBufferTarget.ARRAY_BUFFER); - - var attributes = new glTFAttributes - { - POSITION = positionAccessorIndex, - }; - if (normalAccessorIndex != -1) - { - attributes.NORMAL = normalAccessorIndex; - } -#if GLTF_EXPORT_TANGENTS - if (tangentAccessorIndex != -1) - { - attributes.TANGENT = tangentAccessorIndex; - } -#endif - if (uvAccessorIndex != -1) - { - attributes.TEXCOORD_0 = uvAccessorIndex; - } - if (colorAccessorIndex != -1) - { - attributes.COLOR_0 = colorAccessorIndex; - } - if (weightAccessorIndex != -1) - { - attributes.WEIGHTS_0 = weightAccessorIndex; - } - if (jointsAccessorIndex != -1) - { - attributes.JOINTS_0 = jointsAccessorIndex; - } - - var gltfMesh = new glTFMesh(mesh.name); - for (int j = 0; j < mesh.subMeshCount; ++j) - { - var indices = TriangleUtil.FlipTriangle(mesh.GetIndices(j)).Select(y => (uint)y).ToArray(); - var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices, glBufferTarget.ELEMENT_ARRAY_BUFFER); - - if (j >= materials.Length) - { - Debug.LogWarningFormat("{0}.materials is not enough", rendererName); - break; - } - - gltfMesh.primitives.Add(new glTFPrimitives - { - attributes = attributes, - indices = indicesAccessorIndex, - mode = 4, // triangels ? - material = unityMaterials.IndexOf(materials[j]) - }); - } - return gltfMesh; - } - - static bool UseSparse( - bool usePosition, Vector3 position, - bool useNormal, Vector3 normal, - bool useTangent, Vector3 tangent - ) - { - var useSparse = - (usePosition && position != Vector3.zero) - || (useNormal && normal != Vector3.zero) - || (useTangent && tangent != Vector3.zero) - ; - return useSparse; - } - - static gltfMorphTarget ExportMorphTarget(glTF gltf, int bufferIndex, - Mesh mesh, int j, - bool useSparseAccessorForMorphTarget) - { - var blendShapeVertices = mesh.vertices; - var usePosition = blendShapeVertices != null && blendShapeVertices.Length > 0; - - var blendShapeNormals = mesh.normals; - var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length; - - var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray(); - //var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length; - var useTangent = false; - - var frameCount = mesh.GetBlendShapeFrameCount(j); - mesh.GetBlendShapeFrameVertices(j, frameCount - 1, blendShapeVertices, blendShapeNormals, null); - - var blendShapePositionAccessorIndex = -1; - var blendShapeNormalAccessorIndex = -1; - var blendShapeTangentAccessorIndex = -1; - if (useSparseAccessorForMorphTarget) - { - var accessorCount = blendShapeVertices.Length; - var sparseIndices = Enumerable.Range(0, blendShapeVertices.Length) - .Where(x => UseSparse( - usePosition, blendShapeVertices[x], - useNormal, blendShapeNormals[x], - useTangent, blendShapeTangents[x])) - .ToArray() - ; - - if (sparseIndices.Length == 0) - { - usePosition = false; - useNormal = false; - useTangent = false; - } - else - { - Debug.LogFormat("Sparse {0}/{1}", sparseIndices.Length, mesh.vertexCount); - } - /* - var vertexSize = 12; - if (useNormal) vertexSize += 12; - if (useTangent) vertexSize += 24; - var sparseBytes = (4 + vertexSize) * sparseIndices.Length; - var fullBytes = (vertexSize) * blendShapeVertices.Length; - Debug.LogFormat("Export sparse: {0}/{1}bytes({2}%)", - sparseBytes, fullBytes, (int)((float)sparseBytes / fullBytes) - ); - */ - - var sparseIndicesViewIndex = -1; - if (usePosition) - { - sparseIndicesViewIndex = gltf.ExtendBufferAndGetViewIndex(bufferIndex, sparseIndices); - - blendShapeVertices = sparseIndices.Select(x => blendShapeVertices[x].ReverseZ()).ToArray(); - blendShapePositionAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, - blendShapeVertices, - sparseIndices, sparseIndicesViewIndex, - glBufferTarget.ARRAY_BUFFER); - } - - if (useNormal) - { - blendShapeNormals = sparseIndices.Select(x => blendShapeNormals[x].ReverseZ()).ToArray(); - blendShapeNormalAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, - blendShapeNormals, - sparseIndices, sparseIndicesViewIndex, - glBufferTarget.ARRAY_BUFFER); - } - - if (useTangent) - { - blendShapeTangents = sparseIndices.Select(x => blendShapeTangents[x].ReverseZ()).ToArray(); - blendShapeTangentAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, - blendShapeTangents, sparseIndices, sparseIndicesViewIndex, - glBufferTarget.ARRAY_BUFFER); - } - } - else - { - for (int i = 0; i < blendShapeVertices.Length; ++i) blendShapeVertices[i] = blendShapeVertices[i].ReverseZ(); - if (usePosition) - { - blendShapePositionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, - blendShapeVertices, - glBufferTarget.ARRAY_BUFFER); - } - - if (useNormal) - { - for (int i = 0; i < blendShapeNormals.Length; ++i) blendShapeNormals[i] = blendShapeNormals[i].ReverseZ(); - blendShapeNormalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, - blendShapeNormals, - glBufferTarget.ARRAY_BUFFER); - } - - if (useTangent) - { - for (int i = 0; i < blendShapeTangents.Length; ++i) blendShapeTangents[i] = blendShapeTangents[i].ReverseZ(); - blendShapeTangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, - blendShapeTangents, - glBufferTarget.ARRAY_BUFFER); - } - } - - if (blendShapePositionAccessorIndex != -1) - { - gltf.accessors[blendShapePositionAccessorIndex].min = blendShapeVertices.Aggregate(blendShapeVertices[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray(); - gltf.accessors[blendShapePositionAccessorIndex].max = blendShapeVertices.Aggregate(blendShapeVertices[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray(); - } - - return new gltfMorphTarget - { - POSITION = blendShapePositionAccessorIndex, - NORMAL = blendShapeNormalAccessorIndex, - TANGENT = blendShapeTangentAccessorIndex, - }; - } - - public static void ExportMeshes(glTF gltf, int bufferIndex, - List unityMeshes, List unityMaterials, - bool useSparseAccessorForMorphTarget) - { - for (int i = 0; i < unityMeshes.Count; ++i) - { - var x = unityMeshes[i]; - var mesh = x.Mesh; - var materials = x.Rendererer.sharedMaterials; - - var gltfMesh = ExportPrimitives(gltf, bufferIndex, - x.Rendererer.name, - mesh, materials, unityMaterials); - - for (int j = 0; j < mesh.blendShapeCount; ++j) - { - var morphTarget = ExportMorphTarget(gltf, bufferIndex, - mesh, j, - useSparseAccessorForMorphTarget); - - // - // all primitive has same blendShape - // - for (int k = 0; k < gltfMesh.primitives.Count; ++k) - { - gltfMesh.primitives[k].targets.Add(morphTarget); - gltfMesh.primitives[k].extras.targetNames.Add(mesh.GetBlendShapeName(j)); - } - } - - gltf.meshes.Add(gltfMesh); - } - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace UniGLTF +{ + public struct MeshWithRenderer + { + public Mesh Mesh; + public Renderer Rendererer; + } + + public static class MeshExporter + { + static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex, + string rendererName, + Mesh mesh, Material[] materials, + List unityMaterials) + { + var positions = mesh.vertices.Select(y => y.ReverseZ()).ToArray(); + var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, glBufferTarget.ARRAY_BUFFER); + gltf.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray(); + gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray(); + + var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); +#if GLTF_EXPORT_TANGENTS + var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); +#endif + var uvAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER); + var colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.ARRAY_BUFFER); + + var boneweights = mesh.boneWeights; + var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new Vector4(y.weight0, y.weight1, y.weight2, y.weight3)).ToArray(), glBufferTarget.ARRAY_BUFFER); + var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new UShort4((ushort)y.boneIndex0, (ushort)y.boneIndex1, (ushort)y.boneIndex2, (ushort)y.boneIndex3)).ToArray(), glBufferTarget.ARRAY_BUFFER); + + var attributes = new glTFAttributes + { + POSITION = positionAccessorIndex, + }; + if (normalAccessorIndex != -1) + { + attributes.NORMAL = normalAccessorIndex; + } +#if GLTF_EXPORT_TANGENTS + if (tangentAccessorIndex != -1) + { + attributes.TANGENT = tangentAccessorIndex; + } +#endif + if (uvAccessorIndex != -1) + { + attributes.TEXCOORD_0 = uvAccessorIndex; + } + if (colorAccessorIndex != -1) + { + attributes.COLOR_0 = colorAccessorIndex; + } + if (weightAccessorIndex != -1) + { + attributes.WEIGHTS_0 = weightAccessorIndex; + } + if (jointsAccessorIndex != -1) + { + attributes.JOINTS_0 = jointsAccessorIndex; + } + + var gltfMesh = new glTFMesh(mesh.name); + for (int j = 0; j < mesh.subMeshCount; ++j) + { + var indices = TriangleUtil.FlipTriangle(mesh.GetIndices(j)).Select(y => (uint)y).ToArray(); + var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices, glBufferTarget.ELEMENT_ARRAY_BUFFER); + + if (j >= materials.Length) + { + Debug.LogWarningFormat("{0}.materials is not enough", rendererName); + break; + } + + gltfMesh.primitives.Add(new glTFPrimitives + { + attributes = attributes, + indices = indicesAccessorIndex, + mode = 4, // triangels ? + material = unityMaterials.IndexOf(materials[j]) + }); + } + return gltfMesh; + } + + static bool UseSparse( + bool usePosition, Vector3 position, + bool useNormal, Vector3 normal, + bool useTangent, Vector3 tangent + ) + { + var useSparse = + (usePosition && position != Vector3.zero) + || (useNormal && normal != Vector3.zero) + || (useTangent && tangent != Vector3.zero) + ; + return useSparse; + } + + static gltfMorphTarget ExportMorphTarget(glTF gltf, int bufferIndex, + Mesh mesh, int j, + bool useSparseAccessorForMorphTarget) + { + var blendShapeVertices = mesh.vertices; + var usePosition = blendShapeVertices != null && blendShapeVertices.Length > 0; + + var blendShapeNormals = mesh.normals; + var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length; + + var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray(); + //var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length; + var useTangent = false; + + var frameCount = mesh.GetBlendShapeFrameCount(j); + mesh.GetBlendShapeFrameVertices(j, frameCount - 1, blendShapeVertices, blendShapeNormals, null); + + var blendShapePositionAccessorIndex = -1; + var blendShapeNormalAccessorIndex = -1; + var blendShapeTangentAccessorIndex = -1; + if (useSparseAccessorForMorphTarget) + { + var accessorCount = blendShapeVertices.Length; + var sparseIndices = Enumerable.Range(0, blendShapeVertices.Length) + .Where(x => UseSparse( + usePosition, blendShapeVertices[x], + useNormal, blendShapeNormals[x], + useTangent, blendShapeTangents[x])) + .ToArray() + ; + + if (sparseIndices.Length == 0) + { + usePosition = false; + useNormal = false; + useTangent = false; + } + else + { + Debug.LogFormat("Sparse {0}/{1}", sparseIndices.Length, mesh.vertexCount); + } + /* + var vertexSize = 12; + if (useNormal) vertexSize += 12; + if (useTangent) vertexSize += 24; + var sparseBytes = (4 + vertexSize) * sparseIndices.Length; + var fullBytes = (vertexSize) * blendShapeVertices.Length; + Debug.LogFormat("Export sparse: {0}/{1}bytes({2}%)", + sparseBytes, fullBytes, (int)((float)sparseBytes / fullBytes) + ); + */ + + var sparseIndicesViewIndex = -1; + if (usePosition) + { + sparseIndicesViewIndex = gltf.ExtendBufferAndGetViewIndex(bufferIndex, sparseIndices); + + blendShapeVertices = sparseIndices.Select(x => blendShapeVertices[x].ReverseZ()).ToArray(); + blendShapePositionAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, + blendShapeVertices, + sparseIndices, sparseIndicesViewIndex, + glBufferTarget.ARRAY_BUFFER); + } + + if (useNormal) + { + blendShapeNormals = sparseIndices.Select(x => blendShapeNormals[x].ReverseZ()).ToArray(); + blendShapeNormalAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, + blendShapeNormals, + sparseIndices, sparseIndicesViewIndex, + glBufferTarget.ARRAY_BUFFER); + } + + if (useTangent) + { + blendShapeTangents = sparseIndices.Select(x => blendShapeTangents[x].ReverseZ()).ToArray(); + blendShapeTangentAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, + blendShapeTangents, sparseIndices, sparseIndicesViewIndex, + glBufferTarget.ARRAY_BUFFER); + } + } + else + { + for (int i = 0; i < blendShapeVertices.Length; ++i) blendShapeVertices[i] = blendShapeVertices[i].ReverseZ(); + if (usePosition) + { + blendShapePositionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, + blendShapeVertices, + glBufferTarget.ARRAY_BUFFER); + } + + if (useNormal) + { + for (int i = 0; i < blendShapeNormals.Length; ++i) blendShapeNormals[i] = blendShapeNormals[i].ReverseZ(); + blendShapeNormalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, + blendShapeNormals, + glBufferTarget.ARRAY_BUFFER); + } + + if (useTangent) + { + for (int i = 0; i < blendShapeTangents.Length; ++i) blendShapeTangents[i] = blendShapeTangents[i].ReverseZ(); + blendShapeTangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, + blendShapeTangents, + glBufferTarget.ARRAY_BUFFER); + } + } + + if (blendShapePositionAccessorIndex != -1) + { + gltf.accessors[blendShapePositionAccessorIndex].min = blendShapeVertices.Aggregate(blendShapeVertices[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray(); + gltf.accessors[blendShapePositionAccessorIndex].max = blendShapeVertices.Aggregate(blendShapeVertices[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray(); + } + + return new gltfMorphTarget + { + POSITION = blendShapePositionAccessorIndex, + NORMAL = blendShapeNormalAccessorIndex, + TANGENT = blendShapeTangentAccessorIndex, + }; + } + + public static void ExportMeshes(glTF gltf, int bufferIndex, + List unityMeshes, List unityMaterials, + bool useSparseAccessorForMorphTarget) + { + for (int i = 0; i < unityMeshes.Count; ++i) + { + var x = unityMeshes[i]; + var mesh = x.Mesh; + var materials = x.Rendererer.sharedMaterials; + + var gltfMesh = ExportPrimitives(gltf, bufferIndex, + x.Rendererer.name, + mesh, materials, unityMaterials); + + for (int j = 0; j < mesh.blendShapeCount; ++j) + { + var morphTarget = ExportMorphTarget(gltf, bufferIndex, + mesh, j, + useSparseAccessorForMorphTarget); + + // + // all primitive has same blendShape + // + for (int k = 0; k < gltfMesh.primitives.Count; ++k) + { + gltfMesh.primitives[k].targets.Add(morphTarget); + gltfMesh.primitives[k].extras.targetNames.Add(mesh.GetBlendShapeName(j)); + } + } + + gltf.meshes.Add(gltfMesh); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/MeshExporter.cs.meta b/UniGLTF/Scripts/IO/MeshExporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/MeshExporter.cs.meta rename to UniGLTF/Scripts/IO/MeshExporter.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/MeshImporter.cs b/UniGLTF/Scripts/IO/MeshImporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/MeshImporter.cs rename to UniGLTF/Scripts/IO/MeshImporter.cs index e9dbcf16c..f56f27a39 100644 --- a/UniGLTF/Core/Scripts/IO/MeshImporter.cs +++ b/UniGLTF/Scripts/IO/MeshImporter.cs @@ -1,561 +1,561 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using UnityEngine; - - -namespace UniGLTF -{ - public class MeshImporter - { - const float FRAME_WEIGHT = 100.0f; - - - // multiple submMesh is not sharing a VertexBuffer. - // each subMesh use a independent VertexBuffer. - private static MeshContext _ImportMeshIndependentVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh) - { - //Debug.LogWarning("_ImportMeshIndependentVertexBuffer"); - - var targets = gltfMesh.primitives[0].targets; - for (int i = 1; i < gltfMesh.primitives.Count; ++i) - { - if (!gltfMesh.primitives[i].targets.SequenceEqual(targets)) - { - throw new NotImplementedException(string.Format("diffirent targets: {0} with {1}", - gltfMesh.primitives[i], - targets)); - } - } - - var positions = new List(); - var normals = new List(); - var tangents = new List(); - var uv = new List(); - var colors = new List(); - var meshContext = new MeshContext(); - foreach (var prim in gltfMesh.primitives) - { - var indexOffset = positions.Count; - var indexBuffer = prim.indices; - - var positionCount = positions.Count; - positions.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.POSITION).Select(x => x.ReverseZ())); - positionCount = positions.Count - positionCount; - - // normal - if (prim.attributes.NORMAL != -1) - { - normals.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.NORMAL).Select(x => x.ReverseZ())); - } - - if (prim.attributes.TANGENT != -1) - { - tangents.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.TANGENT).Select(x => x.ReverseZ())); - } - - // uv - if (prim.attributes.TEXCOORD_0 != -1) - { - if (ctx.IsGeneratedUniGLTFAndOlder(1, 16)) - { -#pragma warning disable 0612 - // backward compatibility - uv.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.TEXCOORD_0).Select(x => x.ReverseY())); -#pragma warning restore 0612 - } - else - { - uv.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.TEXCOORD_0).Select(x => x.ReverseUV())); - } - } - else - { - // for inconsistent attributes in primitives - uv.AddRange(new Vector2[positionCount]); - } - - // color - if (prim.attributes.COLOR_0 != -1) - { - colors.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.COLOR_0)); - } - - // skin - if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1) - { - var joints0 = ctx.GLTF.GetArrayFromAccessor(prim.attributes.JOINTS_0); // uint4 - var weights0 = ctx.GLTF.GetArrayFromAccessor(prim.attributes.WEIGHTS_0).Select(x => x.One()).ToArray(); - - for (int j = 0; j < joints0.Length; ++j) - { - var bw = new BoneWeight(); - - bw.boneIndex0 = joints0[j].x; - bw.weight0 = weights0[j].x; - - bw.boneIndex1 = joints0[j].y; - bw.weight1 = weights0[j].y; - - bw.boneIndex2 = joints0[j].z; - bw.weight2 = weights0[j].z; - - bw.boneIndex3 = joints0[j].w; - bw.weight3 = weights0[j].w; - - meshContext.boneWeights.Add(bw); - } - } - - // blendshape - if (prim.targets != null && prim.targets.Count > 0) - { - for (int i = 0; i < prim.targets.Count; ++i) - { - //var name = string.Format("target{0}", i++); - var primTarget = prim.targets[i]; - var blendShape = new BlendShape(!string.IsNullOrEmpty(prim.extras.targetNames[i]) - ? prim.extras.targetNames[i] - : i.ToString()) - ; - if (primTarget.POSITION != -1) - { - blendShape.Positions.AddRange( - ctx.GLTF.GetArrayFromAccessor(primTarget.POSITION).Select(x => x.ReverseZ()).ToArray()); - } - if (primTarget.NORMAL != -1) - { - blendShape.Normals.AddRange( - ctx.GLTF.GetArrayFromAccessor(primTarget.NORMAL).Select(x => x.ReverseZ()).ToArray()); - } - if (primTarget.TANGENT != -1) - { - blendShape.Tangents.AddRange( - ctx.GLTF.GetArrayFromAccessor(primTarget.TANGENT).Select(x => x.ReverseZ()).ToArray()); - } - meshContext.blendShapes.Add(blendShape); - } - } - - var indices = - (indexBuffer >= 0) - ? ctx.GLTF.GetIndices(indexBuffer) - : TriangleUtil.FlipTriangle(Enumerable.Range(0, meshContext.positions.Length)).ToArray() // without index array - ; - for (int i = 0; i < indices.Length; ++i) - { - indices[i] += indexOffset; - } - - meshContext.subMeshes.Add(indices); - - // material - meshContext.materialIndices.Add(prim.material); - } - - meshContext.positions = positions.ToArray(); - meshContext.normals = normals.ToArray(); - meshContext.tangents = tangents.ToArray(); - meshContext.uv = uv.ToArray(); - - return meshContext; - } - - - // multiple submesh sharing same VertexBuffer - private static MeshContext _ImportMeshSharingVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh) - { - var context = new MeshContext(); - - { - var prim = gltfMesh.primitives.First(); - context.positions = ctx.GLTF.GetArrayFromAccessor(prim.attributes.POSITION).SelectInplace(x => x.ReverseZ()); - - // normal - if (prim.attributes.NORMAL != -1) - { - context.normals = ctx.GLTF.GetArrayFromAccessor(prim.attributes.NORMAL).SelectInplace(x => x.ReverseZ()); - } - - // tangent - if (prim.attributes.TANGENT != -1) - { - context.tangents = ctx.GLTF.GetArrayFromAccessor(prim.attributes.TANGENT).SelectInplace(x => x.ReverseZ()); - } - - // uv - if (prim.attributes.TEXCOORD_0 != -1) - { - if (ctx.IsGeneratedUniGLTFAndOlder(1, 16)) - { -#pragma warning disable 0612 - // backward compatibility - context.uv = ctx.GLTF.GetArrayFromAccessor(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseY()); -#pragma warning restore 0612 - } - else - { - context.uv = ctx.GLTF.GetArrayFromAccessor(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseUV()); - } - } - else - { - // for inconsistent attributes in primitives - context.uv = new Vector2[context.positions.Length]; - } - - // color - if (prim.attributes.COLOR_0 != -1) - { - context.colors = ctx.GLTF.GetArrayFromAccessor(prim.attributes.COLOR_0); - } - - // skin - if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1) - { - var joints0 = ctx.GLTF.GetArrayFromAccessor(prim.attributes.JOINTS_0); // uint4 - var weights0 = ctx.GLTF.GetArrayFromAccessor(prim.attributes.WEIGHTS_0); - for (int i = 0; i < weights0.Length; ++i) - { - weights0[i] = weights0[i].One(); - } - - for (int j = 0; j < joints0.Length; ++j) - { - var bw = new BoneWeight(); - - bw.boneIndex0 = joints0[j].x; - bw.weight0 = weights0[j].x; - - bw.boneIndex1 = joints0[j].y; - bw.weight1 = weights0[j].y; - - bw.boneIndex2 = joints0[j].z; - bw.weight2 = weights0[j].z; - - bw.boneIndex3 = joints0[j].w; - bw.weight3 = weights0[j].w; - - context.boneWeights.Add(bw); - } - } - - // blendshape - if (prim.targets != null && prim.targets.Count > 0) - { - context.blendShapes.AddRange(prim.targets.Select((x, i) => new BlendShape( - i < prim.extras.targetNames.Count && !string.IsNullOrEmpty(prim.extras.targetNames[i]) - ? prim.extras.targetNames[i] - : i.ToString()))); - for (int i = 0; i < prim.targets.Count; ++i) - { - //var name = string.Format("target{0}", i++); - var primTarget = prim.targets[i]; - var blendShape = context.blendShapes[i]; - - if (primTarget.POSITION != -1) - { - blendShape.Positions.Assign( - ctx.GLTF.GetArrayFromAccessor(primTarget.POSITION), x => x.ReverseZ()); - } - if (primTarget.NORMAL != -1) - { - blendShape.Normals.Assign( - ctx.GLTF.GetArrayFromAccessor(primTarget.NORMAL), x => x.ReverseZ()); - } - if (primTarget.TANGENT != -1) - { - blendShape.Tangents.Assign( - ctx.GLTF.GetArrayFromAccessor(primTarget.TANGENT), x => x.ReverseZ()); - } - } - } - } - - foreach (var prim in gltfMesh.primitives) - { - if (prim.indices == -1) - { - context.subMeshes.Add(TriangleUtil.FlipTriangle(Enumerable.Range(0, context.positions.Length)).ToArray()); - } - else - { - var indices = ctx.GLTF.GetIndices(prim.indices); - context.subMeshes.Add(indices); - } - - // material - context.materialIndices.Add(prim.material); - } - - return context; - } - - - [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)] - struct Float4 - { - public float x; - public float y; - public float z; - public float w; - - public Float4 One() - { - var sum = x + y + z + w; - var f = 1.0f / sum; - return new Float4 - { - x = x * f, - y = y * f, - z = z * f, - w = w * f, - }; - } - } - - - public class MeshContext - { - public string name; - public Vector3[] positions; - public Vector3[] normals; - public Vector4[] tangents; - public Vector2[] uv; - public Color[] colors; - public List boneWeights = new List(); - public List subMeshes = new List(); - public List materialIndices = new List(); - public List blendShapes = new List(); - } - - - public MeshContext ReadMesh(ImporterContext ctx, int meshIndex) - { - var gltfMesh = ctx.GLTF.meshes[meshIndex]; - glTFAttributes lastAttributes = null; - var sharedAttributes = true; - foreach (var prim in gltfMesh.primitives) - { - if (lastAttributes != null && !prim.attributes.Equals(lastAttributes)) - { - sharedAttributes = false; - break; - } - lastAttributes = prim.attributes; - } - - var meshContext = sharedAttributes - ? _ImportMeshSharingVertexBuffer(ctx, gltfMesh) - : _ImportMeshIndependentVertexBuffer(ctx, gltfMesh) - ; - meshContext.name = gltfMesh.name; - if (string.IsNullOrEmpty(meshContext.name)) - { - meshContext.name = string.Format("UniGLTF import#{0}", meshIndex); - } - - return meshContext; - } - - - public static MeshWithMaterials BuildMesh(ImporterContext ctx, MeshImporter.MeshContext meshContext) - { - if (!meshContext.materialIndices.Any()) - { - meshContext.materialIndices.Add(0); - } - - //Debug.Log(prims.ToJson()); - var mesh = new Mesh(); - mesh.name = meshContext.name; - - if (meshContext.positions.Length > UInt16.MaxValue) - { -#if UNITY_2017_3_OR_NEWER - mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; -#else - Debug.LogWarningFormat("vertices {0} exceed 65535. not implemented. Unity2017.3 supports large mesh", - meshContext.positions.Length); -#endif - } - - mesh.vertices = meshContext.positions; - bool recalculateNormals = false; - if (meshContext.normals != null && meshContext.normals.Length > 0) - { - mesh.normals = meshContext.normals; - } - else - { - recalculateNormals = true; - } - - if (meshContext.uv != null && meshContext.uv.Length > 0) - { - mesh.uv = meshContext.uv; - } - - bool recalculateTangents = true; -#if UNIGLTF_IMPORT_TANGENTS - if (meshContext.tangents != null && meshContext.tangents.Length > 0) - { - mesh.tangents = meshContext.tangents; - recalculateTangents = false; - } -#endif - - if (meshContext.colors != null && meshContext.colors.Length > 0) - { - mesh.colors = meshContext.colors; - } - if (meshContext.boneWeights != null && meshContext.boneWeights.Count > 0) - { - mesh.boneWeights = meshContext.boneWeights.ToArray(); - } - mesh.subMeshCount = meshContext.subMeshes.Count; - for (int i = 0; i < meshContext.subMeshes.Count; ++i) - { - mesh.SetTriangles(meshContext.subMeshes[i], i); - } - - if (recalculateNormals) - { - mesh.RecalculateNormals(); - } - if (recalculateTangents) - { -#if UNITY_5_6_OR_NEWER - mesh.RecalculateTangents(); -#else - CalcTangents(mesh); -#endif - } - - var result = new MeshWithMaterials - { - Mesh = mesh, - Materials = meshContext.materialIndices.Select(x => ctx.GetMaterial(x)).ToArray() - }; - - if (meshContext.blendShapes != null) - { - Vector3[] emptyVertices = null; - foreach (var blendShape in meshContext.blendShapes) - { - if (blendShape.Positions.Count > 0) - { - if (blendShape.Positions.Count == mesh.vertexCount) - { - mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, - blendShape.Positions.ToArray(), - (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount) ? blendShape.Normals.ToArray() : null, - null - ); - } - else - { - Debug.LogWarningFormat("May be partial primitive has blendShape. Rquire separete mesh or extend blend shape, but not implemented: {0}", blendShape.Name); - } - } - else - { - if (emptyVertices == null) - { - emptyVertices = new Vector3[mesh.vertexCount]; - } - // Debug.LogFormat("empty blendshape: {0}.{1}", mesh.name, blendShape.Name); - // add empty blend shape for keep blend shape index - mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, - emptyVertices, - null, - null - ); - } - } - } - - return result; - } - - /// - /// Meshの法線を元にタンジェントを計算する。 - /// - /// メッシュ - /// タンジェント - public static void CalcTangents(Mesh mesh) - { - int vertexCount = mesh.vertexCount; - Vector3[] vertices = mesh.vertices; - Vector3[] normals = mesh.normals; - Vector2[] texcoords = mesh.uv; - int[] triangles = mesh.triangles; - int triangleCount = triangles.Length / 3; - - Vector4[] tangents = new Vector4[vertexCount]; - Vector3[] tan1 = new Vector3[vertexCount]; - Vector3[] tan2 = new Vector3[vertexCount]; - - int tri = 0; - - for (int i = 0; i < (triangleCount); i++) - { - int i1 = triangles[tri]; - int i2 = triangles[tri + 1]; - int i3 = triangles[tri + 2]; - - Vector3 v1 = vertices[i1]; - Vector3 v2 = vertices[i2]; - Vector3 v3 = vertices[i3]; - - Vector2 w1 = texcoords[i1]; - Vector2 w2 = texcoords[i2]; - Vector2 w3 = texcoords[i3]; - - float x1 = v2.x - v1.x; - float x2 = v3.x - v1.x; - float y1 = v2.y - v1.y; - float y2 = v3.y - v1.y; - float z1 = v2.z - v1.z; - float z2 = v3.z - v1.z; - - float s1 = w2.x - w1.x; - float s2 = w3.x - w1.x; - float t1 = w2.y - w1.y; - float t2 = w3.y - w1.y; - - float r = 1.0f / (s1 * t2 - s2 * t1); - Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); - Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); - - tan1[i1] += sdir; - tan1[i2] += sdir; - tan1[i3] += sdir; - - tan2[i1] += tdir; - tan2[i2] += tdir; - tan2[i3] += tdir; - - tri += 3; - } - - for (int i = 0; i < (vertexCount); i++) - { - Vector3 n = normals[i]; - Vector3 t = tan1[i]; - - // Gram-Schmidt orthogonalize - Vector3.OrthoNormalize(ref n, ref t); - tangents[i].x = t.x; - tangents[i].y = t.y; - tangents[i].z = t.z; - - // Calculate handedness - tangents[i].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[i]) < 0.0f) ? -1.0f : 1.0f; - } - - mesh.tangents = tangents; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using UnityEngine; + + +namespace UniGLTF +{ + public class MeshImporter + { + const float FRAME_WEIGHT = 100.0f; + + + // multiple submMesh is not sharing a VertexBuffer. + // each subMesh use a independent VertexBuffer. + private static MeshContext _ImportMeshIndependentVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh) + { + //Debug.LogWarning("_ImportMeshIndependentVertexBuffer"); + + var targets = gltfMesh.primitives[0].targets; + for (int i = 1; i < gltfMesh.primitives.Count; ++i) + { + if (!gltfMesh.primitives[i].targets.SequenceEqual(targets)) + { + throw new NotImplementedException(string.Format("diffirent targets: {0} with {1}", + gltfMesh.primitives[i], + targets)); + } + } + + var positions = new List(); + var normals = new List(); + var tangents = new List(); + var uv = new List(); + var colors = new List(); + var meshContext = new MeshContext(); + foreach (var prim in gltfMesh.primitives) + { + var indexOffset = positions.Count; + var indexBuffer = prim.indices; + + var positionCount = positions.Count; + positions.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.POSITION).Select(x => x.ReverseZ())); + positionCount = positions.Count - positionCount; + + // normal + if (prim.attributes.NORMAL != -1) + { + normals.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.NORMAL).Select(x => x.ReverseZ())); + } + + if (prim.attributes.TANGENT != -1) + { + tangents.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.TANGENT).Select(x => x.ReverseZ())); + } + + // uv + if (prim.attributes.TEXCOORD_0 != -1) + { + if (ctx.IsGeneratedUniGLTFAndOlder(1, 16)) + { +#pragma warning disable 0612 + // backward compatibility + uv.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.TEXCOORD_0).Select(x => x.ReverseY())); +#pragma warning restore 0612 + } + else + { + uv.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.TEXCOORD_0).Select(x => x.ReverseUV())); + } + } + else + { + // for inconsistent attributes in primitives + uv.AddRange(new Vector2[positionCount]); + } + + // color + if (prim.attributes.COLOR_0 != -1) + { + colors.AddRange(ctx.GLTF.GetArrayFromAccessor(prim.attributes.COLOR_0)); + } + + // skin + if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1) + { + var joints0 = ctx.GLTF.GetArrayFromAccessor(prim.attributes.JOINTS_0); // uint4 + var weights0 = ctx.GLTF.GetArrayFromAccessor(prim.attributes.WEIGHTS_0).Select(x => x.One()).ToArray(); + + for (int j = 0; j < joints0.Length; ++j) + { + var bw = new BoneWeight(); + + bw.boneIndex0 = joints0[j].x; + bw.weight0 = weights0[j].x; + + bw.boneIndex1 = joints0[j].y; + bw.weight1 = weights0[j].y; + + bw.boneIndex2 = joints0[j].z; + bw.weight2 = weights0[j].z; + + bw.boneIndex3 = joints0[j].w; + bw.weight3 = weights0[j].w; + + meshContext.boneWeights.Add(bw); + } + } + + // blendshape + if (prim.targets != null && prim.targets.Count > 0) + { + for (int i = 0; i < prim.targets.Count; ++i) + { + //var name = string.Format("target{0}", i++); + var primTarget = prim.targets[i]; + var blendShape = new BlendShape(!string.IsNullOrEmpty(prim.extras.targetNames[i]) + ? prim.extras.targetNames[i] + : i.ToString()) + ; + if (primTarget.POSITION != -1) + { + blendShape.Positions.AddRange( + ctx.GLTF.GetArrayFromAccessor(primTarget.POSITION).Select(x => x.ReverseZ()).ToArray()); + } + if (primTarget.NORMAL != -1) + { + blendShape.Normals.AddRange( + ctx.GLTF.GetArrayFromAccessor(primTarget.NORMAL).Select(x => x.ReverseZ()).ToArray()); + } + if (primTarget.TANGENT != -1) + { + blendShape.Tangents.AddRange( + ctx.GLTF.GetArrayFromAccessor(primTarget.TANGENT).Select(x => x.ReverseZ()).ToArray()); + } + meshContext.blendShapes.Add(blendShape); + } + } + + var indices = + (indexBuffer >= 0) + ? ctx.GLTF.GetIndices(indexBuffer) + : TriangleUtil.FlipTriangle(Enumerable.Range(0, meshContext.positions.Length)).ToArray() // without index array + ; + for (int i = 0; i < indices.Length; ++i) + { + indices[i] += indexOffset; + } + + meshContext.subMeshes.Add(indices); + + // material + meshContext.materialIndices.Add(prim.material); + } + + meshContext.positions = positions.ToArray(); + meshContext.normals = normals.ToArray(); + meshContext.tangents = tangents.ToArray(); + meshContext.uv = uv.ToArray(); + + return meshContext; + } + + + // multiple submesh sharing same VertexBuffer + private static MeshContext _ImportMeshSharingVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh) + { + var context = new MeshContext(); + + { + var prim = gltfMesh.primitives.First(); + context.positions = ctx.GLTF.GetArrayFromAccessor(prim.attributes.POSITION).SelectInplace(x => x.ReverseZ()); + + // normal + if (prim.attributes.NORMAL != -1) + { + context.normals = ctx.GLTF.GetArrayFromAccessor(prim.attributes.NORMAL).SelectInplace(x => x.ReverseZ()); + } + + // tangent + if (prim.attributes.TANGENT != -1) + { + context.tangents = ctx.GLTF.GetArrayFromAccessor(prim.attributes.TANGENT).SelectInplace(x => x.ReverseZ()); + } + + // uv + if (prim.attributes.TEXCOORD_0 != -1) + { + if (ctx.IsGeneratedUniGLTFAndOlder(1, 16)) + { +#pragma warning disable 0612 + // backward compatibility + context.uv = ctx.GLTF.GetArrayFromAccessor(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseY()); +#pragma warning restore 0612 + } + else + { + context.uv = ctx.GLTF.GetArrayFromAccessor(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseUV()); + } + } + else + { + // for inconsistent attributes in primitives + context.uv = new Vector2[context.positions.Length]; + } + + // color + if (prim.attributes.COLOR_0 != -1) + { + context.colors = ctx.GLTF.GetArrayFromAccessor(prim.attributes.COLOR_0); + } + + // skin + if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1) + { + var joints0 = ctx.GLTF.GetArrayFromAccessor(prim.attributes.JOINTS_0); // uint4 + var weights0 = ctx.GLTF.GetArrayFromAccessor(prim.attributes.WEIGHTS_0); + for (int i = 0; i < weights0.Length; ++i) + { + weights0[i] = weights0[i].One(); + } + + for (int j = 0; j < joints0.Length; ++j) + { + var bw = new BoneWeight(); + + bw.boneIndex0 = joints0[j].x; + bw.weight0 = weights0[j].x; + + bw.boneIndex1 = joints0[j].y; + bw.weight1 = weights0[j].y; + + bw.boneIndex2 = joints0[j].z; + bw.weight2 = weights0[j].z; + + bw.boneIndex3 = joints0[j].w; + bw.weight3 = weights0[j].w; + + context.boneWeights.Add(bw); + } + } + + // blendshape + if (prim.targets != null && prim.targets.Count > 0) + { + context.blendShapes.AddRange(prim.targets.Select((x, i) => new BlendShape( + i < prim.extras.targetNames.Count && !string.IsNullOrEmpty(prim.extras.targetNames[i]) + ? prim.extras.targetNames[i] + : i.ToString()))); + for (int i = 0; i < prim.targets.Count; ++i) + { + //var name = string.Format("target{0}", i++); + var primTarget = prim.targets[i]; + var blendShape = context.blendShapes[i]; + + if (primTarget.POSITION != -1) + { + blendShape.Positions.Assign( + ctx.GLTF.GetArrayFromAccessor(primTarget.POSITION), x => x.ReverseZ()); + } + if (primTarget.NORMAL != -1) + { + blendShape.Normals.Assign( + ctx.GLTF.GetArrayFromAccessor(primTarget.NORMAL), x => x.ReverseZ()); + } + if (primTarget.TANGENT != -1) + { + blendShape.Tangents.Assign( + ctx.GLTF.GetArrayFromAccessor(primTarget.TANGENT), x => x.ReverseZ()); + } + } + } + } + + foreach (var prim in gltfMesh.primitives) + { + if (prim.indices == -1) + { + context.subMeshes.Add(TriangleUtil.FlipTriangle(Enumerable.Range(0, context.positions.Length)).ToArray()); + } + else + { + var indices = ctx.GLTF.GetIndices(prim.indices); + context.subMeshes.Add(indices); + } + + // material + context.materialIndices.Add(prim.material); + } + + return context; + } + + + [Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)] + struct Float4 + { + public float x; + public float y; + public float z; + public float w; + + public Float4 One() + { + var sum = x + y + z + w; + var f = 1.0f / sum; + return new Float4 + { + x = x * f, + y = y * f, + z = z * f, + w = w * f, + }; + } + } + + + public class MeshContext + { + public string name; + public Vector3[] positions; + public Vector3[] normals; + public Vector4[] tangents; + public Vector2[] uv; + public Color[] colors; + public List boneWeights = new List(); + public List subMeshes = new List(); + public List materialIndices = new List(); + public List blendShapes = new List(); + } + + + public MeshContext ReadMesh(ImporterContext ctx, int meshIndex) + { + var gltfMesh = ctx.GLTF.meshes[meshIndex]; + glTFAttributes lastAttributes = null; + var sharedAttributes = true; + foreach (var prim in gltfMesh.primitives) + { + if (lastAttributes != null && !prim.attributes.Equals(lastAttributes)) + { + sharedAttributes = false; + break; + } + lastAttributes = prim.attributes; + } + + var meshContext = sharedAttributes + ? _ImportMeshSharingVertexBuffer(ctx, gltfMesh) + : _ImportMeshIndependentVertexBuffer(ctx, gltfMesh) + ; + meshContext.name = gltfMesh.name; + if (string.IsNullOrEmpty(meshContext.name)) + { + meshContext.name = string.Format("UniGLTF import#{0}", meshIndex); + } + + return meshContext; + } + + + public static MeshWithMaterials BuildMesh(ImporterContext ctx, MeshImporter.MeshContext meshContext) + { + if (!meshContext.materialIndices.Any()) + { + meshContext.materialIndices.Add(0); + } + + //Debug.Log(prims.ToJson()); + var mesh = new Mesh(); + mesh.name = meshContext.name; + + if (meshContext.positions.Length > UInt16.MaxValue) + { +#if UNITY_2017_3_OR_NEWER + mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; +#else + Debug.LogWarningFormat("vertices {0} exceed 65535. not implemented. Unity2017.3 supports large mesh", + meshContext.positions.Length); +#endif + } + + mesh.vertices = meshContext.positions; + bool recalculateNormals = false; + if (meshContext.normals != null && meshContext.normals.Length > 0) + { + mesh.normals = meshContext.normals; + } + else + { + recalculateNormals = true; + } + + if (meshContext.uv != null && meshContext.uv.Length > 0) + { + mesh.uv = meshContext.uv; + } + + bool recalculateTangents = true; +#if UNIGLTF_IMPORT_TANGENTS + if (meshContext.tangents != null && meshContext.tangents.Length > 0) + { + mesh.tangents = meshContext.tangents; + recalculateTangents = false; + } +#endif + + if (meshContext.colors != null && meshContext.colors.Length > 0) + { + mesh.colors = meshContext.colors; + } + if (meshContext.boneWeights != null && meshContext.boneWeights.Count > 0) + { + mesh.boneWeights = meshContext.boneWeights.ToArray(); + } + mesh.subMeshCount = meshContext.subMeshes.Count; + for (int i = 0; i < meshContext.subMeshes.Count; ++i) + { + mesh.SetTriangles(meshContext.subMeshes[i], i); + } + + if (recalculateNormals) + { + mesh.RecalculateNormals(); + } + if (recalculateTangents) + { +#if UNITY_5_6_OR_NEWER + mesh.RecalculateTangents(); +#else + CalcTangents(mesh); +#endif + } + + var result = new MeshWithMaterials + { + Mesh = mesh, + Materials = meshContext.materialIndices.Select(x => ctx.GetMaterial(x)).ToArray() + }; + + if (meshContext.blendShapes != null) + { + Vector3[] emptyVertices = null; + foreach (var blendShape in meshContext.blendShapes) + { + if (blendShape.Positions.Count > 0) + { + if (blendShape.Positions.Count == mesh.vertexCount) + { + mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, + blendShape.Positions.ToArray(), + (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount) ? blendShape.Normals.ToArray() : null, + null + ); + } + else + { + Debug.LogWarningFormat("May be partial primitive has blendShape. Rquire separete mesh or extend blend shape, but not implemented: {0}", blendShape.Name); + } + } + else + { + if (emptyVertices == null) + { + emptyVertices = new Vector3[mesh.vertexCount]; + } + // Debug.LogFormat("empty blendshape: {0}.{1}", mesh.name, blendShape.Name); + // add empty blend shape for keep blend shape index + mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, + emptyVertices, + null, + null + ); + } + } + } + + return result; + } + + /// + /// Meshの法線を元にタンジェントを計算する。 + /// + /// メッシュ + /// タンジェント + public static void CalcTangents(Mesh mesh) + { + int vertexCount = mesh.vertexCount; + Vector3[] vertices = mesh.vertices; + Vector3[] normals = mesh.normals; + Vector2[] texcoords = mesh.uv; + int[] triangles = mesh.triangles; + int triangleCount = triangles.Length / 3; + + Vector4[] tangents = new Vector4[vertexCount]; + Vector3[] tan1 = new Vector3[vertexCount]; + Vector3[] tan2 = new Vector3[vertexCount]; + + int tri = 0; + + for (int i = 0; i < (triangleCount); i++) + { + int i1 = triangles[tri]; + int i2 = triangles[tri + 1]; + int i3 = triangles[tri + 2]; + + Vector3 v1 = vertices[i1]; + Vector3 v2 = vertices[i2]; + Vector3 v3 = vertices[i3]; + + Vector2 w1 = texcoords[i1]; + Vector2 w2 = texcoords[i2]; + Vector2 w3 = texcoords[i3]; + + float x1 = v2.x - v1.x; + float x2 = v3.x - v1.x; + float y1 = v2.y - v1.y; + float y2 = v3.y - v1.y; + float z1 = v2.z - v1.z; + float z2 = v3.z - v1.z; + + float s1 = w2.x - w1.x; + float s2 = w3.x - w1.x; + float t1 = w2.y - w1.y; + float t2 = w3.y - w1.y; + + float r = 1.0f / (s1 * t2 - s2 * t1); + Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); + Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); + + tan1[i1] += sdir; + tan1[i2] += sdir; + tan1[i3] += sdir; + + tan2[i1] += tdir; + tan2[i2] += tdir; + tan2[i3] += tdir; + + tri += 3; + } + + for (int i = 0; i < (vertexCount); i++) + { + Vector3 n = normals[i]; + Vector3 t = tan1[i]; + + // Gram-Schmidt orthogonalize + Vector3.OrthoNormalize(ref n, ref t); + tangents[i].x = t.x; + tangents[i].y = t.y; + tangents[i].z = t.z; + + // Calculate handedness + tangents[i].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[i]) < 0.0f) ? -1.0f : 1.0f; + } + + mesh.tangents = tangents; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/MeshImporter.cs.meta b/UniGLTF/Scripts/IO/MeshImporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/MeshImporter.cs.meta rename to UniGLTF/Scripts/IO/MeshImporter.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/MeshWithMaterials.cs b/UniGLTF/Scripts/IO/MeshWithMaterials.cs similarity index 95% rename from UniGLTF/Core/Scripts/IO/MeshWithMaterials.cs rename to UniGLTF/Scripts/IO/MeshWithMaterials.cs index fb0a72b1a..56838167b 100644 --- a/UniGLTF/Core/Scripts/IO/MeshWithMaterials.cs +++ b/UniGLTF/Scripts/IO/MeshWithMaterials.cs @@ -1,13 +1,13 @@ -using System.Collections.Generic; -using UnityEngine; - - -namespace UniGLTF -{ - public class MeshWithMaterials - { - public Mesh Mesh; - public Material[] Materials; - public List Renderers=new List(); // SkinnedMeshRenderer or MeshRenderer - } -} +using System.Collections.Generic; +using UnityEngine; + + +namespace UniGLTF +{ + public class MeshWithMaterials + { + public Mesh Mesh; + public Material[] Materials; + public List Renderers=new List(); // SkinnedMeshRenderer or MeshRenderer + } +} diff --git a/UniGLTF/Core/Scripts/IO/MeshWithMaterials.cs.meta b/UniGLTF/Scripts/IO/MeshWithMaterials.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/MeshWithMaterials.cs.meta rename to UniGLTF/Scripts/IO/MeshWithMaterials.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/NodeImporter.cs b/UniGLTF/Scripts/IO/NodeImporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/NodeImporter.cs rename to UniGLTF/Scripts/IO/NodeImporter.cs index a0df48d6c..503ced1d1 100644 --- a/UniGLTF/Core/Scripts/IO/NodeImporter.cs +++ b/UniGLTF/Scripts/IO/NodeImporter.cs @@ -1,203 +1,203 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - - -namespace UniGLTF -{ - public static class NodeImporter - { - public static GameObject ImportNode(glTFNode node) - { - var nodeName = node.name; - if (!string.IsNullOrEmpty(nodeName) && nodeName.Contains("/")) - { - Debug.LogWarningFormat("node {0} contains /. replace _", node.name); - nodeName = nodeName.Replace("/", "_"); - } - var go = new GameObject(nodeName); - - // - // transform - // - if (node.translation != null && node.translation.Length > 0) - { - go.transform.localPosition = new Vector3( - node.translation[0], - node.translation[1], - node.translation[2]); - } - if (node.rotation != null && node.rotation.Length > 0) - { - go.transform.localRotation = new Quaternion( - node.rotation[0], - node.rotation[1], - node.rotation[2], - node.rotation[3]); - } - if (node.scale != null && node.scale.Length > 0) - { - go.transform.localScale = new Vector3( - node.scale[0], - node.scale[1], - node.scale[2]); - } - if (node.matrix != null && node.matrix.Length > 0) - { - var m = UnityExtensions.MatrixFromArray(node.matrix); - go.transform.localRotation = m.ExtractRotation(); - go.transform.localPosition = m.ExtractPosition(); - go.transform.localScale = m.ExtractScale(); - } - return go; - } - - public class TransformWithSkin - { - public Transform Transform; - public GameObject GameObject { get { return Transform.gameObject; } } - public int? SkinIndex; - } - - public static TransformWithSkin BuildHierarchy(ImporterContext context, int i) - { - var go = context.Nodes[i].gameObject; - if (string.IsNullOrEmpty(go.name)) - { - go.name = string.Format("node{0:000}", i); - } - - var nodeWithSkin = new TransformWithSkin - { - Transform = go.transform, - }; - - // - // build hierachy - // - var node = context.GLTF.nodes[i]; - if (node.children != null) - { - foreach (var child in node.children) - { - context.Nodes[child].transform.SetParent(context.Nodes[i].transform, - false // node has local transform - ); - } - } - - // - // attach mesh - // - if (node.mesh != -1) - { - var mesh = context.Meshes[node.mesh]; - if (mesh.Mesh.blendShapeCount == 0 && node.skin == -1) - { - // without blendshape and bone skinning - var filter = go.AddComponent(); - filter.sharedMesh = mesh.Mesh; - var renderer = go.AddComponent(); - renderer.sharedMaterials = mesh.Materials; - // invisible in loading - renderer.enabled = false; - mesh.Renderers.Add(renderer); - } - else - { - var renderer = go.AddComponent(); - - if (node.skin != -1) - { - nodeWithSkin.SkinIndex = node.skin; - } - - renderer.sharedMesh = mesh.Mesh; - renderer.sharedMaterials = mesh.Materials; - // invisible in loading - renderer.enabled = false; - mesh.Renderers.Add(renderer); - } - } - - return nodeWithSkin; - } - - // - // fix node's coordinate. z-back to z-forward - // - public static void FixCoordinate(ImporterContext context, List nodes) - { - var globalTransformMap = nodes.ToDictionary(x => x.Transform, x => new PosRot - { - Position = x.Transform.position, - Rotation = x.Transform.rotation, - }); - foreach (var x in context.GLTF.rootnodes) - { - // fix nodes coordinate - // reverse Z in global - var t = nodes[x].Transform; - //t.SetParent(root.transform, false); - - foreach (var transform in t.Traverse()) - { - var g = globalTransformMap[transform]; - transform.position = g.Position.ReverseZ(); - transform.rotation = g.Rotation.ReverseZ(); - } - } - } - - public static void SetupSkinning(ImporterContext context, List nodes, int i) - { - var x = nodes[i]; - var skinnedMeshRenderer = x.Transform.GetComponent(); - if (skinnedMeshRenderer != null) - { - var mesh = skinnedMeshRenderer.sharedMesh; - if (x.SkinIndex.HasValue) - { - if (mesh == null) throw new Exception(); - if (skinnedMeshRenderer == null) throw new Exception(); - - if (x.SkinIndex.Value < context.GLTF.skins.Count) - { - var skin = context.GLTF.skins[x.SkinIndex.Value]; - - skinnedMeshRenderer.sharedMesh = null; - - var joints = skin.joints.Select(y => nodes[y].Transform).ToArray(); - skinnedMeshRenderer.bones = joints; - - if (skin.skeleton >= 0 && skin.skeleton < nodes.Count) - { - skinnedMeshRenderer.rootBone = nodes[skin.skeleton].Transform; - } - - if (skin.inverseBindMatrices != -1) - { - // BlendShape only ? -#if false - // https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html - var hipsParent = nodes[0].Transform; - var calculatedBindPoses = joints.Select(y => y.worldToLocalMatrix * hipsParent.localToWorldMatrix).ToArray(); - mesh.bindposes = calculatedBindPoses; -#else - var bindPoses = context.GLTF.GetArrayFromAccessor(skin.inverseBindMatrices) - .Select(y => y.ReverseZ()) - .ToArray() - ; - mesh.bindposes = bindPoses; -#endif - } - - skinnedMeshRenderer.sharedMesh = mesh; - } - } - } - } - - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + + +namespace UniGLTF +{ + public static class NodeImporter + { + public static GameObject ImportNode(glTFNode node) + { + var nodeName = node.name; + if (!string.IsNullOrEmpty(nodeName) && nodeName.Contains("/")) + { + Debug.LogWarningFormat("node {0} contains /. replace _", node.name); + nodeName = nodeName.Replace("/", "_"); + } + var go = new GameObject(nodeName); + + // + // transform + // + if (node.translation != null && node.translation.Length > 0) + { + go.transform.localPosition = new Vector3( + node.translation[0], + node.translation[1], + node.translation[2]); + } + if (node.rotation != null && node.rotation.Length > 0) + { + go.transform.localRotation = new Quaternion( + node.rotation[0], + node.rotation[1], + node.rotation[2], + node.rotation[3]); + } + if (node.scale != null && node.scale.Length > 0) + { + go.transform.localScale = new Vector3( + node.scale[0], + node.scale[1], + node.scale[2]); + } + if (node.matrix != null && node.matrix.Length > 0) + { + var m = UnityExtensions.MatrixFromArray(node.matrix); + go.transform.localRotation = m.ExtractRotation(); + go.transform.localPosition = m.ExtractPosition(); + go.transform.localScale = m.ExtractScale(); + } + return go; + } + + public class TransformWithSkin + { + public Transform Transform; + public GameObject GameObject { get { return Transform.gameObject; } } + public int? SkinIndex; + } + + public static TransformWithSkin BuildHierarchy(ImporterContext context, int i) + { + var go = context.Nodes[i].gameObject; + if (string.IsNullOrEmpty(go.name)) + { + go.name = string.Format("node{0:000}", i); + } + + var nodeWithSkin = new TransformWithSkin + { + Transform = go.transform, + }; + + // + // build hierachy + // + var node = context.GLTF.nodes[i]; + if (node.children != null) + { + foreach (var child in node.children) + { + context.Nodes[child].transform.SetParent(context.Nodes[i].transform, + false // node has local transform + ); + } + } + + // + // attach mesh + // + if (node.mesh != -1) + { + var mesh = context.Meshes[node.mesh]; + if (mesh.Mesh.blendShapeCount == 0 && node.skin == -1) + { + // without blendshape and bone skinning + var filter = go.AddComponent(); + filter.sharedMesh = mesh.Mesh; + var renderer = go.AddComponent(); + renderer.sharedMaterials = mesh.Materials; + // invisible in loading + renderer.enabled = false; + mesh.Renderers.Add(renderer); + } + else + { + var renderer = go.AddComponent(); + + if (node.skin != -1) + { + nodeWithSkin.SkinIndex = node.skin; + } + + renderer.sharedMesh = mesh.Mesh; + renderer.sharedMaterials = mesh.Materials; + // invisible in loading + renderer.enabled = false; + mesh.Renderers.Add(renderer); + } + } + + return nodeWithSkin; + } + + // + // fix node's coordinate. z-back to z-forward + // + public static void FixCoordinate(ImporterContext context, List nodes) + { + var globalTransformMap = nodes.ToDictionary(x => x.Transform, x => new PosRot + { + Position = x.Transform.position, + Rotation = x.Transform.rotation, + }); + foreach (var x in context.GLTF.rootnodes) + { + // fix nodes coordinate + // reverse Z in global + var t = nodes[x].Transform; + //t.SetParent(root.transform, false); + + foreach (var transform in t.Traverse()) + { + var g = globalTransformMap[transform]; + transform.position = g.Position.ReverseZ(); + transform.rotation = g.Rotation.ReverseZ(); + } + } + } + + public static void SetupSkinning(ImporterContext context, List nodes, int i) + { + var x = nodes[i]; + var skinnedMeshRenderer = x.Transform.GetComponent(); + if (skinnedMeshRenderer != null) + { + var mesh = skinnedMeshRenderer.sharedMesh; + if (x.SkinIndex.HasValue) + { + if (mesh == null) throw new Exception(); + if (skinnedMeshRenderer == null) throw new Exception(); + + if (x.SkinIndex.Value < context.GLTF.skins.Count) + { + var skin = context.GLTF.skins[x.SkinIndex.Value]; + + skinnedMeshRenderer.sharedMesh = null; + + var joints = skin.joints.Select(y => nodes[y].Transform).ToArray(); + skinnedMeshRenderer.bones = joints; + + if (skin.skeleton >= 0 && skin.skeleton < nodes.Count) + { + skinnedMeshRenderer.rootBone = nodes[skin.skeleton].Transform; + } + + if (skin.inverseBindMatrices != -1) + { + // BlendShape only ? +#if false + // https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html + var hipsParent = nodes[0].Transform; + var calculatedBindPoses = joints.Select(y => y.worldToLocalMatrix * hipsParent.localToWorldMatrix).ToArray(); + mesh.bindposes = calculatedBindPoses; +#else + var bindPoses = context.GLTF.GetArrayFromAccessor(skin.inverseBindMatrices) + .Select(y => y.ReverseZ()) + .ToArray() + ; + mesh.bindposes = bindPoses; +#endif + } + + skinnedMeshRenderer.sharedMesh = mesh; + } + } + } + } + + } +} diff --git a/UniGLTF/Core/Scripts/IO/NodeImporter.cs.meta b/UniGLTF/Scripts/IO/NodeImporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/NodeImporter.cs.meta rename to UniGLTF/Scripts/IO/NodeImporter.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/ShaderPropExporter.meta b/UniGLTF/Scripts/IO/ShaderPropExporter.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/ShaderPropExporter.meta rename to UniGLTF/Scripts/IO/ShaderPropExporter.meta diff --git a/UniGLTF/Core/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs b/UniGLTF/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs rename to UniGLTF/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs index a529320ca..b170f7eac 100644 --- a/UniGLTF/Core/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs +++ b/UniGLTF/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs @@ -1,133 +1,133 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF.ShaderPropExporter -{ - public class PreExportShadersAttribute : Attribute { } - public class PreExportShaderAttribute : Attribute { } - - public struct SupportedShader - { - public string TargetFolder; - public string ShaderName; - - public SupportedShader(string targetFolder, string shaderName) - { - TargetFolder = targetFolder; - ShaderName = shaderName; - } - } - - public static partial class PreShaderPropExporter - { - const string TARGET_FOLDER = "UniGLTF/Core/Scripts"; - -#pragma warning disable 414 - [PreExportShaders] - static SupportedShader[] SupportedShaders = new SupportedShader[] - { - new SupportedShader(TARGET_FOLDER, "Standard"), - new SupportedShader(TARGET_FOLDER, "Unlit/Color"), - new SupportedShader(TARGET_FOLDER, "Unlit/Texture"), - new SupportedShader(TARGET_FOLDER, "Unlit/Transparent"), - new SupportedShader(TARGET_FOLDER, "Unlit/Transparent Cutout"), - new SupportedShader(TARGET_FOLDER, "UniGLTF/UniUnlit"), - }; -#pragma warning restore 414 - -#if UNITY_EDITOR - [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/PreExport ShaderProps")] - public static void PreExport() - { - foreach (var fi in typeof(PreShaderPropExporter).GetFields( - BindingFlags.Static - | BindingFlags.Public - | BindingFlags.NonPublic)) - { - var attr = fi.GetCustomAttributes(true).FirstOrDefault(y => y is PreExportShadersAttribute); - if (attr != null) - { - var supportedShaders = fi.GetValue(null) as SupportedShader[]; - foreach (var supported in supportedShaders) - { - PreExport(supported); - } - } - } - } - - static string EscapeShaderName(string name) - { - return name.Replace("/", "_").Replace(" ", "_"); - } - - static UnityPath GetExportDir(string target) - { - foreach (var x in UnityPath.FromUnityPath("Assets").TravserseDir()) - { - if (x.Value.EndsWith(target)) - { - var dir = x.Child("PreExportShaderProps"); - dir.EnsureFolder(); - return dir; - } - } - throw new Exception(target + " not found"); - } - - static void PreExport(SupportedShader supportedShader) - { - var path = GetExportDir(supportedShader.TargetFolder).Child(EscapeShaderName(supportedShader.ShaderName) + ".cs"); - Debug.LogFormat("PreExport: {0}", path.FullPath); - - var shader = Shader.Find(supportedShader.ShaderName); - var props = ShaderProps.FromShader(shader); - - File.WriteAllText(path.FullPath, props.ToString(shader.name)); - } -#endif - - #region Runtime - static Dictionary m_shaderPropMap; - - public static ShaderProps GetPropsForSupportedShader(string shaderName) - { - if (m_shaderPropMap == null) - { - m_shaderPropMap = new Dictionary(); - foreach (var prop in typeof(PreShaderPropExporter).GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) - { - if (prop.GetCustomAttributes(typeof(PreExportShaderAttribute), true).Any()) - { - var kv = (KeyValuePair)prop.GetValue(null, null); - m_shaderPropMap.Add(kv.Key, kv.Value); - } - } - } - - ShaderProps props; - if (m_shaderPropMap.TryGetValue(shaderName, out props)) - { - return props; - } - -#if UNITY_EDITOR - // fallback - Debug.LogWarningFormat("{0} is not predefined shader. Use ShaderUtil", shaderName); - var shader = Shader.Find(shaderName); - return ShaderProps.FromShader(shader); -#else - return null; -#endif - } - #endregion - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF.ShaderPropExporter +{ + public class PreExportShadersAttribute : Attribute { } + public class PreExportShaderAttribute : Attribute { } + + public struct SupportedShader + { + public string TargetFolder; + public string ShaderName; + + public SupportedShader(string targetFolder, string shaderName) + { + TargetFolder = targetFolder; + ShaderName = shaderName; + } + } + + public static partial class PreShaderPropExporter + { + const string TARGET_FOLDER = "UniGLTF/Core/Scripts"; + +#pragma warning disable 414 + [PreExportShaders] + static SupportedShader[] SupportedShaders = new SupportedShader[] + { + new SupportedShader(TARGET_FOLDER, "Standard"), + new SupportedShader(TARGET_FOLDER, "Unlit/Color"), + new SupportedShader(TARGET_FOLDER, "Unlit/Texture"), + new SupportedShader(TARGET_FOLDER, "Unlit/Transparent"), + new SupportedShader(TARGET_FOLDER, "Unlit/Transparent Cutout"), + new SupportedShader(TARGET_FOLDER, "UniGLTF/UniUnlit"), + }; +#pragma warning restore 414 + +#if UNITY_EDITOR + [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/PreExport ShaderProps")] + public static void PreExport() + { + foreach (var fi in typeof(PreShaderPropExporter).GetFields( + BindingFlags.Static + | BindingFlags.Public + | BindingFlags.NonPublic)) + { + var attr = fi.GetCustomAttributes(true).FirstOrDefault(y => y is PreExportShadersAttribute); + if (attr != null) + { + var supportedShaders = fi.GetValue(null) as SupportedShader[]; + foreach (var supported in supportedShaders) + { + PreExport(supported); + } + } + } + } + + static string EscapeShaderName(string name) + { + return name.Replace("/", "_").Replace(" ", "_"); + } + + static UnityPath GetExportDir(string target) + { + foreach (var x in UnityPath.FromUnityPath("Assets").TravserseDir()) + { + if (x.Value.EndsWith(target)) + { + var dir = x.Child("PreExportShaderProps"); + dir.EnsureFolder(); + return dir; + } + } + throw new Exception(target + " not found"); + } + + static void PreExport(SupportedShader supportedShader) + { + var path = GetExportDir(supportedShader.TargetFolder).Child(EscapeShaderName(supportedShader.ShaderName) + ".cs"); + Debug.LogFormat("PreExport: {0}", path.FullPath); + + var shader = Shader.Find(supportedShader.ShaderName); + var props = ShaderProps.FromShader(shader); + + File.WriteAllText(path.FullPath, props.ToString(shader.name)); + } +#endif + + #region Runtime + static Dictionary m_shaderPropMap; + + public static ShaderProps GetPropsForSupportedShader(string shaderName) + { + if (m_shaderPropMap == null) + { + m_shaderPropMap = new Dictionary(); + foreach (var prop in typeof(PreShaderPropExporter).GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) + { + if (prop.GetCustomAttributes(typeof(PreExportShaderAttribute), true).Any()) + { + var kv = (KeyValuePair)prop.GetValue(null, null); + m_shaderPropMap.Add(kv.Key, kv.Value); + } + } + } + + ShaderProps props; + if (m_shaderPropMap.TryGetValue(shaderName, out props)) + { + return props; + } + +#if UNITY_EDITOR + // fallback + Debug.LogWarningFormat("{0} is not predefined shader. Use ShaderUtil", shaderName); + var shader = Shader.Find(shaderName); + return ShaderProps.FromShader(shader); +#else + return null; +#endif + } + #endregion + } +} diff --git a/UniGLTF/Core/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs.meta b/UniGLTF/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs.meta rename to UniGLTF/Scripts/IO/ShaderPropExporter/PreShaderPropExporter.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/ShaderPropExporter/ShaderProps.cs b/UniGLTF/Scripts/IO/ShaderPropExporter/ShaderProps.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/ShaderPropExporter/ShaderProps.cs rename to UniGLTF/Scripts/IO/ShaderPropExporter/ShaderProps.cs index d5debaba5..49a3ba77a 100644 --- a/UniGLTF/Core/Scripts/IO/ShaderPropExporter/ShaderProps.cs +++ b/UniGLTF/Scripts/IO/ShaderPropExporter/ShaderProps.cs @@ -1,111 +1,111 @@ -#if UNITY_EDITOR -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -#endif - - -namespace UniGLTF.ShaderPropExporter -{ - public enum ShaderPropertyType - { - TexEnv, - Color, - Range, - Float, - Vector, - } - - public struct ShaderProperty - { - public string Key; - public ShaderPropertyType ShaderPropertyType; - - public ShaderProperty(string key, ShaderPropertyType propType) - { - Key = key; - ShaderPropertyType = propType; - } - } - - public class ShaderProps - { - public ShaderProperty[] Properties; - -#if UNITY_EDITOR - static ShaderPropertyType ConvType(ShaderUtil.ShaderPropertyType src) - { - switch (src) - { - case ShaderUtil.ShaderPropertyType.TexEnv: return ShaderPropertyType.TexEnv; - case ShaderUtil.ShaderPropertyType.Color: return ShaderPropertyType.Color; - case ShaderUtil.ShaderPropertyType.Float: return ShaderPropertyType.Float; - case ShaderUtil.ShaderPropertyType.Range: return ShaderPropertyType.Range; - case ShaderUtil.ShaderPropertyType.Vector: return ShaderPropertyType.Vector; - default: throw new NotImplementedException(); - } - } - - public static ShaderProps FromShader(Shader shader) - { - var properties = new List(); - for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i) - { - var name = ShaderUtil.GetPropertyName(shader, i); - var propType = ShaderUtil.GetPropertyType(shader, i); - properties.Add(new ShaderProperty(name, ConvType(propType))); - } - - return new ShaderProps - { - Properties = properties.ToArray(), - }; - } - - static string EscapeShaderName(string name) - { - return name.Replace("/", "_").Replace(" ", "_"); - } - - public string ToString(string shaderName) - { - var list = new List(); - foreach (var prop in Properties) - { - list.Add(string.Format("new ShaderProperty(\"{0}\", ShaderPropertyType.{1})\r\n", prop.Key, prop.ShaderPropertyType)); - } - - return string.Format(@"using System.Collections.Generic; - - -namespace UniGLTF.ShaderPropExporter -{{ - public static partial class PreShaderPropExporter - {{ - [PreExportShader] - static KeyValuePair {0} - {{ - get - {{ - return new KeyValuePair( - ""{1}"", - new ShaderProps - {{ - Properties = new ShaderProperty[]{{ -{2} - }} - }} - ); - }} - }} - }} -}} -" -, EscapeShaderName(shaderName) -, shaderName -, String.Join(",", list.ToArray())); - } -#endif - } -} +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +#endif + + +namespace UniGLTF.ShaderPropExporter +{ + public enum ShaderPropertyType + { + TexEnv, + Color, + Range, + Float, + Vector, + } + + public struct ShaderProperty + { + public string Key; + public ShaderPropertyType ShaderPropertyType; + + public ShaderProperty(string key, ShaderPropertyType propType) + { + Key = key; + ShaderPropertyType = propType; + } + } + + public class ShaderProps + { + public ShaderProperty[] Properties; + +#if UNITY_EDITOR + static ShaderPropertyType ConvType(ShaderUtil.ShaderPropertyType src) + { + switch (src) + { + case ShaderUtil.ShaderPropertyType.TexEnv: return ShaderPropertyType.TexEnv; + case ShaderUtil.ShaderPropertyType.Color: return ShaderPropertyType.Color; + case ShaderUtil.ShaderPropertyType.Float: return ShaderPropertyType.Float; + case ShaderUtil.ShaderPropertyType.Range: return ShaderPropertyType.Range; + case ShaderUtil.ShaderPropertyType.Vector: return ShaderPropertyType.Vector; + default: throw new NotImplementedException(); + } + } + + public static ShaderProps FromShader(Shader shader) + { + var properties = new List(); + for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i) + { + var name = ShaderUtil.GetPropertyName(shader, i); + var propType = ShaderUtil.GetPropertyType(shader, i); + properties.Add(new ShaderProperty(name, ConvType(propType))); + } + + return new ShaderProps + { + Properties = properties.ToArray(), + }; + } + + static string EscapeShaderName(string name) + { + return name.Replace("/", "_").Replace(" ", "_"); + } + + public string ToString(string shaderName) + { + var list = new List(); + foreach (var prop in Properties) + { + list.Add(string.Format("new ShaderProperty(\"{0}\", ShaderPropertyType.{1})\r\n", prop.Key, prop.ShaderPropertyType)); + } + + return string.Format(@"using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{{ + public static partial class PreShaderPropExporter + {{ + [PreExportShader] + static KeyValuePair {0} + {{ + get + {{ + return new KeyValuePair( + ""{1}"", + new ShaderProps + {{ + Properties = new ShaderProperty[]{{ +{2} + }} + }} + ); + }} + }} + }} +}} +" +, EscapeShaderName(shaderName) +, shaderName +, String.Join(",", list.ToArray())); + } +#endif + } +} diff --git a/UniGLTF/Core/Scripts/IO/ShaderPropExporter/ShaderProps.cs.meta b/UniGLTF/Scripts/IO/ShaderPropExporter/ShaderProps.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/ShaderPropExporter/ShaderProps.cs.meta rename to UniGLTF/Scripts/IO/ShaderPropExporter/ShaderProps.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/ShaderStore.cs b/UniGLTF/Scripts/IO/ShaderStore.cs similarity index 95% rename from UniGLTF/Core/Scripts/IO/ShaderStore.cs rename to UniGLTF/Scripts/IO/ShaderStore.cs index dc767a57a..7618af07c 100644 --- a/UniGLTF/Core/Scripts/IO/ShaderStore.cs +++ b/UniGLTF/Scripts/IO/ShaderStore.cs @@ -1,123 +1,123 @@ -using UnityEngine; - - -namespace UniGLTF -{ - public interface IShaderStore - { - Shader GetShader(glTFMaterial material); - } - - public class ShaderStore : IShaderStore - { - readonly string m_defaultShaderName = "Standard"; - Shader m_default; - Shader Default - { - get - { - if (m_default == null) - { - m_default = Shader.Find(m_defaultShaderName); - } - return m_default; - } - } - - Shader m_vcolor; - Shader VColor - { - get - { - if (m_vcolor == null) m_vcolor = Shader.Find("UniGLTF/StandardVColor"); - return m_vcolor; - } - } - - Shader m_uniUnlit; - Shader UniUnlit - { - get - { - if (m_uniUnlit == null) m_uniUnlit = Shader.Find("UniGLTF/UniUnlit"); - return m_uniUnlit; - } - } - - Shader m_unlitTexture; - Shader UnlitTexture - { - get - { - if (m_unlitTexture == null) m_unlitTexture = Shader.Find("Unlit/Texture"); - return m_unlitTexture; - } - } - - Shader m_unlitColor; - Shader UnlitColor - { - get - { - if (m_unlitColor == null) m_unlitColor = Shader.Find("Unlit/Color"); - return m_unlitColor; - } - } - - Shader m_unlitTransparent; - Shader UnlitTransparent - { - get - { - if (m_unlitTransparent == null) m_unlitTransparent = Shader.Find("Unlit/Transparent"); - return m_unlitTransparent; - } - } - - Shader m_unlitCoutout; - Shader UnlitCutout - { - get - { - if (m_unlitCoutout == null) m_unlitCoutout = Shader.Find("Unlit/Transparent Cutout"); - return m_unlitCoutout; - } - } - - //ImporterContext m_context; - public ShaderStore(ImporterContext _) - { - //m_context = context; - } - - public static bool IsWhite(float[] color) - { - if (color == null) return false; - if(color.Length!=4)return false; - if(color[0]!=1 - || color[1]!=1 - || color[2]!=1 - || color[3] != 1) - { - return false; - } - return true; - } - - public Shader GetShader(glTFMaterial material) - { - if (material == null) - { - return Default; - } - - if (material.extensions != null && material.extensions.KHR_materials_unlit != null) - { - return UniUnlit; - } - - // standard - return Default; - } - } -} +using UnityEngine; + + +namespace UniGLTF +{ + public interface IShaderStore + { + Shader GetShader(glTFMaterial material); + } + + public class ShaderStore : IShaderStore + { + readonly string m_defaultShaderName = "Standard"; + Shader m_default; + Shader Default + { + get + { + if (m_default == null) + { + m_default = Shader.Find(m_defaultShaderName); + } + return m_default; + } + } + + Shader m_vcolor; + Shader VColor + { + get + { + if (m_vcolor == null) m_vcolor = Shader.Find("UniGLTF/StandardVColor"); + return m_vcolor; + } + } + + Shader m_uniUnlit; + Shader UniUnlit + { + get + { + if (m_uniUnlit == null) m_uniUnlit = Shader.Find("UniGLTF/UniUnlit"); + return m_uniUnlit; + } + } + + Shader m_unlitTexture; + Shader UnlitTexture + { + get + { + if (m_unlitTexture == null) m_unlitTexture = Shader.Find("Unlit/Texture"); + return m_unlitTexture; + } + } + + Shader m_unlitColor; + Shader UnlitColor + { + get + { + if (m_unlitColor == null) m_unlitColor = Shader.Find("Unlit/Color"); + return m_unlitColor; + } + } + + Shader m_unlitTransparent; + Shader UnlitTransparent + { + get + { + if (m_unlitTransparent == null) m_unlitTransparent = Shader.Find("Unlit/Transparent"); + return m_unlitTransparent; + } + } + + Shader m_unlitCoutout; + Shader UnlitCutout + { + get + { + if (m_unlitCoutout == null) m_unlitCoutout = Shader.Find("Unlit/Transparent Cutout"); + return m_unlitCoutout; + } + } + + //ImporterContext m_context; + public ShaderStore(ImporterContext _) + { + //m_context = context; + } + + public static bool IsWhite(float[] color) + { + if (color == null) return false; + if(color.Length!=4)return false; + if(color[0]!=1 + || color[1]!=1 + || color[2]!=1 + || color[3] != 1) + { + return false; + } + return true; + } + + public Shader GetShader(glTFMaterial material) + { + if (material == null) + { + return Default; + } + + if (material.extensions != null && material.extensions.KHR_materials_unlit != null) + { + return UniUnlit; + } + + // standard + return Default; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/ShaderStore.cs.meta b/UniGLTF/Scripts/IO/ShaderStore.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/ShaderStore.cs.meta rename to UniGLTF/Scripts/IO/ShaderStore.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/StaticMeshIntegrator.cs b/UniGLTF/Scripts/IO/StaticMeshIntegrator.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/StaticMeshIntegrator.cs rename to UniGLTF/Scripts/IO/StaticMeshIntegrator.cs index 44dd3051d..a6bd91937 100644 --- a/UniGLTF/Core/Scripts/IO/StaticMeshIntegrator.cs +++ b/UniGLTF/Scripts/IO/StaticMeshIntegrator.cs @@ -1,186 +1,186 @@ -using System.Collections.Generic; -using UnityEngine; -using System.IO; -using System.Linq; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public static class StaticMeshIntegrator - { - const string ASSET_SUFFIX = ".mesh.asset"; - - class Integrator - { - List m_positions = new List(); - List m_normals = new List(); - List m_uv = new List(); - /* - List m_uv2 = new List(); // ToDo - List m_uv3 = new List(); // ToDo - List m_uv4 = new List(); // ToDo - List m_colors = new List(); // ToDo - */ - - List m_subMeshes = new List(); - - List m_materials = new List(); - public List Materials - { - get { return m_materials; } - } - - public void Push(Matrix4x4 localToRoot, Mesh mesh, Material[] materials) - { - var offset = m_positions.Count; - - var hasNormal = m_normals.Count == m_positions.Count; - var hasUv = m_uv.Count == m_positions.Count; - - // attributes - m_positions.AddRange(mesh.vertices.Select(x => localToRoot.MultiplyPoint(x))); - if(mesh.normals!=null && mesh.normals.Length == mesh.vertexCount) - { - if (!hasNormal) for (int i = m_normals.Count; i < m_positions.Count; ++i) m_normals.Add(Vector3.zero); - m_normals.AddRange(mesh.normals.Select(x => localToRoot.MultiplyVector(x))); - } - if (mesh.uv != null && mesh.uv.Length == mesh.vertexCount) - { - if (!hasUv) for (int i = m_uv.Count; i < m_positions.Count; ++i) m_uv.Add(Vector2.zero); - m_uv.AddRange(mesh.uv); - } - - // indices - for (int i = 0; i < mesh.subMeshCount; ++i) - { - m_subMeshes.Add(mesh.GetIndices(i).Select(x => offset + x).ToArray()); - } - - // materials - m_materials.AddRange(materials); - } - - public Mesh ToMesh() - { - var mesh = new Mesh(); - mesh.name = "integrated"; - - mesh.vertices = m_positions.ToArray(); - if (m_normals.Count > 0) - { - if (m_normals.Count < m_positions.Count) for (int i = m_normals.Count; i < m_positions.Count; ++i) m_normals.Add(Vector3.zero); - mesh.normals = m_normals.ToArray(); - } - if (m_uv.Count > 0) - { - if (m_uv.Count < m_positions.Count) for (int i = m_uv.Count; i < m_positions.Count; ++i) m_uv.Add(Vector2.zero); - mesh.uv = m_uv.ToArray(); - } - - mesh.subMeshCount = m_subMeshes.Count; - for(int i=0; i(); - var filter = t.GetComponent(); - if (renderer != null && filter != null && filter.sharedMesh != null - && renderer.sharedMaterials!=null && renderer.sharedMaterials.Length == filter.sharedMesh.subMeshCount) - { - integrator.Push(root.worldToLocalMatrix * t.localToWorldMatrix, filter.sharedMesh, renderer.sharedMaterials); - } - } - - return new MeshWithMaterials - { - Mesh = integrator.ToMesh(), - Materials = integrator.Materials.ToArray(), - }; - } - -#if UNITY_EDITOR - [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Integrate static mesh", validate = true)] - public static bool CanIntegrateSelected() - { - return Selection.activeObject != null && Selection.activeObject is GameObject; - } - - [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Integrate static mesh")] - public static void IntegrateSelected() - { - var go = Selection.activeObject as GameObject; - var meshWithMaterials = Integrate(go.transform); - - // save as asset - var assetPath = ""; -#if UNITY_2018_2_OR_NEWER - var prefab = PrefabUtility.GetCorrespondingObjectFromSource(go); -#else - var prefab = PrefabUtility.GetPrefabParent(go); -#endif - if (prefab != null) - { - var prefabPath = AssetDatabase.GetAssetPath(prefab); - assetPath = string.Format("{0}/{1}_{2}{3}", - Path.GetDirectoryName(prefabPath), - Path.GetFileNameWithoutExtension(prefabPath), - go.name, - ASSET_SUFFIX - ); - } - else - { - var path = EditorUtility.SaveFilePanel( - "Save mesh", - "Assets", - go.name+".asset", - "asset"); - if (string.IsNullOrEmpty(path)) - { - return; - } - assetPath = UnityPath.FromFullpath(path).Value; - } - - assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath); - Debug.LogFormat("CreateAsset: {0}", assetPath); - AssetDatabase.CreateAsset(meshWithMaterials.Mesh, assetPath); - - // add component - var meshObject = new GameObject(go.name + ".integrated"); - if (go.transform.parent != null) - { - meshObject.transform.SetParent(go.transform.parent, false); - } - meshObject.transform.localPosition = go.transform.localPosition; - meshObject.transform.localRotation = go.transform.localRotation; - meshObject.transform.localScale = go.transform.localScale; - - var filter = meshObject.AddComponent(); - filter.sharedMesh = meshWithMaterials.Mesh; - var renderer = meshObject.AddComponent(); - renderer.sharedMaterials = meshWithMaterials.Materials; - } -#endif - } -} +using System.Collections.Generic; +using UnityEngine; +using System.IO; +using System.Linq; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + public static class StaticMeshIntegrator + { + const string ASSET_SUFFIX = ".mesh.asset"; + + class Integrator + { + List m_positions = new List(); + List m_normals = new List(); + List m_uv = new List(); + /* + List m_uv2 = new List(); // ToDo + List m_uv3 = new List(); // ToDo + List m_uv4 = new List(); // ToDo + List m_colors = new List(); // ToDo + */ + + List m_subMeshes = new List(); + + List m_materials = new List(); + public List Materials + { + get { return m_materials; } + } + + public void Push(Matrix4x4 localToRoot, Mesh mesh, Material[] materials) + { + var offset = m_positions.Count; + + var hasNormal = m_normals.Count == m_positions.Count; + var hasUv = m_uv.Count == m_positions.Count; + + // attributes + m_positions.AddRange(mesh.vertices.Select(x => localToRoot.MultiplyPoint(x))); + if(mesh.normals!=null && mesh.normals.Length == mesh.vertexCount) + { + if (!hasNormal) for (int i = m_normals.Count; i < m_positions.Count; ++i) m_normals.Add(Vector3.zero); + m_normals.AddRange(mesh.normals.Select(x => localToRoot.MultiplyVector(x))); + } + if (mesh.uv != null && mesh.uv.Length == mesh.vertexCount) + { + if (!hasUv) for (int i = m_uv.Count; i < m_positions.Count; ++i) m_uv.Add(Vector2.zero); + m_uv.AddRange(mesh.uv); + } + + // indices + for (int i = 0; i < mesh.subMeshCount; ++i) + { + m_subMeshes.Add(mesh.GetIndices(i).Select(x => offset + x).ToArray()); + } + + // materials + m_materials.AddRange(materials); + } + + public Mesh ToMesh() + { + var mesh = new Mesh(); + mesh.name = "integrated"; + + mesh.vertices = m_positions.ToArray(); + if (m_normals.Count > 0) + { + if (m_normals.Count < m_positions.Count) for (int i = m_normals.Count; i < m_positions.Count; ++i) m_normals.Add(Vector3.zero); + mesh.normals = m_normals.ToArray(); + } + if (m_uv.Count > 0) + { + if (m_uv.Count < m_positions.Count) for (int i = m_uv.Count; i < m_positions.Count; ++i) m_uv.Add(Vector2.zero); + mesh.uv = m_uv.ToArray(); + } + + mesh.subMeshCount = m_subMeshes.Count; + for(int i=0; i(); + var filter = t.GetComponent(); + if (renderer != null && filter != null && filter.sharedMesh != null + && renderer.sharedMaterials!=null && renderer.sharedMaterials.Length == filter.sharedMesh.subMeshCount) + { + integrator.Push(root.worldToLocalMatrix * t.localToWorldMatrix, filter.sharedMesh, renderer.sharedMaterials); + } + } + + return new MeshWithMaterials + { + Mesh = integrator.ToMesh(), + Materials = integrator.Materials.ToArray(), + }; + } + +#if UNITY_EDITOR + [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Integrate static mesh", validate = true)] + public static bool CanIntegrateSelected() + { + return Selection.activeObject != null && Selection.activeObject is GameObject; + } + + [MenuItem(UniGLTFVersion.UNIGLTF_VERSION + "/Integrate static mesh")] + public static void IntegrateSelected() + { + var go = Selection.activeObject as GameObject; + var meshWithMaterials = Integrate(go.transform); + + // save as asset + var assetPath = ""; +#if UNITY_2018_2_OR_NEWER + var prefab = PrefabUtility.GetCorrespondingObjectFromSource(go); +#else + var prefab = PrefabUtility.GetPrefabParent(go); +#endif + if (prefab != null) + { + var prefabPath = AssetDatabase.GetAssetPath(prefab); + assetPath = string.Format("{0}/{1}_{2}{3}", + Path.GetDirectoryName(prefabPath), + Path.GetFileNameWithoutExtension(prefabPath), + go.name, + ASSET_SUFFIX + ); + } + else + { + var path = EditorUtility.SaveFilePanel( + "Save mesh", + "Assets", + go.name+".asset", + "asset"); + if (string.IsNullOrEmpty(path)) + { + return; + } + assetPath = UnityPath.FromFullpath(path).Value; + } + + assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath); + Debug.LogFormat("CreateAsset: {0}", assetPath); + AssetDatabase.CreateAsset(meshWithMaterials.Mesh, assetPath); + + // add component + var meshObject = new GameObject(go.name + ".integrated"); + if (go.transform.parent != null) + { + meshObject.transform.SetParent(go.transform.parent, false); + } + meshObject.transform.localPosition = go.transform.localPosition; + meshObject.transform.localRotation = go.transform.localRotation; + meshObject.transform.localScale = go.transform.localScale; + + var filter = meshObject.AddComponent(); + filter.sharedMesh = meshWithMaterials.Mesh; + var renderer = meshObject.AddComponent(); + renderer.sharedMaterials = meshWithMaterials.Materials; + } +#endif + } +} diff --git a/UniGLTF/Core/Scripts/IO/StaticMeshIntegrator.cs.meta b/UniGLTF/Scripts/IO/StaticMeshIntegrator.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/StaticMeshIntegrator.cs.meta rename to UniGLTF/Scripts/IO/StaticMeshIntegrator.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/TextureConverter.cs b/UniGLTF/Scripts/IO/TextureConverter.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/TextureConverter.cs rename to UniGLTF/Scripts/IO/TextureConverter.cs index b7fba39cc..94d2d95b1 100644 --- a/UniGLTF/Core/Scripts/IO/TextureConverter.cs +++ b/UniGLTF/Scripts/IO/TextureConverter.cs @@ -1,177 +1,177 @@ -using System.Linq; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public interface ITextureConverter - { - Texture2D GetImportTexture(Texture2D texture); - Texture2D GetExportTexture(Texture2D texture); - } - - public static class TextureConverter - { - public delegate Color32 ColorConversion(Color32 color); - - public static Texture2D Convert(Texture2D texture, glTFTextureTypes textureType, ColorConversion colorConversion, Material convertMaterial) - { - var copyTexture = TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), convertMaterial); - if (colorConversion != null) - { - copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray()); - copyTexture.Apply(); - } - copyTexture.name = texture.name; - return copyTexture; - } - - public static void AppendTextureExtension(Texture texture, string extension) - { - if (!texture.name.EndsWith(extension)) - { - texture.name = texture.name + extension; - } - } - - public static void RemoveTextureExtension(Texture texture, string extension) - { - if (texture.name.EndsWith(extension)) - { - texture.name = texture.name.Replace(extension, ""); - } - } - } - - class MetallicRoughnessConverter : ITextureConverter - { - private const string m_extension = ".metallicRoughness"; - - public Texture2D GetImportTexture(Texture2D texture) - { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Import, null); - TextureConverter.AppendTextureExtension(converted, m_extension); - return converted; - } - - public Texture2D GetExportTexture(Texture2D texture) - { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Export, null); - TextureConverter.RemoveTextureExtension(converted, m_extension); - return converted; - } - - public Color32 Import(Color32 src) - { - return new Color32 - { - r = src.b, - g = 0, - b = 0, - a = (byte)(255 - src.g), - }; - } - - public Color32 Export(Color32 src) - { - return new Color32 - { - r = 0, - g = (byte)(255 - src.a), - b = src.r, - a = 255, - }; - } - } - - class NormalConverter : ITextureConverter - { - private const string m_extension = ".normal"; - - private Material m_decoder; - private Material GetDecoder() - { - if (m_decoder == null) - { - m_decoder = new Material(Shader.Find("UniGLTF/NormalMapDecoder")); - } - return m_decoder; - } - - private Material m_encoder; - private Material GetEncoder() - { - if (m_encoder == null) - { - m_encoder = new Material(Shader.Find("UniGLTF/NormalMapEncoder")); - } - return m_encoder; - } - - public Texture2D GetImportTexture(Texture2D texture) - { -#if UNITY_WEBGL && !UNITY_EDITOR - return texture; -#endif - var mat = GetEncoder(); - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Normal, null, mat); - TextureConverter.AppendTextureExtension(converted, m_extension); - return converted; - } - - public Texture2D GetExportTexture(Texture2D texture) - { -#if UNITY_WEBGL && !UNITY_EDITOR - return texture; -#endif - var mat = GetDecoder(); - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Normal, null, mat); - TextureConverter.RemoveTextureExtension(converted, m_extension); - return converted; - } - } - - class OcclusionConverter : ITextureConverter - { - private const string m_extension = ".occlusion"; - - public Texture2D GetImportTexture(Texture2D texture) - { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Occlusion, Import, null); - TextureConverter.AppendTextureExtension(converted, m_extension); - return converted; - } - - public Texture2D GetExportTexture(Texture2D texture) - { - var converted = TextureConverter.Convert(texture, glTFTextureTypes.Occlusion, Export, null); - TextureConverter.RemoveTextureExtension(converted, m_extension); - return converted; - } - - public Color32 Import(Color32 src) - { - return new Color32 - { - r = 0, - g = src.r, - b = 0, - a = 255, - }; - } - - public Color32 Export(Color32 src) - { - return new Color32 - { - r = src.g, - g = 0, - b = 0, - a = 255, - }; - } - } +using System.Linq; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + public interface ITextureConverter + { + Texture2D GetImportTexture(Texture2D texture); + Texture2D GetExportTexture(Texture2D texture); + } + + public static class TextureConverter + { + public delegate Color32 ColorConversion(Color32 color); + + public static Texture2D Convert(Texture2D texture, glTFTextureTypes textureType, ColorConversion colorConversion, Material convertMaterial) + { + var copyTexture = TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), convertMaterial); + if (colorConversion != null) + { + copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray()); + copyTexture.Apply(); + } + copyTexture.name = texture.name; + return copyTexture; + } + + public static void AppendTextureExtension(Texture texture, string extension) + { + if (!texture.name.EndsWith(extension)) + { + texture.name = texture.name + extension; + } + } + + public static void RemoveTextureExtension(Texture texture, string extension) + { + if (texture.name.EndsWith(extension)) + { + texture.name = texture.name.Replace(extension, ""); + } + } + } + + class MetallicRoughnessConverter : ITextureConverter + { + private const string m_extension = ".metallicRoughness"; + + public Texture2D GetImportTexture(Texture2D texture) + { + var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Import, null); + TextureConverter.AppendTextureExtension(converted, m_extension); + return converted; + } + + public Texture2D GetExportTexture(Texture2D texture) + { + var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Export, null); + TextureConverter.RemoveTextureExtension(converted, m_extension); + return converted; + } + + public Color32 Import(Color32 src) + { + return new Color32 + { + r = src.b, + g = 0, + b = 0, + a = (byte)(255 - src.g), + }; + } + + public Color32 Export(Color32 src) + { + return new Color32 + { + r = 0, + g = (byte)(255 - src.a), + b = src.r, + a = 255, + }; + } + } + + class NormalConverter : ITextureConverter + { + private const string m_extension = ".normal"; + + private Material m_decoder; + private Material GetDecoder() + { + if (m_decoder == null) + { + m_decoder = new Material(Shader.Find("UniGLTF/NormalMapDecoder")); + } + return m_decoder; + } + + private Material m_encoder; + private Material GetEncoder() + { + if (m_encoder == null) + { + m_encoder = new Material(Shader.Find("UniGLTF/NormalMapEncoder")); + } + return m_encoder; + } + + public Texture2D GetImportTexture(Texture2D texture) + { +#if UNITY_WEBGL && !UNITY_EDITOR + return texture; +#endif + var mat = GetEncoder(); + var converted = TextureConverter.Convert(texture, glTFTextureTypes.Normal, null, mat); + TextureConverter.AppendTextureExtension(converted, m_extension); + return converted; + } + + public Texture2D GetExportTexture(Texture2D texture) + { +#if UNITY_WEBGL && !UNITY_EDITOR + return texture; +#endif + var mat = GetDecoder(); + var converted = TextureConverter.Convert(texture, glTFTextureTypes.Normal, null, mat); + TextureConverter.RemoveTextureExtension(converted, m_extension); + return converted; + } + } + + class OcclusionConverter : ITextureConverter + { + private const string m_extension = ".occlusion"; + + public Texture2D GetImportTexture(Texture2D texture) + { + var converted = TextureConverter.Convert(texture, glTFTextureTypes.Occlusion, Import, null); + TextureConverter.AppendTextureExtension(converted, m_extension); + return converted; + } + + public Texture2D GetExportTexture(Texture2D texture) + { + var converted = TextureConverter.Convert(texture, glTFTextureTypes.Occlusion, Export, null); + TextureConverter.RemoveTextureExtension(converted, m_extension); + return converted; + } + + public Color32 Import(Color32 src) + { + return new Color32 + { + r = 0, + g = src.r, + b = 0, + a = 255, + }; + } + + public Color32 Export(Color32 src) + { + return new Color32 + { + r = src.g, + g = 0, + b = 0, + a = 255, + }; + } + } } \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/TextureConverter.cs.meta b/UniGLTF/Scripts/IO/TextureConverter.cs.meta similarity index 71% rename from UniGLTF/Core/Scripts/IO/TextureConverter.cs.meta rename to UniGLTF/Scripts/IO/TextureConverter.cs.meta index 7f44191b9..1c3a1df2d 100644 --- a/UniGLTF/Core/Scripts/IO/TextureConverter.cs.meta +++ b/UniGLTF/Scripts/IO/TextureConverter.cs.meta @@ -1,3 +1,3 @@ -fileFormatVersion: 2 -guid: 5d2d27884d6c4780b08c745e5cc5c5b5 +fileFormatVersion: 2 +guid: 5d2d27884d6c4780b08c745e5cc5c5b5 timeCreated: 1537261040 \ No newline at end of file diff --git a/UniGLTF/Core/Scripts/IO/TextureExportManager.cs b/UniGLTF/Scripts/IO/TextureExportManager.cs similarity index 100% rename from UniGLTF/Core/Scripts/IO/TextureExportManager.cs rename to UniGLTF/Scripts/IO/TextureExportManager.cs diff --git a/UniGLTF/Core/Scripts/IO/TextureExportManager.cs.meta b/UniGLTF/Scripts/IO/TextureExportManager.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/TextureExportManager.cs.meta rename to UniGLTF/Scripts/IO/TextureExportManager.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/TextureIO.cs b/UniGLTF/Scripts/IO/TextureIO.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/TextureIO.cs rename to UniGLTF/Scripts/IO/TextureIO.cs index b46fee5ab..cc0d86b99 100644 --- a/UniGLTF/Core/Scripts/IO/TextureIO.cs +++ b/UniGLTF/Scripts/IO/TextureIO.cs @@ -1,175 +1,175 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public static class TextureIO - { - public static RenderTextureReadWrite GetColorSpace(glTFTextureTypes textureType) - { - switch (textureType) - { - case glTFTextureTypes.Metallic: - case glTFTextureTypes.Normal: - case glTFTextureTypes.Occlusion: - return RenderTextureReadWrite.Linear; - case glTFTextureTypes.BaseColor: - case glTFTextureTypes.Emissive: - return RenderTextureReadWrite.sRGB; - default: - return RenderTextureReadWrite.sRGB; - } - } - - public static glTFTextureTypes GetglTFTextureType(string shaderName, string propName) - { - switch (propName) - { - case "_Color": - return glTFTextureTypes.BaseColor; - case "_MetallicGlossMap": - return glTFTextureTypes.Metallic; - case "_BumpMap": - return glTFTextureTypes.Normal; - case "_OcclusionMap": - return glTFTextureTypes.Occlusion; - case "_EmissionMap": - return glTFTextureTypes.Emissive; - default: - return glTFTextureTypes.Unknown; - } - } - - public static glTFTextureTypes GetglTFTextureType(glTF glTf, int textureIndex) - { - foreach (var material in glTf.materials) - { - var textureInfo = material.GetTextures().FirstOrDefault(x => (x!=null) && x.index == textureIndex); - if (textureInfo != null) - { - return textureInfo.TextreType; - } - } - return glTFTextureTypes.Unknown; - } - -#if UNITY_EDITOR - public static void MarkTextureAssetAsNormalMap(string assetPath) - { - if (string.IsNullOrEmpty(assetPath)) - { - return; - } - - var textureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter; - if (null == textureImporter) - { - return; - } - - //Debug.LogFormat("[MarkTextureAssetAsNormalMap] {0}", assetPath); - textureImporter.textureType = TextureImporterType.NormalMap; - textureImporter.SaveAndReimport(); - } -#endif - - public struct TextureExportItem - { - public Texture Texture; - public glTFTextureTypes TextureType; - - public TextureExportItem(Texture texture, glTFTextureTypes textureType) - { - Texture = texture; - TextureType = textureType; - } - } - - public static IEnumerable GetTextures(Material m) - { - var props = ShaderPropExporter.PreShaderPropExporter.GetPropsForSupportedShader(m.shader.name); - if (props == null) - { - yield return new TextureExportItem(m.mainTexture, glTFTextureTypes.BaseColor); - } - - foreach (var prop in props.Properties) - { - - if (prop.ShaderPropertyType == ShaderPropExporter.ShaderPropertyType.TexEnv) - { - yield return new TextureExportItem(m.GetTexture(prop.Key), GetglTFTextureType(m.shader.name, prop.Key)); - } - } - } - - - struct BytesWithMime - { - public Byte[] Bytes; - public string Mime; - } - - static BytesWithMime GetBytesWithMime(Texture texture, glTFTextureTypes textureType) - { -#if UNITY_EDITOR - var path = UnityPath.FromAsset(texture); - if (path.IsUnderAssetsFolder) - { - if (path.Extension == ".png") - { - return new BytesWithMime - { - Bytes = System.IO.File.ReadAllBytes(path.FullPath), - Mime = "image/png", - }; - } - } -#endif - - return new BytesWithMime - { - Bytes = TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), null).EncodeToPNG(), - Mime = "image/png", - }; - } - - public static int ExportTexture(glTF gltf, int bufferIndex, Texture texture, glTFTextureTypes textureType) - { - var bytesWithMime = GetBytesWithMime(texture, textureType); ; - - // add view - var view = gltf.buffers[bufferIndex].Append(bytesWithMime.Bytes, glBufferTarget.NONE); - var viewIndex = gltf.AddBufferView(view); - - // add image - var imageIndex = gltf.images.Count; - gltf.images.Add(new glTFImage - { - name = texture.name, - bufferView = viewIndex, - mimeType = bytesWithMime.Mime, - }); - - // add sampler - var samplerIndex = gltf.samplers.Count; - var sampler = TextureSamplerUtil.Export(texture); - gltf.samplers.Add(sampler); - - // add texture - gltf.textures.Add(new glTFTexture - { - sampler = samplerIndex, - source = imageIndex, - }); - - return imageIndex; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + public static class TextureIO + { + public static RenderTextureReadWrite GetColorSpace(glTFTextureTypes textureType) + { + switch (textureType) + { + case glTFTextureTypes.Metallic: + case glTFTextureTypes.Normal: + case glTFTextureTypes.Occlusion: + return RenderTextureReadWrite.Linear; + case glTFTextureTypes.BaseColor: + case glTFTextureTypes.Emissive: + return RenderTextureReadWrite.sRGB; + default: + return RenderTextureReadWrite.sRGB; + } + } + + public static glTFTextureTypes GetglTFTextureType(string shaderName, string propName) + { + switch (propName) + { + case "_Color": + return glTFTextureTypes.BaseColor; + case "_MetallicGlossMap": + return glTFTextureTypes.Metallic; + case "_BumpMap": + return glTFTextureTypes.Normal; + case "_OcclusionMap": + return glTFTextureTypes.Occlusion; + case "_EmissionMap": + return glTFTextureTypes.Emissive; + default: + return glTFTextureTypes.Unknown; + } + } + + public static glTFTextureTypes GetglTFTextureType(glTF glTf, int textureIndex) + { + foreach (var material in glTf.materials) + { + var textureInfo = material.GetTextures().FirstOrDefault(x => (x!=null) && x.index == textureIndex); + if (textureInfo != null) + { + return textureInfo.TextreType; + } + } + return glTFTextureTypes.Unknown; + } + +#if UNITY_EDITOR + public static void MarkTextureAssetAsNormalMap(string assetPath) + { + if (string.IsNullOrEmpty(assetPath)) + { + return; + } + + var textureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter; + if (null == textureImporter) + { + return; + } + + //Debug.LogFormat("[MarkTextureAssetAsNormalMap] {0}", assetPath); + textureImporter.textureType = TextureImporterType.NormalMap; + textureImporter.SaveAndReimport(); + } +#endif + + public struct TextureExportItem + { + public Texture Texture; + public glTFTextureTypes TextureType; + + public TextureExportItem(Texture texture, glTFTextureTypes textureType) + { + Texture = texture; + TextureType = textureType; + } + } + + public static IEnumerable GetTextures(Material m) + { + var props = ShaderPropExporter.PreShaderPropExporter.GetPropsForSupportedShader(m.shader.name); + if (props == null) + { + yield return new TextureExportItem(m.mainTexture, glTFTextureTypes.BaseColor); + } + + foreach (var prop in props.Properties) + { + + if (prop.ShaderPropertyType == ShaderPropExporter.ShaderPropertyType.TexEnv) + { + yield return new TextureExportItem(m.GetTexture(prop.Key), GetglTFTextureType(m.shader.name, prop.Key)); + } + } + } + + + struct BytesWithMime + { + public Byte[] Bytes; + public string Mime; + } + + static BytesWithMime GetBytesWithMime(Texture texture, glTFTextureTypes textureType) + { +#if UNITY_EDITOR + var path = UnityPath.FromAsset(texture); + if (path.IsUnderAssetsFolder) + { + if (path.Extension == ".png") + { + return new BytesWithMime + { + Bytes = System.IO.File.ReadAllBytes(path.FullPath), + Mime = "image/png", + }; + } + } +#endif + + return new BytesWithMime + { + Bytes = TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), null).EncodeToPNG(), + Mime = "image/png", + }; + } + + public static int ExportTexture(glTF gltf, int bufferIndex, Texture texture, glTFTextureTypes textureType) + { + var bytesWithMime = GetBytesWithMime(texture, textureType); ; + + // add view + var view = gltf.buffers[bufferIndex].Append(bytesWithMime.Bytes, glBufferTarget.NONE); + var viewIndex = gltf.AddBufferView(view); + + // add image + var imageIndex = gltf.images.Count; + gltf.images.Add(new glTFImage + { + name = texture.name, + bufferView = viewIndex, + mimeType = bytesWithMime.Mime, + }); + + // add sampler + var samplerIndex = gltf.samplers.Count; + var sampler = TextureSamplerUtil.Export(texture); + gltf.samplers.Add(sampler); + + // add texture + gltf.textures.Add(new glTFTexture + { + sampler = samplerIndex, + source = imageIndex, + }); + + return imageIndex; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/TextureIO.cs.meta b/UniGLTF/Scripts/IO/TextureIO.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/TextureIO.cs.meta rename to UniGLTF/Scripts/IO/TextureIO.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/TextureItem.cs b/UniGLTF/Scripts/IO/TextureItem.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/TextureItem.cs rename to UniGLTF/Scripts/IO/TextureItem.cs index d77699e03..30031976c 100644 --- a/UniGLTF/Core/Scripts/IO/TextureItem.cs +++ b/UniGLTF/Scripts/IO/TextureItem.cs @@ -1,300 +1,300 @@ -using UnityEngine; -using System.Linq; -using System.Collections.Generic; -using System.Collections; -using System.IO; -using System; -using DepthFirstScheduler; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public class TextureItem - { - private int m_textureIndex; - public Texture2D Texture - { - get - { - return m_textureLoader.Texture; - } - } - - #region Texture converter - private Dictionary m_converts = new Dictionary(); - public Dictionary Converts - { - get { return m_converts; } - } - - public Texture2D ConvertTexture(string prop) - { - var convertedTexture = Converts.FirstOrDefault(x => x.Key == prop); - if (convertedTexture.Value != null) - return convertedTexture.Value; - - if (prop == "_BumpMap") - { - if (Application.isPlaying) - { - var converted = new NormalConverter().GetImportTexture(Texture); - m_converts.Add(prop, converted); - return converted; - } - else - { -#if UNITY_EDITOR - var textureAssetPath = AssetDatabase.GetAssetPath(Texture); - if (!string.IsNullOrEmpty(textureAssetPath)) - { - TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath); - } - else - { - Debug.LogWarningFormat("no asset for {0}", Texture); - } -#endif - return Texture; - } - } - - if (prop == "_MetallicGlossMap") - { - var converted = new MetallicRoughnessConverter().GetImportTexture(Texture); - m_converts.Add(prop, converted); - return converted; - } - - if (prop == "_OcclusionMap") - { - var converted = new OcclusionConverter().GetImportTexture(Texture); - m_converts.Add(prop, converted); - return converted; - } - - return null; - } - #endregion - - public bool IsAsset - { - private set; - get; - } - - public IEnumerable GetTexturesForSaveAssets() - { - if (!IsAsset) - { - yield return Texture; - } - if (m_converts.Any()) - { - foreach (var texture in m_converts) - { - yield return texture.Value; - } - } - } - - /// - /// Texture from buffer - /// - /// - public TextureItem(int index) - { - m_textureIndex = index; -#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER - m_textureLoader = new UnityWebRequestTextureLoader(m_textureIndex); -#else - m_textureLoader = new TextureLoader(m_textureIndex); -#endif - } - -#if UNITY_EDITOR - /// - /// Texture from asset - /// - /// - /// - /// - public TextureItem(int index, UnityPath assetPath, string textureName) - { - m_textureIndex = index; - IsAsset = true; - m_textureLoader = new AssetTextureLoader(assetPath, textureName); - } -#endif - - #region Process - ITextureLoader m_textureLoader; - - public void Process(glTF gltf, IStorage storage) - { - ProcessOnAnyThread(gltf, storage); - ProcessOnMainThreadCoroutine(gltf).CoroutinetoEnd(); - } - - public IEnumerator ProcessCoroutine(glTF gltf, IStorage storage) - { - ProcessOnAnyThread(gltf, storage); - yield return ProcessOnMainThreadCoroutine(gltf); - } - - public void ProcessOnAnyThread(glTF gltf, IStorage storage) - { - m_textureLoader.ProcessOnAnyThread(gltf, storage); - } - - public IEnumerator ProcessOnMainThreadCoroutine(glTF gltf) - { - using (m_textureLoader) - { - var textureType = TextureIO.GetglTFTextureType(gltf, m_textureIndex); - var colorSpace = TextureIO.GetColorSpace(textureType); - var isLinear = colorSpace == RenderTextureReadWrite.Linear; - yield return m_textureLoader.ProcessOnMainThread(isLinear); - TextureSamplerUtil.SetSampler(Texture, gltf.GetSamplerFromTextureIndex(m_textureIndex)); - } - } - #endregion - - struct ColorSpaceScope : IDisposable - { - bool m_sRGBWrite; - - public ColorSpaceScope(RenderTextureReadWrite colorSpace) - { - m_sRGBWrite = GL.sRGBWrite; - switch (colorSpace) - { - case RenderTextureReadWrite.Linear: - GL.sRGBWrite = false; - break; - - case RenderTextureReadWrite.sRGB: - default: - GL.sRGBWrite = true; - break; - } - } - public ColorSpaceScope(bool sRGBWrite) - { - m_sRGBWrite = GL.sRGBWrite; - GL.sRGBWrite = sRGBWrite; - } - - public void Dispose() - { - GL.sRGBWrite = m_sRGBWrite; - } - } - -#if UNITY_EDITOR && VRM_DEVELOP - [MenuItem("Assets/CopySRGBWrite", true)] - static bool CopySRGBWriteIsEnable() - { - return Selection.activeObject is Texture; - } - - [MenuItem("Assets/CopySRGBWrite")] - static void CopySRGBWrite() - { - CopySRGBWrite(true); - } - - [MenuItem("Assets/CopyNotSRGBWrite", true)] - static bool CopyNotSRGBWriteIsEnable() - { - return Selection.activeObject is Texture; - } - - [MenuItem("Assets/CopyNotSRGBWrite")] - static void CopyNotSRGBWrite() - { - CopySRGBWrite(false); - } - - static string AddPath(string path, string add) - { - return string.Format("{0}/{1}{2}{3}", - Path.GetDirectoryName(path), - Path.GetFileNameWithoutExtension(path), - add, - Path.GetExtension(path)); - } - - static void CopySRGBWrite(bool isSRGB) - { - var src = Selection.activeObject as Texture; - var texturePath = UnityPath.FromAsset(src); - - var path = EditorUtility.SaveFilePanel("save prefab", "Assets", - Path.GetFileNameWithoutExtension(AddPath(texturePath.FullPath, ".sRGB")), "prefab"); - var assetPath = UnityPath.FromFullpath(path); - if (!assetPath.IsUnderAssetsFolder) - { - return; - } - Debug.LogFormat("[CopySRGBWrite] {0} => {1}", texturePath, assetPath); - - var renderTexture = new RenderTexture(src.width, src.height, 0, - RenderTextureFormat.ARGB32, - RenderTextureReadWrite.sRGB); - using (var scope = new ColorSpaceScope(isSRGB)) - { - Graphics.Blit(src, renderTexture); - } - - var dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, - RenderTextureReadWrite.sRGB == RenderTextureReadWrite.Linear); - dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0); - dst.Apply(); - - RenderTexture.active = null; - - assetPath.CreateAsset(dst); - - GameObject.DestroyImmediate(renderTexture); - } -#endif - - public static Texture2D CopyTexture(Texture src, RenderTextureReadWrite colorSpace, Material material) - { - Texture2D dst = null; - - var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, colorSpace); - - using (var scope = new ColorSpaceScope(colorSpace)) - { - if (material != null) - { - Graphics.Blit(src, renderTexture, material); - } - else - { - Graphics.Blit(src, renderTexture); - } - } - - dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear); - dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0); - dst.name = src.name; - dst.Apply(); - - RenderTexture.active = null; - if (Application.isEditor) - { - GameObject.DestroyImmediate(renderTexture); - } - else - { - GameObject.Destroy(renderTexture); - } - return dst; - } - } -} +using UnityEngine; +using System.Linq; +using System.Collections.Generic; +using System.Collections; +using System.IO; +using System; +using DepthFirstScheduler; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + public class TextureItem + { + private int m_textureIndex; + public Texture2D Texture + { + get + { + return m_textureLoader.Texture; + } + } + + #region Texture converter + private Dictionary m_converts = new Dictionary(); + public Dictionary Converts + { + get { return m_converts; } + } + + public Texture2D ConvertTexture(string prop) + { + var convertedTexture = Converts.FirstOrDefault(x => x.Key == prop); + if (convertedTexture.Value != null) + return convertedTexture.Value; + + if (prop == "_BumpMap") + { + if (Application.isPlaying) + { + var converted = new NormalConverter().GetImportTexture(Texture); + m_converts.Add(prop, converted); + return converted; + } + else + { +#if UNITY_EDITOR + var textureAssetPath = AssetDatabase.GetAssetPath(Texture); + if (!string.IsNullOrEmpty(textureAssetPath)) + { + TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath); + } + else + { + Debug.LogWarningFormat("no asset for {0}", Texture); + } +#endif + return Texture; + } + } + + if (prop == "_MetallicGlossMap") + { + var converted = new MetallicRoughnessConverter().GetImportTexture(Texture); + m_converts.Add(prop, converted); + return converted; + } + + if (prop == "_OcclusionMap") + { + var converted = new OcclusionConverter().GetImportTexture(Texture); + m_converts.Add(prop, converted); + return converted; + } + + return null; + } + #endregion + + public bool IsAsset + { + private set; + get; + } + + public IEnumerable GetTexturesForSaveAssets() + { + if (!IsAsset) + { + yield return Texture; + } + if (m_converts.Any()) + { + foreach (var texture in m_converts) + { + yield return texture.Value; + } + } + } + + /// + /// Texture from buffer + /// + /// + public TextureItem(int index) + { + m_textureIndex = index; +#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER + m_textureLoader = new UnityWebRequestTextureLoader(m_textureIndex); +#else + m_textureLoader = new TextureLoader(m_textureIndex); +#endif + } + +#if UNITY_EDITOR + /// + /// Texture from asset + /// + /// + /// + /// + public TextureItem(int index, UnityPath assetPath, string textureName) + { + m_textureIndex = index; + IsAsset = true; + m_textureLoader = new AssetTextureLoader(assetPath, textureName); + } +#endif + + #region Process + ITextureLoader m_textureLoader; + + public void Process(glTF gltf, IStorage storage) + { + ProcessOnAnyThread(gltf, storage); + ProcessOnMainThreadCoroutine(gltf).CoroutinetoEnd(); + } + + public IEnumerator ProcessCoroutine(glTF gltf, IStorage storage) + { + ProcessOnAnyThread(gltf, storage); + yield return ProcessOnMainThreadCoroutine(gltf); + } + + public void ProcessOnAnyThread(glTF gltf, IStorage storage) + { + m_textureLoader.ProcessOnAnyThread(gltf, storage); + } + + public IEnumerator ProcessOnMainThreadCoroutine(glTF gltf) + { + using (m_textureLoader) + { + var textureType = TextureIO.GetglTFTextureType(gltf, m_textureIndex); + var colorSpace = TextureIO.GetColorSpace(textureType); + var isLinear = colorSpace == RenderTextureReadWrite.Linear; + yield return m_textureLoader.ProcessOnMainThread(isLinear); + TextureSamplerUtil.SetSampler(Texture, gltf.GetSamplerFromTextureIndex(m_textureIndex)); + } + } + #endregion + + struct ColorSpaceScope : IDisposable + { + bool m_sRGBWrite; + + public ColorSpaceScope(RenderTextureReadWrite colorSpace) + { + m_sRGBWrite = GL.sRGBWrite; + switch (colorSpace) + { + case RenderTextureReadWrite.Linear: + GL.sRGBWrite = false; + break; + + case RenderTextureReadWrite.sRGB: + default: + GL.sRGBWrite = true; + break; + } + } + public ColorSpaceScope(bool sRGBWrite) + { + m_sRGBWrite = GL.sRGBWrite; + GL.sRGBWrite = sRGBWrite; + } + + public void Dispose() + { + GL.sRGBWrite = m_sRGBWrite; + } + } + +#if UNITY_EDITOR && VRM_DEVELOP + [MenuItem("Assets/CopySRGBWrite", true)] + static bool CopySRGBWriteIsEnable() + { + return Selection.activeObject is Texture; + } + + [MenuItem("Assets/CopySRGBWrite")] + static void CopySRGBWrite() + { + CopySRGBWrite(true); + } + + [MenuItem("Assets/CopyNotSRGBWrite", true)] + static bool CopyNotSRGBWriteIsEnable() + { + return Selection.activeObject is Texture; + } + + [MenuItem("Assets/CopyNotSRGBWrite")] + static void CopyNotSRGBWrite() + { + CopySRGBWrite(false); + } + + static string AddPath(string path, string add) + { + return string.Format("{0}/{1}{2}{3}", + Path.GetDirectoryName(path), + Path.GetFileNameWithoutExtension(path), + add, + Path.GetExtension(path)); + } + + static void CopySRGBWrite(bool isSRGB) + { + var src = Selection.activeObject as Texture; + var texturePath = UnityPath.FromAsset(src); + + var path = EditorUtility.SaveFilePanel("save prefab", "Assets", + Path.GetFileNameWithoutExtension(AddPath(texturePath.FullPath, ".sRGB")), "prefab"); + var assetPath = UnityPath.FromFullpath(path); + if (!assetPath.IsUnderAssetsFolder) + { + return; + } + Debug.LogFormat("[CopySRGBWrite] {0} => {1}", texturePath, assetPath); + + var renderTexture = new RenderTexture(src.width, src.height, 0, + RenderTextureFormat.ARGB32, + RenderTextureReadWrite.sRGB); + using (var scope = new ColorSpaceScope(isSRGB)) + { + Graphics.Blit(src, renderTexture); + } + + var dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, + RenderTextureReadWrite.sRGB == RenderTextureReadWrite.Linear); + dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0); + dst.Apply(); + + RenderTexture.active = null; + + assetPath.CreateAsset(dst); + + GameObject.DestroyImmediate(renderTexture); + } +#endif + + public static Texture2D CopyTexture(Texture src, RenderTextureReadWrite colorSpace, Material material) + { + Texture2D dst = null; + + var renderTexture = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.ARGB32, colorSpace); + + using (var scope = new ColorSpaceScope(colorSpace)) + { + if (material != null) + { + Graphics.Blit(src, renderTexture, material); + } + else + { + Graphics.Blit(src, renderTexture); + } + } + + dst = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear); + dst.ReadPixels(new Rect(0, 0, src.width, src.height), 0, 0); + dst.name = src.name; + dst.Apply(); + + RenderTexture.active = null; + if (Application.isEditor) + { + GameObject.DestroyImmediate(renderTexture); + } + else + { + GameObject.Destroy(renderTexture); + } + return dst; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/TextureItem.cs.meta b/UniGLTF/Scripts/IO/TextureItem.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/TextureItem.cs.meta rename to UniGLTF/Scripts/IO/TextureItem.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/TextureLoader.cs b/UniGLTF/Scripts/IO/TextureLoader.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/TextureLoader.cs rename to UniGLTF/Scripts/IO/TextureLoader.cs index e8e10fa71..107c566bb 100644 --- a/UniGLTF/Core/Scripts/IO/TextureLoader.cs +++ b/UniGLTF/Scripts/IO/TextureLoader.cs @@ -1,297 +1,297 @@ -using System; -using System.Collections; -using System.IO; -using UnityEngine; -using UnityEngine.Networking; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public interface ITextureLoader : IDisposable - { - Texture2D Texture { get; } - - /// - /// Call from any thread - /// - /// - /// - void ProcessOnAnyThread(glTF gltf, IStorage storage); - - /// - /// Call from unity main thread - /// - /// - /// - IEnumerator ProcessOnMainThread(bool isLinear); - } - -#if UNITY_EDITOR - public class AssetTextureLoader : ITextureLoader - { - public Texture2D Texture - { - private set; - get; - } - - UnityPath m_assetPath; - - public AssetTextureLoader(UnityPath assetPath, string _) - { - m_assetPath = assetPath; - } - - public void Dispose() - { - } - - public void ProcessOnAnyThread(glTF gltf, IStorage storage) - { - } - - public IEnumerator ProcessOnMainThread(bool isLinear) - { - // - // texture from assets - // - m_assetPath.ImportAsset(); - var importer = m_assetPath.GetImporter(); - if (importer == null) - { - Debug.LogWarningFormat("fail to get TextureImporter: {0}", m_assetPath); - } - importer.sRGBTexture = !isLinear; - importer.SaveAndReimport(); - - Texture = m_assetPath.LoadAsset(); - //Texture.name = m_textureName; - if (Texture == null) - { - Debug.LogWarningFormat("fail to Load Texture2D: {0}", m_assetPath); - } - - yield break; - } - } -#endif - - public class TextureLoader : ITextureLoader - { - int m_textureIndex; - public TextureLoader(int textureIndex) - { - m_textureIndex = textureIndex; - } - - public Texture2D Texture - { - private set; - get; - } - - public void Dispose() - { - } - - static Byte[] ToArray(ArraySegment bytes) - { - if (bytes.Array == null) - { - return new byte[] { }; - } - else if (bytes.Offset == 0 && bytes.Count == bytes.Array.Length) - { - return bytes.Array; - } - else - { - Byte[] result = new byte[bytes.Count]; - Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length); - return result; - } - } - - Byte[] m_imageBytes; - string m_textureName; - public void ProcessOnAnyThread(glTF gltf, IStorage storage) - { - var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex); - var segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName); - m_imageBytes = ToArray(segments); - } - - public IEnumerator ProcessOnMainThread(bool isLinear) - { - // - // texture from image(png etc) bytes - // - Texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, isLinear); - Texture.name = m_textureName; - if (m_imageBytes != null) - { - Texture.LoadImage(m_imageBytes); - } - yield break; - } - } - - public class UnityWebRequestTextureLoader : ITextureLoader - { - public Texture2D Texture - { - private set; - get; - } - - int m_textureIndex; - - public UnityWebRequestTextureLoader(int textureIndex) - { - m_textureIndex = textureIndex; - } - - UnityWebRequest m_uwr; - public void Dispose() - { - if (m_uwr != null) - { - m_uwr.Dispose(); - m_uwr = null; - } - } - - ArraySegment m_segments; - string m_textureName; - public void ProcessOnAnyThread(glTF gltf, IStorage storage) - { - var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex); - m_segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName); - } - -#if false - HttpHost m_http; - class HttpHost : IDisposable - { - TcpListener m_listener; - Socket m_connection; - - public HttpHost(int port) - { - m_listener = new TcpListener(IPAddress.Loopback, port); - m_listener.Start(); - m_listener.BeginAcceptSocket(OnAccepted, m_listener); - } - - void OnAccepted(IAsyncResult ar) - { - var l = ar.AsyncState as TcpListener; - if (l == null) return; - m_connection = l.EndAcceptSocket(ar); - // 次の接続受付はしない - - BeginRead(m_connection, new byte[8192]); - } - - void BeginRead(Socket c, byte[] buffer) - { - AsyncCallback callback = ar => - { - var s = ar.AsyncState as Socket; - if (s == null) return; - var size = s.EndReceive(ar); - if (size > 0) - { - OnRead(buffer, size); - } - BeginRead(s, buffer); - }; - m_connection.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, callback, m_connection); - } - - List m_buffer = new List(); - void OnRead(byte[] buffer, int len) - { - m_buffer.AddRange(buffer.Take(len)); - } - - public string Url - { - get - { - - } - } - - public void Dispose() - { - if (m_connection != null) - { - m_connection.Dispose(); - m_connection = null; - } - if(m_listener != null) - { - m_listener.Stop(); - m_listener = null; - } - } - } -#endif - - class Deleter : IDisposable - { - string m_path; - public Deleter(string path) - { - m_path = path; - } - public void Dispose() - { - if (File.Exists(m_path)) - { - File.Delete(m_path); - } - } - } - - public IEnumerator ProcessOnMainThread(bool isLinear) - { - // tmp file - var tmp = Path.GetTempFileName(); - using (var f = new FileStream(tmp, FileMode.Create)) - { - f.Write(m_segments.Array, m_segments.Offset, m_segments.Count); - } - - using (var d = new Deleter(tmp)) - { - var url = "file:///" + tmp.Replace("\\", "/"); - Debug.LogFormat("UnityWebRequest: {0}", url); - using (var m_uwr = new WWW(url)) - { - yield return m_uwr; - - // wait for request - while (!m_uwr.isDone) - { - yield return null; - } - - if (!string.IsNullOrEmpty(m_uwr.error)) - { - Debug.Log(m_uwr.error); - yield break; - } - - // Get downloaded asset bundle - Texture = m_uwr.textureNonReadable; - Texture.name = m_textureName; - } - } - } - } -} +using System; +using System.Collections; +using System.IO; +using UnityEngine; +using UnityEngine.Networking; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + public interface ITextureLoader : IDisposable + { + Texture2D Texture { get; } + + /// + /// Call from any thread + /// + /// + /// + void ProcessOnAnyThread(glTF gltf, IStorage storage); + + /// + /// Call from unity main thread + /// + /// + /// + IEnumerator ProcessOnMainThread(bool isLinear); + } + +#if UNITY_EDITOR + public class AssetTextureLoader : ITextureLoader + { + public Texture2D Texture + { + private set; + get; + } + + UnityPath m_assetPath; + + public AssetTextureLoader(UnityPath assetPath, string _) + { + m_assetPath = assetPath; + } + + public void Dispose() + { + } + + public void ProcessOnAnyThread(glTF gltf, IStorage storage) + { + } + + public IEnumerator ProcessOnMainThread(bool isLinear) + { + // + // texture from assets + // + m_assetPath.ImportAsset(); + var importer = m_assetPath.GetImporter(); + if (importer == null) + { + Debug.LogWarningFormat("fail to get TextureImporter: {0}", m_assetPath); + } + importer.sRGBTexture = !isLinear; + importer.SaveAndReimport(); + + Texture = m_assetPath.LoadAsset(); + //Texture.name = m_textureName; + if (Texture == null) + { + Debug.LogWarningFormat("fail to Load Texture2D: {0}", m_assetPath); + } + + yield break; + } + } +#endif + + public class TextureLoader : ITextureLoader + { + int m_textureIndex; + public TextureLoader(int textureIndex) + { + m_textureIndex = textureIndex; + } + + public Texture2D Texture + { + private set; + get; + } + + public void Dispose() + { + } + + static Byte[] ToArray(ArraySegment bytes) + { + if (bytes.Array == null) + { + return new byte[] { }; + } + else if (bytes.Offset == 0 && bytes.Count == bytes.Array.Length) + { + return bytes.Array; + } + else + { + Byte[] result = new byte[bytes.Count]; + Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length); + return result; + } + } + + Byte[] m_imageBytes; + string m_textureName; + public void ProcessOnAnyThread(glTF gltf, IStorage storage) + { + var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex); + var segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName); + m_imageBytes = ToArray(segments); + } + + public IEnumerator ProcessOnMainThread(bool isLinear) + { + // + // texture from image(png etc) bytes + // + Texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, isLinear); + Texture.name = m_textureName; + if (m_imageBytes != null) + { + Texture.LoadImage(m_imageBytes); + } + yield break; + } + } + + public class UnityWebRequestTextureLoader : ITextureLoader + { + public Texture2D Texture + { + private set; + get; + } + + int m_textureIndex; + + public UnityWebRequestTextureLoader(int textureIndex) + { + m_textureIndex = textureIndex; + } + + UnityWebRequest m_uwr; + public void Dispose() + { + if (m_uwr != null) + { + m_uwr.Dispose(); + m_uwr = null; + } + } + + ArraySegment m_segments; + string m_textureName; + public void ProcessOnAnyThread(glTF gltf, IStorage storage) + { + var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex); + m_segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName); + } + +#if false + HttpHost m_http; + class HttpHost : IDisposable + { + TcpListener m_listener; + Socket m_connection; + + public HttpHost(int port) + { + m_listener = new TcpListener(IPAddress.Loopback, port); + m_listener.Start(); + m_listener.BeginAcceptSocket(OnAccepted, m_listener); + } + + void OnAccepted(IAsyncResult ar) + { + var l = ar.AsyncState as TcpListener; + if (l == null) return; + m_connection = l.EndAcceptSocket(ar); + // 次の接続受付はしない + + BeginRead(m_connection, new byte[8192]); + } + + void BeginRead(Socket c, byte[] buffer) + { + AsyncCallback callback = ar => + { + var s = ar.AsyncState as Socket; + if (s == null) return; + var size = s.EndReceive(ar); + if (size > 0) + { + OnRead(buffer, size); + } + BeginRead(s, buffer); + }; + m_connection.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, callback, m_connection); + } + + List m_buffer = new List(); + void OnRead(byte[] buffer, int len) + { + m_buffer.AddRange(buffer.Take(len)); + } + + public string Url + { + get + { + + } + } + + public void Dispose() + { + if (m_connection != null) + { + m_connection.Dispose(); + m_connection = null; + } + if(m_listener != null) + { + m_listener.Stop(); + m_listener = null; + } + } + } +#endif + + class Deleter : IDisposable + { + string m_path; + public Deleter(string path) + { + m_path = path; + } + public void Dispose() + { + if (File.Exists(m_path)) + { + File.Delete(m_path); + } + } + } + + public IEnumerator ProcessOnMainThread(bool isLinear) + { + // tmp file + var tmp = Path.GetTempFileName(); + using (var f = new FileStream(tmp, FileMode.Create)) + { + f.Write(m_segments.Array, m_segments.Offset, m_segments.Count); + } + + using (var d = new Deleter(tmp)) + { + var url = "file:///" + tmp.Replace("\\", "/"); + Debug.LogFormat("UnityWebRequest: {0}", url); + using (var m_uwr = new WWW(url)) + { + yield return m_uwr; + + // wait for request + while (!m_uwr.isDone) + { + yield return null; + } + + if (!string.IsNullOrEmpty(m_uwr.error)) + { + Debug.Log(m_uwr.error); + yield break; + } + + // Get downloaded asset bundle + Texture = m_uwr.textureNonReadable; + Texture.name = m_textureName; + } + } + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/TextureLoader.cs.meta b/UniGLTF/Scripts/IO/TextureLoader.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/TextureLoader.cs.meta rename to UniGLTF/Scripts/IO/TextureLoader.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/TextureSamplerUtil.cs b/UniGLTF/Scripts/IO/TextureSamplerUtil.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/TextureSamplerUtil.cs rename to UniGLTF/Scripts/IO/TextureSamplerUtil.cs index 00b3beea1..c6339e2b2 100644 --- a/UniGLTF/Core/Scripts/IO/TextureSamplerUtil.cs +++ b/UniGLTF/Scripts/IO/TextureSamplerUtil.cs @@ -1,257 +1,257 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - - -namespace UniGLTF -{ - public static class TextureSamplerUtil - { - #region WrapMode - public enum TextureWrapType - { - All, -#if UNITY_2017_1_OR_NEWER - U, - V, - W, -#endif - } - - public static KeyValuePair TypeWithMode(TextureWrapType type, TextureWrapMode mode) - { - return new KeyValuePair(type, mode); - } - - public static IEnumerable> GetUnityWrapMode(glTFTextureSampler sampler) - { -#if UNITY_2017_1_OR_NEWER - if (sampler.wrapS == sampler.wrapT) - { - switch (sampler.wrapS) - { - case glWrap.NONE: // default - yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Repeat); - break; - - case glWrap.CLAMP_TO_EDGE: - yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Clamp); - break; - - case glWrap.REPEAT: - yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Repeat); - break; - - case glWrap.MIRRORED_REPEAT: - yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Mirror); - break; - - default: - throw new NotImplementedException(); - } - } - else - { - switch (sampler.wrapS) - { - case glWrap.NONE: // default - yield return TypeWithMode(TextureWrapType.U, TextureWrapMode.Repeat); - break; - - case glWrap.CLAMP_TO_EDGE: - yield return TypeWithMode(TextureWrapType.U, TextureWrapMode.Clamp); - break; - - case glWrap.REPEAT: - yield return TypeWithMode(TextureWrapType.U, TextureWrapMode.Repeat); - break; - - case glWrap.MIRRORED_REPEAT: - yield return TypeWithMode(TextureWrapType.U, TextureWrapMode.Mirror); - break; - - default: - throw new NotImplementedException(); - } - switch (sampler.wrapT) - { - case glWrap.NONE: // default - yield return TypeWithMode(TextureWrapType.V, TextureWrapMode.Repeat); - break; - - case glWrap.CLAMP_TO_EDGE: - yield return TypeWithMode(TextureWrapType.V, TextureWrapMode.Clamp); - break; - - case glWrap.REPEAT: - yield return TypeWithMode(TextureWrapType.V, TextureWrapMode.Repeat); - break; - - case glWrap.MIRRORED_REPEAT: - yield return TypeWithMode(TextureWrapType.V, TextureWrapMode.Mirror); - break; - - default: - throw new NotImplementedException(); - } -#else - // Unity2017.1より前 - // * wrapSとwrapTの区別が無くてwrapしかない - // * Mirrorが無い - - switch (sampler.wrapS) - { - case glWrap.NONE: // default - yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Repeat); - break; - - case glWrap.CLAMP_TO_EDGE: - case glWrap.MIRRORED_REPEAT: - yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Clamp); - break; - - case glWrap.REPEAT: - yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Repeat); - break; - - default: - throw new NotImplementedException(); -#endif - } - } - #endregion - - public static FilterMode ImportFilterMode(glFilter filterMode) - { - switch (filterMode) - { - case glFilter.NEAREST: - case glFilter.NEAREST_MIPMAP_LINEAR: - case glFilter.NEAREST_MIPMAP_NEAREST: - return FilterMode.Point; - - case glFilter.NONE: - case glFilter.LINEAR: - case glFilter.LINEAR_MIPMAP_NEAREST: - return FilterMode.Bilinear; - - case glFilter.LINEAR_MIPMAP_LINEAR: - return FilterMode.Trilinear; - - default: - throw new NotImplementedException(); - - } - } - - public static void SetSampler(Texture2D texture, glTFTextureSampler sampler) - { - if (texture == null) - { - return; - } - - foreach (var kv in GetUnityWrapMode(sampler)) - { - switch (kv.Key) - { - case TextureWrapType.All: - texture.wrapMode = kv.Value; - break; - -#if UNITY_2017_1_OR_NEWER - case TextureWrapType.U: - texture.wrapModeU = kv.Value; - break; - - case TextureWrapType.V: - texture.wrapModeV = kv.Value; - break; - - case TextureWrapType.W: - texture.wrapModeW = kv.Value; - break; -#endif - - default: - throw new NotImplementedException(); - } - } - - texture.filterMode = ImportFilterMode(sampler.minFilter); - } - - #region Export - public static glFilter ExportFilterMode(Texture texture) - { - switch (texture.filterMode) - { - case FilterMode.Point: - return glFilter.NEAREST; - - case FilterMode.Bilinear: - return glFilter.LINEAR; - - case FilterMode.Trilinear: - return glFilter.LINEAR_MIPMAP_LINEAR; - - default: - throw new NotImplementedException(); - } - } - - public static TextureWrapMode GetWrapS(Texture texture) - { -#if UNITY_2017_1_OR_NEWER - return texture.wrapModeU; -#else - return texture.wrapMode; -#endif - } - - public static TextureWrapMode GetWrapT(Texture texture) - { -#if UNITY_2017_1_OR_NEWER - return texture.wrapModeV; -#else - return texture.wrapMode; -#endif - } - - public static glWrap ExportWrapMode(TextureWrapMode wrapMode) - { - switch (wrapMode) - { - case TextureWrapMode.Clamp: - return glWrap.CLAMP_TO_EDGE; - - case TextureWrapMode.Repeat: - return glWrap.REPEAT; - -#if UNITY_2017_1_OR_NEWER - case TextureWrapMode.Mirror: - case TextureWrapMode.MirrorOnce: - return glWrap.MIRRORED_REPEAT; -#endif - - default: - throw new NotImplementedException(); - } - } - - public static glTFTextureSampler Export(Texture texture) - { - var filter = ExportFilterMode(texture); - var wrapS = ExportWrapMode(GetWrapS(texture)); - var wrapT = ExportWrapMode(GetWrapT(texture)); - return new glTFTextureSampler - { - magFilter = filter, - minFilter = filter, - wrapS = wrapS, - wrapT = wrapT, - }; - } - #endregion - } -} +using System; +using System.Collections.Generic; +using UnityEngine; + + +namespace UniGLTF +{ + public static class TextureSamplerUtil + { + #region WrapMode + public enum TextureWrapType + { + All, +#if UNITY_2017_1_OR_NEWER + U, + V, + W, +#endif + } + + public static KeyValuePair TypeWithMode(TextureWrapType type, TextureWrapMode mode) + { + return new KeyValuePair(type, mode); + } + + public static IEnumerable> GetUnityWrapMode(glTFTextureSampler sampler) + { +#if UNITY_2017_1_OR_NEWER + if (sampler.wrapS == sampler.wrapT) + { + switch (sampler.wrapS) + { + case glWrap.NONE: // default + yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Repeat); + break; + + case glWrap.CLAMP_TO_EDGE: + yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Clamp); + break; + + case glWrap.REPEAT: + yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Repeat); + break; + + case glWrap.MIRRORED_REPEAT: + yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Mirror); + break; + + default: + throw new NotImplementedException(); + } + } + else + { + switch (sampler.wrapS) + { + case glWrap.NONE: // default + yield return TypeWithMode(TextureWrapType.U, TextureWrapMode.Repeat); + break; + + case glWrap.CLAMP_TO_EDGE: + yield return TypeWithMode(TextureWrapType.U, TextureWrapMode.Clamp); + break; + + case glWrap.REPEAT: + yield return TypeWithMode(TextureWrapType.U, TextureWrapMode.Repeat); + break; + + case glWrap.MIRRORED_REPEAT: + yield return TypeWithMode(TextureWrapType.U, TextureWrapMode.Mirror); + break; + + default: + throw new NotImplementedException(); + } + switch (sampler.wrapT) + { + case glWrap.NONE: // default + yield return TypeWithMode(TextureWrapType.V, TextureWrapMode.Repeat); + break; + + case glWrap.CLAMP_TO_EDGE: + yield return TypeWithMode(TextureWrapType.V, TextureWrapMode.Clamp); + break; + + case glWrap.REPEAT: + yield return TypeWithMode(TextureWrapType.V, TextureWrapMode.Repeat); + break; + + case glWrap.MIRRORED_REPEAT: + yield return TypeWithMode(TextureWrapType.V, TextureWrapMode.Mirror); + break; + + default: + throw new NotImplementedException(); + } +#else + // Unity2017.1より前 + // * wrapSとwrapTの区別が無くてwrapしかない + // * Mirrorが無い + + switch (sampler.wrapS) + { + case glWrap.NONE: // default + yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Repeat); + break; + + case glWrap.CLAMP_TO_EDGE: + case glWrap.MIRRORED_REPEAT: + yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Clamp); + break; + + case glWrap.REPEAT: + yield return TypeWithMode(TextureWrapType.All, TextureWrapMode.Repeat); + break; + + default: + throw new NotImplementedException(); +#endif + } + } + #endregion + + public static FilterMode ImportFilterMode(glFilter filterMode) + { + switch (filterMode) + { + case glFilter.NEAREST: + case glFilter.NEAREST_MIPMAP_LINEAR: + case glFilter.NEAREST_MIPMAP_NEAREST: + return FilterMode.Point; + + case glFilter.NONE: + case glFilter.LINEAR: + case glFilter.LINEAR_MIPMAP_NEAREST: + return FilterMode.Bilinear; + + case glFilter.LINEAR_MIPMAP_LINEAR: + return FilterMode.Trilinear; + + default: + throw new NotImplementedException(); + + } + } + + public static void SetSampler(Texture2D texture, glTFTextureSampler sampler) + { + if (texture == null) + { + return; + } + + foreach (var kv in GetUnityWrapMode(sampler)) + { + switch (kv.Key) + { + case TextureWrapType.All: + texture.wrapMode = kv.Value; + break; + +#if UNITY_2017_1_OR_NEWER + case TextureWrapType.U: + texture.wrapModeU = kv.Value; + break; + + case TextureWrapType.V: + texture.wrapModeV = kv.Value; + break; + + case TextureWrapType.W: + texture.wrapModeW = kv.Value; + break; +#endif + + default: + throw new NotImplementedException(); + } + } + + texture.filterMode = ImportFilterMode(sampler.minFilter); + } + + #region Export + public static glFilter ExportFilterMode(Texture texture) + { + switch (texture.filterMode) + { + case FilterMode.Point: + return glFilter.NEAREST; + + case FilterMode.Bilinear: + return glFilter.LINEAR; + + case FilterMode.Trilinear: + return glFilter.LINEAR_MIPMAP_LINEAR; + + default: + throw new NotImplementedException(); + } + } + + public static TextureWrapMode GetWrapS(Texture texture) + { +#if UNITY_2017_1_OR_NEWER + return texture.wrapModeU; +#else + return texture.wrapMode; +#endif + } + + public static TextureWrapMode GetWrapT(Texture texture) + { +#if UNITY_2017_1_OR_NEWER + return texture.wrapModeV; +#else + return texture.wrapMode; +#endif + } + + public static glWrap ExportWrapMode(TextureWrapMode wrapMode) + { + switch (wrapMode) + { + case TextureWrapMode.Clamp: + return glWrap.CLAMP_TO_EDGE; + + case TextureWrapMode.Repeat: + return glWrap.REPEAT; + +#if UNITY_2017_1_OR_NEWER + case TextureWrapMode.Mirror: + case TextureWrapMode.MirrorOnce: + return glWrap.MIRRORED_REPEAT; +#endif + + default: + throw new NotImplementedException(); + } + } + + public static glTFTextureSampler Export(Texture texture) + { + var filter = ExportFilterMode(texture); + var wrapS = ExportWrapMode(GetWrapS(texture)); + var wrapT = ExportWrapMode(GetWrapT(texture)); + return new glTFTextureSampler + { + magFilter = filter, + minFilter = filter, + wrapS = wrapS, + wrapT = wrapT, + }; + } + #endregion + } +} diff --git a/UniGLTF/Core/Scripts/IO/TextureSamplerUtil.cs.meta b/UniGLTF/Scripts/IO/TextureSamplerUtil.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/TextureSamplerUtil.cs.meta rename to UniGLTF/Scripts/IO/TextureSamplerUtil.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/TriangleUtil.cs b/UniGLTF/Scripts/IO/TriangleUtil.cs similarity index 95% rename from UniGLTF/Core/Scripts/IO/TriangleUtil.cs rename to UniGLTF/Scripts/IO/TriangleUtil.cs index c77e806ac..b5b935966 100644 --- a/UniGLTF/Core/Scripts/IO/TriangleUtil.cs +++ b/UniGLTF/Scripts/IO/TriangleUtil.cs @@ -1,51 +1,51 @@ -using System; -using System.Linq; -using System.Collections.Generic; - - -public static class TriangleUtil -{ - public static IEnumerable FlipTriangle(IEnumerable src) - { - return FlipTriangle(src.Select(x => (Int32)x)); - } - - public static IEnumerable FlipTriangle(IEnumerable src) - { - return FlipTriangle(src.Select(x => (Int32)x)); - } - - public static IEnumerable FlipTriangle(IEnumerable src) - { - return FlipTriangle(src.Select(x => (Int32)x)); - } - - public static IEnumerable FlipTriangle(IEnumerable src) - { - var it = src.GetEnumerator(); - while (true) - { - if (!it.MoveNext()) - { - yield break; - } - var i0 = it.Current; - - if (!it.MoveNext()) - { - yield break; - } - var i1 = it.Current; - - if (!it.MoveNext()) - { - yield break; - } - var i2 = it.Current; - - yield return i2; - yield return i1; - yield return i0; - } - } -} +using System; +using System.Linq; +using System.Collections.Generic; + + +public static class TriangleUtil +{ + public static IEnumerable FlipTriangle(IEnumerable src) + { + return FlipTriangle(src.Select(x => (Int32)x)); + } + + public static IEnumerable FlipTriangle(IEnumerable src) + { + return FlipTriangle(src.Select(x => (Int32)x)); + } + + public static IEnumerable FlipTriangle(IEnumerable src) + { + return FlipTriangle(src.Select(x => (Int32)x)); + } + + public static IEnumerable FlipTriangle(IEnumerable src) + { + var it = src.GetEnumerator(); + while (true) + { + if (!it.MoveNext()) + { + yield break; + } + var i0 = it.Current; + + if (!it.MoveNext()) + { + yield break; + } + var i1 = it.Current; + + if (!it.MoveNext()) + { + yield break; + } + var i2 = it.Current; + + yield return i2; + yield return i1; + yield return i0; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/TriangleUtil.cs.meta b/UniGLTF/Scripts/IO/TriangleUtil.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/TriangleUtil.cs.meta rename to UniGLTF/Scripts/IO/TriangleUtil.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/UnityPath.cs b/UniGLTF/Scripts/IO/UnityPath.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/UnityPath.cs rename to UniGLTF/Scripts/IO/UnityPath.cs index e54290920..08b5d784b 100644 --- a/UniGLTF/Core/Scripts/IO/UnityPath.cs +++ b/UniGLTF/Scripts/IO/UnityPath.cs @@ -1,411 +1,411 @@ -using System; -using System.IO; -using UnityEngine; -using System.Collections.Generic; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - /// - /// relative path from Unity project root. - /// For AssetDatabase. - /// - public struct UnityPath - { - #region UnityPath - public string Value - { - get; - private set; - } - - public override string ToString() - { - return string.Format("unity://{0}", Value); - } - - public bool IsNull - { - get { return Value == null; } - } - - public bool IsUnderAssetsFolder - { - get - { - if (IsNull) - { - return false; - } - return Value == "Assets" || Value.StartsWith("Assets/"); - } - } - - public string FileNameWithoutExtension - { - get { return Path.GetFileNameWithoutExtension(Value); } - } - - public string Extension - { - get { return Path.GetExtension(Value); } - } - - public UnityPath Parent - { - get - { - if (IsNull) - { - return default(UnityPath); - } - - return new UnityPath(Path.GetDirectoryName(Value)); - } - } - - public bool HasParent - { - get - { - return !string.IsNullOrEmpty(Value); - } - } - - static readonly char[] EscapeChars = new char[] - { - '\\', - '/', - ':', - '*', - '?', - '"', - '<', - '>', - '|', - }; - - static string EscapeFilePath(string path) - { - foreach (var x in EscapeChars) - { - path = path.Replace(x, '+'); - } - return path; - } - - public UnityPath Child(string name) - { - if (IsNull) - { - throw new NotImplementedException(); - } - else if (Value == "") - { - return new UnityPath(name); - } - else - { - return new UnityPath(Value + "/" + name); - } - } - - public override int GetHashCode() - { - if (IsNull) - { - return 0; - } - return Value.GetHashCode(); - } - - public override bool Equals(object obj) - { - if(obj is UnityPath) - { - var rhs = (UnityPath)obj; - if(Value==null && rhs.Value == null) - { - return true; - } - else if (Value == null) - { - return false; - } - else if (rhs.Value == null) - { - return false; - } - else - { - return Value == rhs.Value; - } - } - else - { - return false; - } - } - - /// - /// Remove extension and add suffix - /// - /// - /// - /// - public UnityPath GetAssetFolder(string suffix) - { - if (!IsUnderAssetsFolder) - { - throw new NotImplementedException(); - } - - return new UnityPath( - string.Format("{0}/{1}{2}", - Parent.Value, - FileNameWithoutExtension, - suffix - )); - } - - UnityPath(string value) - { - Value = value.Replace("\\", "/"); - } - - /// - /// - /// - /// Relative from unity current path. GetParent(Application.dataPath) - /// - public static UnityPath FromUnityPath(string unityPath) - { - if (String.IsNullOrEmpty(unityPath)) - { - return new UnityPath - { - Value="" - }; - } - return FromFullpath(Path.GetFullPath(unityPath)); - } - #endregion - - #region FullPath - static string s_basePath; - static string BaseFullPath - { - get - { - if (string.IsNullOrEmpty(s_basePath)) - { - s_basePath = Path.GetFullPath(Application.dataPath + "/..").Replace("\\", "/"); - } - return s_basePath; - } - } - - static string AssetFullPath - { - get - { - return BaseFullPath + "/Assets"; - } - } - - public string FullPath - { - get - { - if (IsNull) - { - throw new NotImplementedException(); - } - return Path.Combine(BaseFullPath, Value).Replace("\\", "/"); - } - } - - public bool IsFileExists - { - get { return File.Exists(FullPath); } - } - - public bool IsDirectoryExists - { - get { return Directory.Exists(FullPath); } - } - - /// - /// - /// - /// C:/path/to/file - /// - public static UnityPath FromFullpath(string fullPath) - { - if(fullPath == null) - { - fullPath = ""; - } - fullPath = fullPath.Replace("\\", "/"); - - if (fullPath == BaseFullPath) { - return new UnityPath - { - Value="" - }; - } - else if(fullPath.StartsWith(BaseFullPath + "/")) - { - return new UnityPath(fullPath.Substring(BaseFullPath.Length + 1)); - } - else - { - return default(UnityPath); - } - } - - public static bool IsUnderAssetFolder(string fullPath) - { - return fullPath.Replace("\\", "/").StartsWith(AssetFullPath); - } - #endregion - - public IEnumerable TravserseDir() - { - if (IsDirectoryExists) - { - yield return this; - - foreach(var child in ChildDirs) - { - foreach(var x in child.TravserseDir()) - { - yield return x; - } - } - } - } - - public IEnumerable ChildDirs - { - get - { - foreach(var x in Directory.GetDirectories(FullPath)) - { - yield return UnityPath.FromFullpath(x); - } - } - } - - public IEnumerable ChildFiles - { - get - { - foreach (var x in Directory.GetFiles(FullPath)) - { - yield return UnityPath.FromFullpath(x); - } - } - } - -#if UNITY_EDITOR - public T GetImporter() where T : AssetImporter - { - return AssetImporter.GetAtPath(Value) as T; - } - - public static UnityPath FromAsset(UnityEngine.Object asset) - { - return new UnityPath(AssetDatabase.GetAssetPath(asset)); - } - - public void ImportAsset() - { - if (!IsUnderAssetsFolder) - { - throw new NotImplementedException(); - } - AssetDatabase.ImportAsset(Value); - } - - public void EnsureFolder() - { - if (IsNull) - { - throw new NotImplementedException(); - } - - if (HasParent) - { - Parent.EnsureFolder(); - } - - if (!IsDirectoryExists) - { - var parent = Parent; - // ensure parent - parent.ImportAsset(); - // create - AssetDatabase.CreateFolder( - parent.Value, - Path.GetFileName(Value) - ); - ImportAsset(); - } - } - - public UnityEngine.Object[] GetSubAssets() - { - if (!IsUnderAssetsFolder) - { - throw new NotImplementedException(); - } - - return AssetDatabase.LoadAllAssetsAtPath(Value); - } - - public void CreateAsset(UnityEngine.Object o) - { - if (!IsUnderAssetsFolder) - { - throw new NotImplementedException(); - } - - AssetDatabase.CreateAsset(o, Value); - } - - public void AddObjectToAsset(UnityEngine.Object o) - { - if (!IsUnderAssetsFolder) - { - throw new NotImplementedException(); - } - - AssetDatabase.AddObjectToAsset(o, Value); - } - - public T LoadAsset() where T : UnityEngine.Object - { - if (!IsUnderAssetsFolder) - { - throw new NotImplementedException(); - } - - return AssetDatabase.LoadAssetAtPath(Value); - } - - public UnityPath GenerateUniqueAssetPath() - { - if (!IsUnderAssetsFolder) - { - throw new NotImplementedException(); - } - - return new UnityPath(AssetDatabase.GenerateUniqueAssetPath(Value)); - } - #endif - } -} +using System; +using System.IO; +using UnityEngine; +using System.Collections.Generic; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + /// + /// relative path from Unity project root. + /// For AssetDatabase. + /// + public struct UnityPath + { + #region UnityPath + public string Value + { + get; + private set; + } + + public override string ToString() + { + return string.Format("unity://{0}", Value); + } + + public bool IsNull + { + get { return Value == null; } + } + + public bool IsUnderAssetsFolder + { + get + { + if (IsNull) + { + return false; + } + return Value == "Assets" || Value.StartsWith("Assets/"); + } + } + + public string FileNameWithoutExtension + { + get { return Path.GetFileNameWithoutExtension(Value); } + } + + public string Extension + { + get { return Path.GetExtension(Value); } + } + + public UnityPath Parent + { + get + { + if (IsNull) + { + return default(UnityPath); + } + + return new UnityPath(Path.GetDirectoryName(Value)); + } + } + + public bool HasParent + { + get + { + return !string.IsNullOrEmpty(Value); + } + } + + static readonly char[] EscapeChars = new char[] + { + '\\', + '/', + ':', + '*', + '?', + '"', + '<', + '>', + '|', + }; + + static string EscapeFilePath(string path) + { + foreach (var x in EscapeChars) + { + path = path.Replace(x, '+'); + } + return path; + } + + public UnityPath Child(string name) + { + if (IsNull) + { + throw new NotImplementedException(); + } + else if (Value == "") + { + return new UnityPath(name); + } + else + { + return new UnityPath(Value + "/" + name); + } + } + + public override int GetHashCode() + { + if (IsNull) + { + return 0; + } + return Value.GetHashCode(); + } + + public override bool Equals(object obj) + { + if(obj is UnityPath) + { + var rhs = (UnityPath)obj; + if(Value==null && rhs.Value == null) + { + return true; + } + else if (Value == null) + { + return false; + } + else if (rhs.Value == null) + { + return false; + } + else + { + return Value == rhs.Value; + } + } + else + { + return false; + } + } + + /// + /// Remove extension and add suffix + /// + /// + /// + /// + public UnityPath GetAssetFolder(string suffix) + { + if (!IsUnderAssetsFolder) + { + throw new NotImplementedException(); + } + + return new UnityPath( + string.Format("{0}/{1}{2}", + Parent.Value, + FileNameWithoutExtension, + suffix + )); + } + + UnityPath(string value) + { + Value = value.Replace("\\", "/"); + } + + /// + /// + /// + /// Relative from unity current path. GetParent(Application.dataPath) + /// + public static UnityPath FromUnityPath(string unityPath) + { + if (String.IsNullOrEmpty(unityPath)) + { + return new UnityPath + { + Value="" + }; + } + return FromFullpath(Path.GetFullPath(unityPath)); + } + #endregion + + #region FullPath + static string s_basePath; + static string BaseFullPath + { + get + { + if (string.IsNullOrEmpty(s_basePath)) + { + s_basePath = Path.GetFullPath(Application.dataPath + "/..").Replace("\\", "/"); + } + return s_basePath; + } + } + + static string AssetFullPath + { + get + { + return BaseFullPath + "/Assets"; + } + } + + public string FullPath + { + get + { + if (IsNull) + { + throw new NotImplementedException(); + } + return Path.Combine(BaseFullPath, Value).Replace("\\", "/"); + } + } + + public bool IsFileExists + { + get { return File.Exists(FullPath); } + } + + public bool IsDirectoryExists + { + get { return Directory.Exists(FullPath); } + } + + /// + /// + /// + /// C:/path/to/file + /// + public static UnityPath FromFullpath(string fullPath) + { + if(fullPath == null) + { + fullPath = ""; + } + fullPath = fullPath.Replace("\\", "/"); + + if (fullPath == BaseFullPath) { + return new UnityPath + { + Value="" + }; + } + else if(fullPath.StartsWith(BaseFullPath + "/")) + { + return new UnityPath(fullPath.Substring(BaseFullPath.Length + 1)); + } + else + { + return default(UnityPath); + } + } + + public static bool IsUnderAssetFolder(string fullPath) + { + return fullPath.Replace("\\", "/").StartsWith(AssetFullPath); + } + #endregion + + public IEnumerable TravserseDir() + { + if (IsDirectoryExists) + { + yield return this; + + foreach(var child in ChildDirs) + { + foreach(var x in child.TravserseDir()) + { + yield return x; + } + } + } + } + + public IEnumerable ChildDirs + { + get + { + foreach(var x in Directory.GetDirectories(FullPath)) + { + yield return UnityPath.FromFullpath(x); + } + } + } + + public IEnumerable ChildFiles + { + get + { + foreach (var x in Directory.GetFiles(FullPath)) + { + yield return UnityPath.FromFullpath(x); + } + } + } + +#if UNITY_EDITOR + public T GetImporter() where T : AssetImporter + { + return AssetImporter.GetAtPath(Value) as T; + } + + public static UnityPath FromAsset(UnityEngine.Object asset) + { + return new UnityPath(AssetDatabase.GetAssetPath(asset)); + } + + public void ImportAsset() + { + if (!IsUnderAssetsFolder) + { + throw new NotImplementedException(); + } + AssetDatabase.ImportAsset(Value); + } + + public void EnsureFolder() + { + if (IsNull) + { + throw new NotImplementedException(); + } + + if (HasParent) + { + Parent.EnsureFolder(); + } + + if (!IsDirectoryExists) + { + var parent = Parent; + // ensure parent + parent.ImportAsset(); + // create + AssetDatabase.CreateFolder( + parent.Value, + Path.GetFileName(Value) + ); + ImportAsset(); + } + } + + public UnityEngine.Object[] GetSubAssets() + { + if (!IsUnderAssetsFolder) + { + throw new NotImplementedException(); + } + + return AssetDatabase.LoadAllAssetsAtPath(Value); + } + + public void CreateAsset(UnityEngine.Object o) + { + if (!IsUnderAssetsFolder) + { + throw new NotImplementedException(); + } + + AssetDatabase.CreateAsset(o, Value); + } + + public void AddObjectToAsset(UnityEngine.Object o) + { + if (!IsUnderAssetsFolder) + { + throw new NotImplementedException(); + } + + AssetDatabase.AddObjectToAsset(o, Value); + } + + public T LoadAsset() where T : UnityEngine.Object + { + if (!IsUnderAssetsFolder) + { + throw new NotImplementedException(); + } + + return AssetDatabase.LoadAssetAtPath(Value); + } + + public UnityPath GenerateUniqueAssetPath() + { + if (!IsUnderAssetsFolder) + { + throw new NotImplementedException(); + } + + return new UnityPath(AssetDatabase.GenerateUniqueAssetPath(Value)); + } + #endif + } +} diff --git a/UniGLTF/Core/Scripts/IO/UnityPath.cs.meta b/UniGLTF/Scripts/IO/UnityPath.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/UnityPath.cs.meta rename to UniGLTF/Scripts/IO/UnityPath.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/ZipArchiveStorage.cs b/UniGLTF/Scripts/IO/ZipArchiveStorage.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/ZipArchiveStorage.cs rename to UniGLTF/Scripts/IO/ZipArchiveStorage.cs index 317f745bd..ea05e92b8 100644 --- a/UniGLTF/Core/Scripts/IO/ZipArchiveStorage.cs +++ b/UniGLTF/Scripts/IO/ZipArchiveStorage.cs @@ -1,385 +1,385 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Linq; -using System.IO.Compression; -using System.Runtime.InteropServices; - -/// -/// https://en.wikipedia.org/wiki/Zip_(file_format) -/// -namespace UniGLTF.Zip -{ - - enum CompressionMethod : ushort - { - Stored = 0, // The file is stored (no compression) - Shrink = 1, // The file is Shrunk - Reduced1 = 2, // The file is Reduced with compression factor 1 - Reduced2 = 3, // The file is Reduced with compression factor 2 - Reduced3 = 4, // The file is Reduced with compression factor 3 - Reduced4 = 5, // The file is Reduced with compression factor 4 - Imploded = 6, // The file is Imploded - Reserved = 7, // Reserved for Tokenizing compression algorithm - Deflated = 8, // The file is Deflated - } - - class ZipParseException : Exception - { - public ZipParseException(string msg) : base(msg) - { } - } - - class EOCD - { - public ushort NumberOfThisDisk; - public ushort DiskWhereCentralDirectoryStarts; - public ushort NumberOfCentralDirectoryRecordsOnThisDisk; - public ushort TotalNumberOfCentralDirectoryRecords; - public int SizeOfCentralDirectoryBytes; - public int OffsetOfStartOfCentralDirectory; - public string Comment; - - public override string ToString() - { - return string.Format("", - NumberOfCentralDirectoryRecordsOnThisDisk, - OffsetOfStartOfCentralDirectory, - Comment - ); - } - - static int FindEOCD(byte[] bytes) - { - for (int i = bytes.Length - 22; i >= 0; --i) - { - if (bytes[i] == 0x50 - && bytes[i + 1] == 0x4b - && bytes[i + 2] == 0x05 - && bytes[i + 3] == 0x06) - { - return i; - } - } - - throw new ZipParseException("EOCD is not found"); - } - - public static EOCD Parse(Byte[] bytes) - { - var pos = FindEOCD(bytes); - using (var ms = new MemoryStream(bytes, pos, bytes.Length - pos, false)) - using (var r = new BinaryReader(ms)) - { - var sig = r.ReadInt32(); - if (sig != 0x06054b50) throw new ZipParseException("invalid eocd signature: " + sig); - - var eocd = new EOCD - { - NumberOfThisDisk = r.ReadUInt16(), - DiskWhereCentralDirectoryStarts = r.ReadUInt16(), - NumberOfCentralDirectoryRecordsOnThisDisk = r.ReadUInt16(), - TotalNumberOfCentralDirectoryRecords = r.ReadUInt16(), - SizeOfCentralDirectoryBytes = r.ReadInt32(), - OffsetOfStartOfCentralDirectory = r.ReadInt32(), - }; - - var commentLength = r.ReadUInt16(); - var commentBytes = r.ReadBytes(commentLength); - eocd.Comment = Encoding.ASCII.GetString(commentBytes); - - return eocd; - } - } - } - - abstract class CommonHeader - { - public Encoding Encoding = Encoding.UTF8; - public Byte[] Bytes; - public int Offset; - public abstract int Signature - { - get; - } - protected CommonHeader(Byte[] bytes, int offset) - { - var sig = BitConverter.ToInt32(bytes, offset); - if (sig != Signature) - { - throw new ZipParseException("invalid central directory file signature: " + sig); - } - Bytes = bytes; - Offset = offset; - - var start = offset + 4; - using (var ms = new MemoryStream(bytes, start, bytes.Length - start, false)) - using (var r = new BinaryReader(ms)) - { - ReadBefore(r); - Read(r); - ReadAfter(r); - } - } - - public UInt16 VersionNeededToExtract; - public UInt16 GeneralPurposeBitFlag; - public CompressionMethod CompressionMethod; - public UInt16 FileLastModificationTime; - public UInt16 FileLastModificationDate; - public Int32 CRC32; - public Int32 CompressedSize; - public Int32 UncompressedSize; - public UInt16 FileNameLength; - public UInt16 ExtraFieldLength; - - public abstract int FixedFieldLength - { - get; - } - - public abstract int Length - { - get; - } - - public string FileName - { - get - { - return Encoding.GetString(Bytes, - Offset + FixedFieldLength, - FileNameLength); - } - } - - public ArraySegment ExtraField - { - get - { - return new ArraySegment(Bytes, - Offset + FixedFieldLength + FileNameLength, - ExtraFieldLength); - } - } - - public override string ToString() - { - return string.Format("", - FileName, - CompressedSize, - UncompressedSize, - CompressionMethod - ); - } - - public abstract void ReadBefore(BinaryReader r); - - public void Read(BinaryReader r) - { - VersionNeededToExtract = r.ReadUInt16(); - GeneralPurposeBitFlag = r.ReadUInt16(); - CompressionMethod = (CompressionMethod)r.ReadUInt16(); - FileLastModificationTime = r.ReadUInt16(); - FileLastModificationDate = r.ReadUInt16(); - CRC32 = r.ReadInt32(); - CompressedSize = r.ReadInt32(); - UncompressedSize = r.ReadInt32(); - FileNameLength = r.ReadUInt16(); - ExtraFieldLength = r.ReadUInt16(); - } - - public abstract void ReadAfter(BinaryReader r); - } - - class CentralDirectoryFileHeader : CommonHeader - { - public override int Signature - { - get - { - return 0x02014b50; - } - } - - public CentralDirectoryFileHeader(Byte[] bytes, int offset) : base(bytes, offset) { } - - public UInt16 VersionMadeBy; - public UInt16 FileCommentLength; - public UInt16 DiskNumberWhereFileStarts; - public UInt16 InternalFileAttributes; - public Int32 ExternalFileAttributes; - public Int32 RelativeOffsetOfLocalFileHeader; - - public override int FixedFieldLength - { - get - { - return 46; - } - } - - public string FileComment - { - get - { - return Encoding.GetString(Bytes, - Offset + 46 + FileNameLength + ExtraFieldLength, - FileCommentLength); - } - } - - public override int Length - { - get - { - return FixedFieldLength + FileNameLength + ExtraFieldLength + FileCommentLength; - } - } - - public override void ReadBefore(BinaryReader r) - { - VersionMadeBy = r.ReadUInt16(); - } - - public override void ReadAfter(BinaryReader r) - { - FileCommentLength = r.ReadUInt16(); - DiskNumberWhereFileStarts = r.ReadUInt16(); - InternalFileAttributes = r.ReadUInt16(); - ExternalFileAttributes = r.ReadInt32(); - RelativeOffsetOfLocalFileHeader = r.ReadInt32(); - } - } - - class LocalFileHeader : CommonHeader - { - public override int FixedFieldLength - { - get - { - return 30; - } - } - - public override int Signature - { - get - { - return 0x04034b50; - } - } - - public override int Length - { - get - { - return FixedFieldLength + FileNameLength + ExtraFieldLength; - } - } - - public LocalFileHeader(Byte[] bytes, int offset) : base(bytes, offset) - { - } - - public override void ReadBefore(BinaryReader r) - { - } - - public override void ReadAfter(BinaryReader r) - { - } - } - - class ZipArchiveStorage : IStorage - { - public override string ToString() - { - return string.Format("", String.Join("", Entries.Select(x => x.ToString() + "\n").ToArray())); - } - - public List Entries = new List(); - - public static ZipArchiveStorage Parse(byte[] bytes) - { - var eocd = EOCD.Parse(bytes); - var archive = new ZipArchiveStorage(); - - var pos = eocd.OffsetOfStartOfCentralDirectory; - for (int i = 0; i < eocd.NumberOfCentralDirectoryRecordsOnThisDisk; ++i) - { - var file = new CentralDirectoryFileHeader(bytes, pos); - archive.Entries.Add(file); - pos += file.Length; - } - - return archive; - } - - public Byte[] Extract(CentralDirectoryFileHeader header) - { - var local = new LocalFileHeader(header.Bytes, header.RelativeOffsetOfLocalFileHeader); - var pos = local.Offset + local.Length; - - var dst = new Byte[local.UncompressedSize]; - -#if true - using (var s = new MemoryStream(header.Bytes, pos, local.CompressedSize, false)) - using (var deflateStream = new DeflateStream(s, CompressionMode.Decompress)) - { - int dst_pos = 0; - for (int remain = dst.Length; remain > 0;) - { - var readSize = deflateStream.Read(dst, dst_pos, remain); - dst_pos += readSize; - remain -= readSize; - } - } -#else - var size=RawInflate.RawInflateImport.RawInflate(dst, 0, dst.Length, - header.Bytes, pos, header.CompressedSize); -#endif - - return dst; - } - - public string ExtractToString(CentralDirectoryFileHeader header, Encoding encoding) - { - var local = new LocalFileHeader(header.Bytes, header.RelativeOffsetOfLocalFileHeader); - var pos = local.Offset + local.Length; - - using (var s = new MemoryStream(header.Bytes, pos, local.CompressedSize, false)) - using (var deflateStream = new DeflateStream(s, CompressionMode.Decompress)) - using (var r = new StreamReader(deflateStream, encoding)) - { - return r.ReadToEnd(); - } - } - - public ArraySegment Get(string url) - { - var found = Entries.FirstOrDefault(x => x.FileName == url); - if (found == null) - { - throw new FileNotFoundException("[ZipArchive]" + url); - } - - switch (found.CompressionMethod) - { - case CompressionMethod.Deflated: - return new ArraySegment(Extract(found)); - - case CompressionMethod.Stored: - return new ArraySegment(found.Bytes, found.RelativeOffsetOfLocalFileHeader, found.CompressedSize); - } - - throw new NotImplementedException(found.CompressionMethod.ToString()); - } - - public string GetPath(string url) - { - return null; - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.IO.Compression; +using System.Runtime.InteropServices; + +/// +/// https://en.wikipedia.org/wiki/Zip_(file_format) +/// +namespace UniGLTF.Zip +{ + + enum CompressionMethod : ushort + { + Stored = 0, // The file is stored (no compression) + Shrink = 1, // The file is Shrunk + Reduced1 = 2, // The file is Reduced with compression factor 1 + Reduced2 = 3, // The file is Reduced with compression factor 2 + Reduced3 = 4, // The file is Reduced with compression factor 3 + Reduced4 = 5, // The file is Reduced with compression factor 4 + Imploded = 6, // The file is Imploded + Reserved = 7, // Reserved for Tokenizing compression algorithm + Deflated = 8, // The file is Deflated + } + + class ZipParseException : Exception + { + public ZipParseException(string msg) : base(msg) + { } + } + + class EOCD + { + public ushort NumberOfThisDisk; + public ushort DiskWhereCentralDirectoryStarts; + public ushort NumberOfCentralDirectoryRecordsOnThisDisk; + public ushort TotalNumberOfCentralDirectoryRecords; + public int SizeOfCentralDirectoryBytes; + public int OffsetOfStartOfCentralDirectory; + public string Comment; + + public override string ToString() + { + return string.Format("", + NumberOfCentralDirectoryRecordsOnThisDisk, + OffsetOfStartOfCentralDirectory, + Comment + ); + } + + static int FindEOCD(byte[] bytes) + { + for (int i = bytes.Length - 22; i >= 0; --i) + { + if (bytes[i] == 0x50 + && bytes[i + 1] == 0x4b + && bytes[i + 2] == 0x05 + && bytes[i + 3] == 0x06) + { + return i; + } + } + + throw new ZipParseException("EOCD is not found"); + } + + public static EOCD Parse(Byte[] bytes) + { + var pos = FindEOCD(bytes); + using (var ms = new MemoryStream(bytes, pos, bytes.Length - pos, false)) + using (var r = new BinaryReader(ms)) + { + var sig = r.ReadInt32(); + if (sig != 0x06054b50) throw new ZipParseException("invalid eocd signature: " + sig); + + var eocd = new EOCD + { + NumberOfThisDisk = r.ReadUInt16(), + DiskWhereCentralDirectoryStarts = r.ReadUInt16(), + NumberOfCentralDirectoryRecordsOnThisDisk = r.ReadUInt16(), + TotalNumberOfCentralDirectoryRecords = r.ReadUInt16(), + SizeOfCentralDirectoryBytes = r.ReadInt32(), + OffsetOfStartOfCentralDirectory = r.ReadInt32(), + }; + + var commentLength = r.ReadUInt16(); + var commentBytes = r.ReadBytes(commentLength); + eocd.Comment = Encoding.ASCII.GetString(commentBytes); + + return eocd; + } + } + } + + abstract class CommonHeader + { + public Encoding Encoding = Encoding.UTF8; + public Byte[] Bytes; + public int Offset; + public abstract int Signature + { + get; + } + protected CommonHeader(Byte[] bytes, int offset) + { + var sig = BitConverter.ToInt32(bytes, offset); + if (sig != Signature) + { + throw new ZipParseException("invalid central directory file signature: " + sig); + } + Bytes = bytes; + Offset = offset; + + var start = offset + 4; + using (var ms = new MemoryStream(bytes, start, bytes.Length - start, false)) + using (var r = new BinaryReader(ms)) + { + ReadBefore(r); + Read(r); + ReadAfter(r); + } + } + + public UInt16 VersionNeededToExtract; + public UInt16 GeneralPurposeBitFlag; + public CompressionMethod CompressionMethod; + public UInt16 FileLastModificationTime; + public UInt16 FileLastModificationDate; + public Int32 CRC32; + public Int32 CompressedSize; + public Int32 UncompressedSize; + public UInt16 FileNameLength; + public UInt16 ExtraFieldLength; + + public abstract int FixedFieldLength + { + get; + } + + public abstract int Length + { + get; + } + + public string FileName + { + get + { + return Encoding.GetString(Bytes, + Offset + FixedFieldLength, + FileNameLength); + } + } + + public ArraySegment ExtraField + { + get + { + return new ArraySegment(Bytes, + Offset + FixedFieldLength + FileNameLength, + ExtraFieldLength); + } + } + + public override string ToString() + { + return string.Format("", + FileName, + CompressedSize, + UncompressedSize, + CompressionMethod + ); + } + + public abstract void ReadBefore(BinaryReader r); + + public void Read(BinaryReader r) + { + VersionNeededToExtract = r.ReadUInt16(); + GeneralPurposeBitFlag = r.ReadUInt16(); + CompressionMethod = (CompressionMethod)r.ReadUInt16(); + FileLastModificationTime = r.ReadUInt16(); + FileLastModificationDate = r.ReadUInt16(); + CRC32 = r.ReadInt32(); + CompressedSize = r.ReadInt32(); + UncompressedSize = r.ReadInt32(); + FileNameLength = r.ReadUInt16(); + ExtraFieldLength = r.ReadUInt16(); + } + + public abstract void ReadAfter(BinaryReader r); + } + + class CentralDirectoryFileHeader : CommonHeader + { + public override int Signature + { + get + { + return 0x02014b50; + } + } + + public CentralDirectoryFileHeader(Byte[] bytes, int offset) : base(bytes, offset) { } + + public UInt16 VersionMadeBy; + public UInt16 FileCommentLength; + public UInt16 DiskNumberWhereFileStarts; + public UInt16 InternalFileAttributes; + public Int32 ExternalFileAttributes; + public Int32 RelativeOffsetOfLocalFileHeader; + + public override int FixedFieldLength + { + get + { + return 46; + } + } + + public string FileComment + { + get + { + return Encoding.GetString(Bytes, + Offset + 46 + FileNameLength + ExtraFieldLength, + FileCommentLength); + } + } + + public override int Length + { + get + { + return FixedFieldLength + FileNameLength + ExtraFieldLength + FileCommentLength; + } + } + + public override void ReadBefore(BinaryReader r) + { + VersionMadeBy = r.ReadUInt16(); + } + + public override void ReadAfter(BinaryReader r) + { + FileCommentLength = r.ReadUInt16(); + DiskNumberWhereFileStarts = r.ReadUInt16(); + InternalFileAttributes = r.ReadUInt16(); + ExternalFileAttributes = r.ReadInt32(); + RelativeOffsetOfLocalFileHeader = r.ReadInt32(); + } + } + + class LocalFileHeader : CommonHeader + { + public override int FixedFieldLength + { + get + { + return 30; + } + } + + public override int Signature + { + get + { + return 0x04034b50; + } + } + + public override int Length + { + get + { + return FixedFieldLength + FileNameLength + ExtraFieldLength; + } + } + + public LocalFileHeader(Byte[] bytes, int offset) : base(bytes, offset) + { + } + + public override void ReadBefore(BinaryReader r) + { + } + + public override void ReadAfter(BinaryReader r) + { + } + } + + class ZipArchiveStorage : IStorage + { + public override string ToString() + { + return string.Format("", String.Join("", Entries.Select(x => x.ToString() + "\n").ToArray())); + } + + public List Entries = new List(); + + public static ZipArchiveStorage Parse(byte[] bytes) + { + var eocd = EOCD.Parse(bytes); + var archive = new ZipArchiveStorage(); + + var pos = eocd.OffsetOfStartOfCentralDirectory; + for (int i = 0; i < eocd.NumberOfCentralDirectoryRecordsOnThisDisk; ++i) + { + var file = new CentralDirectoryFileHeader(bytes, pos); + archive.Entries.Add(file); + pos += file.Length; + } + + return archive; + } + + public Byte[] Extract(CentralDirectoryFileHeader header) + { + var local = new LocalFileHeader(header.Bytes, header.RelativeOffsetOfLocalFileHeader); + var pos = local.Offset + local.Length; + + var dst = new Byte[local.UncompressedSize]; + +#if true + using (var s = new MemoryStream(header.Bytes, pos, local.CompressedSize, false)) + using (var deflateStream = new DeflateStream(s, CompressionMode.Decompress)) + { + int dst_pos = 0; + for (int remain = dst.Length; remain > 0;) + { + var readSize = deflateStream.Read(dst, dst_pos, remain); + dst_pos += readSize; + remain -= readSize; + } + } +#else + var size=RawInflate.RawInflateImport.RawInflate(dst, 0, dst.Length, + header.Bytes, pos, header.CompressedSize); +#endif + + return dst; + } + + public string ExtractToString(CentralDirectoryFileHeader header, Encoding encoding) + { + var local = new LocalFileHeader(header.Bytes, header.RelativeOffsetOfLocalFileHeader); + var pos = local.Offset + local.Length; + + using (var s = new MemoryStream(header.Bytes, pos, local.CompressedSize, false)) + using (var deflateStream = new DeflateStream(s, CompressionMode.Decompress)) + using (var r = new StreamReader(deflateStream, encoding)) + { + return r.ReadToEnd(); + } + } + + public ArraySegment Get(string url) + { + var found = Entries.FirstOrDefault(x => x.FileName == url); + if (found == null) + { + throw new FileNotFoundException("[ZipArchive]" + url); + } + + switch (found.CompressionMethod) + { + case CompressionMethod.Deflated: + return new ArraySegment(Extract(found)); + + case CompressionMethod.Stored: + return new ArraySegment(found.Bytes, found.RelativeOffsetOfLocalFileHeader, found.CompressedSize); + } + + throw new NotImplementedException(found.CompressionMethod.ToString()); + } + + public string GetPath(string url) + { + return null; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/ZipArchiveStorage.cs.meta b/UniGLTF/Scripts/IO/ZipArchiveStorage.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/ZipArchiveStorage.cs.meta rename to UniGLTF/Scripts/IO/ZipArchiveStorage.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/glbImporter.cs b/UniGLTF/Scripts/IO/glbImporter.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/glbImporter.cs rename to UniGLTF/Scripts/IO/glbImporter.cs index 68acce1bf..2eef5e1db 100644 --- a/UniGLTF/Core/Scripts/IO/glbImporter.cs +++ b/UniGLTF/Scripts/IO/glbImporter.cs @@ -1,79 +1,79 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using UnityEngine; - - -namespace UniGLTF -{ - public static class glbImporter - { - public const string GLB_MAGIC = "glTF"; - public const float GLB_VERSION = 2.0f; - - public static GlbChunkType ToChunkType(string src) - { - switch(src) - { - case "BIN": - return GlbChunkType.BIN; - - case "JSON": - return GlbChunkType.JSON; - - default: - throw new FormatException("unknown chunk type: " + src); - } - } - - public static List ParseGlbChanks(Byte[] bytes) - { - if (bytes.Length == 0) - { - throw new Exception("empty bytes"); - } - - int pos = 0; - if (Encoding.ASCII.GetString(bytes, 0, 4) != GLB_MAGIC) - { - throw new Exception("invalid magic"); - } - pos += 4; - - var version = BitConverter.ToUInt32(bytes, pos); - if (version != GLB_VERSION) - { - Debug.LogWarningFormat("unknown version: {0}", version); - return null; - } - pos += 4; - - //var totalLength = BitConverter.ToUInt32(bytes, pos); - pos += 4; - - var chunks = new List(); - while (pos < bytes.Length) - { - var chunkDataSize = BitConverter.ToInt32(bytes, pos); - pos += 4; - - //var type = (GlbChunkType)BitConverter.ToUInt32(bytes, pos); - var chunkTypeBytes = bytes.Skip(pos).Take(4).Where(x => x != 0).ToArray(); - var chunkTypeStr = Encoding.ASCII.GetString(chunkTypeBytes); - var type = ToChunkType(chunkTypeStr); - pos += 4; - - chunks.Add(new GlbChunk - { - ChunkType = type, - Bytes = new ArraySegment(bytes, (int)pos, (int)chunkDataSize) - }); - - pos += chunkDataSize; - } - - return chunks; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + + +namespace UniGLTF +{ + public static class glbImporter + { + public const string GLB_MAGIC = "glTF"; + public const float GLB_VERSION = 2.0f; + + public static GlbChunkType ToChunkType(string src) + { + switch(src) + { + case "BIN": + return GlbChunkType.BIN; + + case "JSON": + return GlbChunkType.JSON; + + default: + throw new FormatException("unknown chunk type: " + src); + } + } + + public static List ParseGlbChanks(Byte[] bytes) + { + if (bytes.Length == 0) + { + throw new Exception("empty bytes"); + } + + int pos = 0; + if (Encoding.ASCII.GetString(bytes, 0, 4) != GLB_MAGIC) + { + throw new Exception("invalid magic"); + } + pos += 4; + + var version = BitConverter.ToUInt32(bytes, pos); + if (version != GLB_VERSION) + { + Debug.LogWarningFormat("unknown version: {0}", version); + return null; + } + pos += 4; + + //var totalLength = BitConverter.ToUInt32(bytes, pos); + pos += 4; + + var chunks = new List(); + while (pos < bytes.Length) + { + var chunkDataSize = BitConverter.ToInt32(bytes, pos); + pos += 4; + + //var type = (GlbChunkType)BitConverter.ToUInt32(bytes, pos); + var chunkTypeBytes = bytes.Skip(pos).Take(4).Where(x => x != 0).ToArray(); + var chunkTypeStr = Encoding.ASCII.GetString(chunkTypeBytes); + var type = ToChunkType(chunkTypeStr); + pos += 4; + + chunks.Add(new GlbChunk + { + ChunkType = type, + Bytes = new ArraySegment(bytes, (int)pos, (int)chunkDataSize) + }); + + pos += chunkDataSize; + } + + return chunks; + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/glbImporter.cs.meta b/UniGLTF/Scripts/IO/glbImporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/glbImporter.cs.meta rename to UniGLTF/Scripts/IO/glbImporter.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/gltfExporter.cs b/UniGLTF/Scripts/IO/gltfExporter.cs similarity index 97% rename from UniGLTF/Core/Scripts/IO/gltfExporter.cs rename to UniGLTF/Scripts/IO/gltfExporter.cs index ec1a28474..32298b858 100644 --- a/UniGLTF/Core/Scripts/IO/gltfExporter.cs +++ b/UniGLTF/Scripts/IO/gltfExporter.cs @@ -1,365 +1,365 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif - - -namespace UniGLTF -{ - public class gltfExporter : IDisposable - { - const string CONVERT_HUMANOID_KEY = UniGLTFVersion.UNIGLTF_VERSION + "/Export"; - -#if UNITY_EDITOR - [MenuItem(CONVERT_HUMANOID_KEY, true, 1)] - private static bool ExportValidate() - { - return Selection.activeObject != null && Selection.activeObject is GameObject; - } - - [MenuItem(CONVERT_HUMANOID_KEY, false, 1)] - private static void ExportFromMenu() - { - var go = Selection.activeObject as GameObject; - var path = EditorUtility.SaveFilePanel( - "Save glb", - "", - go.name + ".glb", - "glb"); - if (string.IsNullOrEmpty(path)) - { - return; - } - - var gltf = new glTF(); - using (var exporter = new gltfExporter(gltf)) - { - exporter.Prepare(go); - exporter.Export(); - } - var bytes = gltf.ToGlbBytes(); - File.WriteAllBytes(path, bytes); - - if (path.StartsWithUnityAssetPath()) - { - AssetDatabase.ImportAsset(path.ToUnityRelativePath()); - AssetDatabase.Refresh(); - } - } -#endif - - glTF glTF; - - public bool UseSparseAccessorForBlendShape - { - get; - set; - } - - public GameObject Copy - { - get; - protected set; - } - - public List Meshes - { - get; - private set; - } - - public List Nodes - { - get; - private set; - } - - public List Materials - { - get; - private set; - } - - public TextureExportManager TextureManager; - - protected virtual IMaterialExporter CreateMaterialExporter() - { - return new MaterialExporter(); - } - - /// - /// このエクスポーターがサポートするExtension - /// - protected virtual IEnumerable ExtensionUsed - { - get - { - yield return glTF_KHR_materials_unlit.ExtensionName; - } - } - - public gltfExporter(glTF gltf) - { - glTF = gltf; - - glTF.extensionsUsed.AddRange(ExtensionUsed); - - glTF.asset = new glTFAssets - { - generator = "UniGLTF-" + UniGLTFVersion.VERSION, - version = "2.0", - }; - } - - public static glTF Export(GameObject go) - { - var gltf = new glTF(); - using (var exporter = new gltfExporter(gltf)) - { - exporter.Prepare(go); - exporter.Export(); - } - return gltf; - } - - public virtual void Prepare(GameObject go) - { - // コピーを作って、Z軸を反転することで左手系を右手系に変換する - Copy = GameObject.Instantiate(go); - Copy.transform.ReverseZRecursive(); - } - - public void Export() - { - FromGameObject(glTF, Copy, UseSparseAccessorForBlendShape); - } - - public void Dispose() - { - if (Application.isEditor) - { - GameObject.DestroyImmediate(Copy); - } - else - { - GameObject.Destroy(Copy); - } - } - - #region Export - static glTFNode ExportNode(Transform x, List nodes, List meshes, List skins) - { - var node = new glTFNode - { - name = x.name, - children = x.transform.GetChildren().Select(y => nodes.IndexOf(y)).ToArray(), - rotation = x.transform.localRotation.ToArray(), - translation = x.transform.localPosition.ToArray(), - scale = x.transform.localScale.ToArray(), - }; - - if (x.gameObject.activeInHierarchy) - { - var meshFilter = x.GetComponent(); - if (meshFilter != null) - { - node.mesh = meshes.IndexOf(meshFilter.sharedMesh); - } - - var skinnredMeshRenderer = x.GetComponent(); - if (skinnredMeshRenderer != null) - { - node.mesh = meshes.IndexOf(skinnredMeshRenderer.sharedMesh); - node.skin = skins.IndexOf(skinnredMeshRenderer); - } - } - - return node; - } - - void FromGameObject(glTF gltf, GameObject go, bool useSparseAccessorForMorphTarget = false) - { - var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]); - var bufferIndex = gltf.AddBuffer(bytesBuffer); - - GameObject tmpParent = null; - if (go.transform.childCount == 0) - { - tmpParent = new GameObject("tmpParent"); - go.transform.SetParent(tmpParent.transform, true); - go = tmpParent; - } - - try - { - - Nodes = go.transform.Traverse() - .Skip(1) // exclude root object for the symmetry with the importer - .ToList(); - - #region Materials and Textures - Materials = Nodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList(); - var unityTextures = Materials.SelectMany(x => TextureIO.GetTextures(x)).Where(x => x.Texture != null).Distinct().ToList(); - - TextureManager = new TextureExportManager(unityTextures.Select(x => x.Texture)); - - var materialExporter = CreateMaterialExporter(); - gltf.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList(); - - for (int i = 0; i < unityTextures.Count; ++i) - { - var unityTexture = unityTextures[i]; - TextureIO.ExportTexture(gltf, bufferIndex, TextureManager.GetExportTexture(i), unityTexture.TextureType); - } - #endregion - - - #region Meshes - var unityMeshes = Nodes - .Select(x => new MeshWithRenderer - { - Mesh = x.GetSharedMesh(), - Rendererer = x.GetComponent(), - }) - .Where(x => - { - if (x.Mesh == null) - { - return false; - } - if (x.Rendererer.sharedMaterials == null - || x.Rendererer.sharedMaterials.Length == 0) - { - return false; - } - - return true; - }) - .ToList(); - MeshExporter.ExportMeshes(gltf, bufferIndex, unityMeshes, Materials, useSparseAccessorForMorphTarget); - Meshes = unityMeshes.Select(x => x.Mesh).ToList(); - #endregion - - #region Skins - var unitySkins = Nodes - .Select(x => x.GetComponent()).Where(x => - x != null - && x.bones != null - && x.bones.Length > 0) - .ToList(); - gltf.nodes = Nodes.Select(x => ExportNode(x, Nodes, unityMeshes.Select(y => y.Mesh).ToList(), unitySkins)).ToList(); - gltf.scenes = new List - { - new gltfScene - { - nodes = go.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(), - } - }; - - foreach (var x in unitySkins) - { - var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray(); - var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE); - - var skin = new glTFSkin - { - inverseBindMatrices = accessor, - joints = x.bones.Select(y => Nodes.IndexOf(y)).ToArray(), - skeleton = Nodes.IndexOf(x.rootBone), - }; - var skinIndex = gltf.skins.Count; - gltf.skins.Add(skin); - - foreach (var z in Nodes.Where(y => y.Has(x))) - { - var nodeIndex = Nodes.IndexOf(z); - var node = gltf.nodes[nodeIndex]; - node.skin = skinIndex; - } - } - #endregion - -#if UNITY_EDITOR - #region Animations - - var clips = new List(); - var animator = go.GetComponent(); - var animation = go.GetComponent(); - if (animator != null) - { - clips = AnimationExporter.GetAnimationClips(animator); - } - else if (animation != null) - { - clips = AnimationExporter.GetAnimationClips(animation); - } - - if (clips.Any()) - { - foreach (AnimationClip clip in clips) - { - var animationWithCurve = AnimationExporter.Export(clip, go.transform, Nodes); - - foreach (var kv in animationWithCurve.SamplerMap) - { - var sampler = animationWithCurve.Animation.samplers[kv.Key]; - - var inputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input); - sampler.input = inputAccessorIndex; - - var outputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Output); - sampler.output = outputAccessorIndex; - - // modify accessors - var outputAccessor = gltf.accessors[outputAccessorIndex]; - var channel = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key); - switch (glTFAnimationTarget.GetElementCount(channel.target.path)) - { - case 1: - outputAccessor.type = "SCALAR"; - //outputAccessor.count = ; - break; - case 3: - outputAccessor.type = "VEC3"; - outputAccessor.count /= 3; - break; - - case 4: - outputAccessor.type = "VEC4"; - outputAccessor.count /= 4; - break; - - default: - throw new NotImplementedException(); - } - } - animationWithCurve.Animation.name = clip.name; - gltf.animations.Add(animationWithCurve.Animation); - } - } - #endregion -#endif - } - finally - { - if (tmpParent != null) - { - tmpParent.transform.GetChild(0).SetParent(null); - if (Application.isPlaying) - { - GameObject.Destroy(tmpParent); - } - else - { - GameObject.DestroyImmediate(tmpParent); - } - } - } - } - #endregion - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + + +namespace UniGLTF +{ + public class gltfExporter : IDisposable + { + const string CONVERT_HUMANOID_KEY = UniGLTFVersion.UNIGLTF_VERSION + "/Export"; + +#if UNITY_EDITOR + [MenuItem(CONVERT_HUMANOID_KEY, true, 1)] + private static bool ExportValidate() + { + return Selection.activeObject != null && Selection.activeObject is GameObject; + } + + [MenuItem(CONVERT_HUMANOID_KEY, false, 1)] + private static void ExportFromMenu() + { + var go = Selection.activeObject as GameObject; + var path = EditorUtility.SaveFilePanel( + "Save glb", + "", + go.name + ".glb", + "glb"); + if (string.IsNullOrEmpty(path)) + { + return; + } + + var gltf = new glTF(); + using (var exporter = new gltfExporter(gltf)) + { + exporter.Prepare(go); + exporter.Export(); + } + var bytes = gltf.ToGlbBytes(); + File.WriteAllBytes(path, bytes); + + if (path.StartsWithUnityAssetPath()) + { + AssetDatabase.ImportAsset(path.ToUnityRelativePath()); + AssetDatabase.Refresh(); + } + } +#endif + + glTF glTF; + + public bool UseSparseAccessorForBlendShape + { + get; + set; + } + + public GameObject Copy + { + get; + protected set; + } + + public List Meshes + { + get; + private set; + } + + public List Nodes + { + get; + private set; + } + + public List Materials + { + get; + private set; + } + + public TextureExportManager TextureManager; + + protected virtual IMaterialExporter CreateMaterialExporter() + { + return new MaterialExporter(); + } + + /// + /// このエクスポーターがサポートするExtension + /// + protected virtual IEnumerable ExtensionUsed + { + get + { + yield return glTF_KHR_materials_unlit.ExtensionName; + } + } + + public gltfExporter(glTF gltf) + { + glTF = gltf; + + glTF.extensionsUsed.AddRange(ExtensionUsed); + + glTF.asset = new glTFAssets + { + generator = "UniGLTF-" + UniGLTFVersion.VERSION, + version = "2.0", + }; + } + + public static glTF Export(GameObject go) + { + var gltf = new glTF(); + using (var exporter = new gltfExporter(gltf)) + { + exporter.Prepare(go); + exporter.Export(); + } + return gltf; + } + + public virtual void Prepare(GameObject go) + { + // コピーを作って、Z軸を反転することで左手系を右手系に変換する + Copy = GameObject.Instantiate(go); + Copy.transform.ReverseZRecursive(); + } + + public void Export() + { + FromGameObject(glTF, Copy, UseSparseAccessorForBlendShape); + } + + public void Dispose() + { + if (Application.isEditor) + { + GameObject.DestroyImmediate(Copy); + } + else + { + GameObject.Destroy(Copy); + } + } + + #region Export + static glTFNode ExportNode(Transform x, List nodes, List meshes, List skins) + { + var node = new glTFNode + { + name = x.name, + children = x.transform.GetChildren().Select(y => nodes.IndexOf(y)).ToArray(), + rotation = x.transform.localRotation.ToArray(), + translation = x.transform.localPosition.ToArray(), + scale = x.transform.localScale.ToArray(), + }; + + if (x.gameObject.activeInHierarchy) + { + var meshFilter = x.GetComponent(); + if (meshFilter != null) + { + node.mesh = meshes.IndexOf(meshFilter.sharedMesh); + } + + var skinnredMeshRenderer = x.GetComponent(); + if (skinnredMeshRenderer != null) + { + node.mesh = meshes.IndexOf(skinnredMeshRenderer.sharedMesh); + node.skin = skins.IndexOf(skinnredMeshRenderer); + } + } + + return node; + } + + void FromGameObject(glTF gltf, GameObject go, bool useSparseAccessorForMorphTarget = false) + { + var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]); + var bufferIndex = gltf.AddBuffer(bytesBuffer); + + GameObject tmpParent = null; + if (go.transform.childCount == 0) + { + tmpParent = new GameObject("tmpParent"); + go.transform.SetParent(tmpParent.transform, true); + go = tmpParent; + } + + try + { + + Nodes = go.transform.Traverse() + .Skip(1) // exclude root object for the symmetry with the importer + .ToList(); + + #region Materials and Textures + Materials = Nodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList(); + var unityTextures = Materials.SelectMany(x => TextureIO.GetTextures(x)).Where(x => x.Texture != null).Distinct().ToList(); + + TextureManager = new TextureExportManager(unityTextures.Select(x => x.Texture)); + + var materialExporter = CreateMaterialExporter(); + gltf.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList(); + + for (int i = 0; i < unityTextures.Count; ++i) + { + var unityTexture = unityTextures[i]; + TextureIO.ExportTexture(gltf, bufferIndex, TextureManager.GetExportTexture(i), unityTexture.TextureType); + } + #endregion + + + #region Meshes + var unityMeshes = Nodes + .Select(x => new MeshWithRenderer + { + Mesh = x.GetSharedMesh(), + Rendererer = x.GetComponent(), + }) + .Where(x => + { + if (x.Mesh == null) + { + return false; + } + if (x.Rendererer.sharedMaterials == null + || x.Rendererer.sharedMaterials.Length == 0) + { + return false; + } + + return true; + }) + .ToList(); + MeshExporter.ExportMeshes(gltf, bufferIndex, unityMeshes, Materials, useSparseAccessorForMorphTarget); + Meshes = unityMeshes.Select(x => x.Mesh).ToList(); + #endregion + + #region Skins + var unitySkins = Nodes + .Select(x => x.GetComponent()).Where(x => + x != null + && x.bones != null + && x.bones.Length > 0) + .ToList(); + gltf.nodes = Nodes.Select(x => ExportNode(x, Nodes, unityMeshes.Select(y => y.Mesh).ToList(), unitySkins)).ToList(); + gltf.scenes = new List + { + new gltfScene + { + nodes = go.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(), + } + }; + + foreach (var x in unitySkins) + { + var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray(); + var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE); + + var skin = new glTFSkin + { + inverseBindMatrices = accessor, + joints = x.bones.Select(y => Nodes.IndexOf(y)).ToArray(), + skeleton = Nodes.IndexOf(x.rootBone), + }; + var skinIndex = gltf.skins.Count; + gltf.skins.Add(skin); + + foreach (var z in Nodes.Where(y => y.Has(x))) + { + var nodeIndex = Nodes.IndexOf(z); + var node = gltf.nodes[nodeIndex]; + node.skin = skinIndex; + } + } + #endregion + +#if UNITY_EDITOR + #region Animations + + var clips = new List(); + var animator = go.GetComponent(); + var animation = go.GetComponent(); + if (animator != null) + { + clips = AnimationExporter.GetAnimationClips(animator); + } + else if (animation != null) + { + clips = AnimationExporter.GetAnimationClips(animation); + } + + if (clips.Any()) + { + foreach (AnimationClip clip in clips) + { + var animationWithCurve = AnimationExporter.Export(clip, go.transform, Nodes); + + foreach (var kv in animationWithCurve.SamplerMap) + { + var sampler = animationWithCurve.Animation.samplers[kv.Key]; + + var inputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input); + sampler.input = inputAccessorIndex; + + var outputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Output); + sampler.output = outputAccessorIndex; + + // modify accessors + var outputAccessor = gltf.accessors[outputAccessorIndex]; + var channel = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key); + switch (glTFAnimationTarget.GetElementCount(channel.target.path)) + { + case 1: + outputAccessor.type = "SCALAR"; + //outputAccessor.count = ; + break; + case 3: + outputAccessor.type = "VEC3"; + outputAccessor.count /= 3; + break; + + case 4: + outputAccessor.type = "VEC4"; + outputAccessor.count /= 4; + break; + + default: + throw new NotImplementedException(); + } + } + animationWithCurve.Animation.name = clip.name; + gltf.animations.Add(animationWithCurve.Animation); + } + } + #endregion +#endif + } + finally + { + if (tmpParent != null) + { + tmpParent.transform.GetChild(0).SetParent(null); + if (Application.isPlaying) + { + GameObject.Destroy(tmpParent); + } + else + { + GameObject.DestroyImmediate(tmpParent); + } + } + } + } + #endregion + } +} diff --git a/UniGLTF/Core/Scripts/IO/gltfExporter.cs.meta b/UniGLTF/Scripts/IO/gltfExporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/gltfExporter.cs.meta rename to UniGLTF/Scripts/IO/gltfExporter.cs.meta diff --git a/UniGLTF/Core/Scripts/IO/gltfImporter.cs b/UniGLTF/Scripts/IO/gltfImporter.cs similarity index 96% rename from UniGLTF/Core/Scripts/IO/gltfImporter.cs rename to UniGLTF/Scripts/IO/gltfImporter.cs index 84f4d183a..2629574e0 100644 --- a/UniGLTF/Core/Scripts/IO/gltfImporter.cs +++ b/UniGLTF/Scripts/IO/gltfImporter.cs @@ -1,52 +1,52 @@ -using System; -using UnityEngine; - - -namespace UniGLTF -{ - public static class gltfImporter - { - [Obsolete("Use ImporterContext.Load(path)")] - public static ImporterContext Load(string path) - { - var context = new ImporterContext(); - context.Load(path); - context.ShowMeshes(); - context.EnableUpdateWhenOffscreen(); - return context; - } - - [Obsolete("Use ImporterContext.Parse(path, bytes)")] - public static ImporterContext Parse(string path, Byte[] bytes) - { - var context = new ImporterContext(); - context.Load(path); - context.ShowMeshes(); - context.EnableUpdateWhenOffscreen(); - return context; - } - - [Obsolete("use ImporterContext.Load()")] - public static void Load(ImporterContext context) - { - context.Load(); - context.ShowMeshes(); - context.EnableUpdateWhenOffscreen(); - } - - public static void LoadVrmAsync(string path, Byte[] bytes, Action onLoaded, Action onError = null, bool show = true) - { - var context = new ImporterContext(); - context.Parse(path, bytes); - context.LoadAsync(() => - { - if (show) - { - context.ShowMeshes(); - } - onLoaded(context.Root); - }, - onError); - } - } -} +using System; +using UnityEngine; + + +namespace UniGLTF +{ + public static class gltfImporter + { + [Obsolete("Use ImporterContext.Load(path)")] + public static ImporterContext Load(string path) + { + var context = new ImporterContext(); + context.Load(path); + context.ShowMeshes(); + context.EnableUpdateWhenOffscreen(); + return context; + } + + [Obsolete("Use ImporterContext.Parse(path, bytes)")] + public static ImporterContext Parse(string path, Byte[] bytes) + { + var context = new ImporterContext(); + context.Load(path); + context.ShowMeshes(); + context.EnableUpdateWhenOffscreen(); + return context; + } + + [Obsolete("use ImporterContext.Load()")] + public static void Load(ImporterContext context) + { + context.Load(); + context.ShowMeshes(); + context.EnableUpdateWhenOffscreen(); + } + + public static void LoadVrmAsync(string path, Byte[] bytes, Action onLoaded, Action onError = null, bool show = true) + { + var context = new ImporterContext(); + context.Parse(path, bytes); + context.LoadAsync(() => + { + if (show) + { + context.ShowMeshes(); + } + onLoaded(context.Root); + }, + onError); + } + } +} diff --git a/UniGLTF/Core/Scripts/IO/gltfImporter.cs.meta b/UniGLTF/Scripts/IO/gltfImporter.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/IO/gltfImporter.cs.meta rename to UniGLTF/Scripts/IO/gltfImporter.cs.meta diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps.meta b/UniGLTF/Scripts/PreExportShaderProps.meta similarity index 100% rename from UniGLTF/Core/Scripts/PreExportShaderProps.meta rename to UniGLTF/Scripts/PreExportShaderProps.meta diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Standard.cs b/UniGLTF/Scripts/PreExportShaderProps/Standard.cs similarity index 97% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Standard.cs rename to UniGLTF/Scripts/PreExportShaderProps/Standard.cs index bd2d5d122..aa5b342d2 100644 --- a/UniGLTF/Core/Scripts/PreExportShaderProps/Standard.cs +++ b/UniGLTF/Scripts/PreExportShaderProps/Standard.cs @@ -1,52 +1,52 @@ -using System.Collections.Generic; - - -namespace UniGLTF.ShaderPropExporter -{ - public static partial class PreShaderPropExporter - { - [PreExportShader] - static KeyValuePair Standard - { - get - { - return new KeyValuePair( - "Standard", - new ShaderProps - { - Properties = new ShaderProperty[]{ -new ShaderProperty("_Color", ShaderPropertyType.Color) -,new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) -,new ShaderProperty("_Cutoff", ShaderPropertyType.Range) -,new ShaderProperty("_Glossiness", ShaderPropertyType.Range) -,new ShaderProperty("_GlossMapScale", ShaderPropertyType.Range) -,new ShaderProperty("_SmoothnessTextureChannel", ShaderPropertyType.Float) -,new ShaderProperty("_Metallic", ShaderPropertyType.Range) -,new ShaderProperty("_MetallicGlossMap", ShaderPropertyType.TexEnv) -,new ShaderProperty("_SpecularHighlights", ShaderPropertyType.Float) -,new ShaderProperty("_GlossyReflections", ShaderPropertyType.Float) -,new ShaderProperty("_BumpScale", ShaderPropertyType.Float) -,new ShaderProperty("_BumpMap", ShaderPropertyType.TexEnv) -,new ShaderProperty("_Parallax", ShaderPropertyType.Range) -,new ShaderProperty("_ParallaxMap", ShaderPropertyType.TexEnv) -,new ShaderProperty("_OcclusionStrength", ShaderPropertyType.Range) -,new ShaderProperty("_OcclusionMap", ShaderPropertyType.TexEnv) -,new ShaderProperty("_EmissionColor", ShaderPropertyType.Color) -,new ShaderProperty("_EmissionMap", ShaderPropertyType.TexEnv) -,new ShaderProperty("_DetailMask", ShaderPropertyType.TexEnv) -,new ShaderProperty("_DetailAlbedoMap", ShaderPropertyType.TexEnv) -,new ShaderProperty("_DetailNormalMapScale", ShaderPropertyType.Float) -,new ShaderProperty("_DetailNormalMap", ShaderPropertyType.TexEnv) -,new ShaderProperty("_UVSec", ShaderPropertyType.Float) -,new ShaderProperty("_Mode", ShaderPropertyType.Float) -,new ShaderProperty("_SrcBlend", ShaderPropertyType.Float) -,new ShaderProperty("_DstBlend", ShaderPropertyType.Float) -,new ShaderProperty("_ZWrite", ShaderPropertyType.Float) - - } - } - ); - } - } - } -} +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair Standard + { + get + { + return new KeyValuePair( + "Standard", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_Color", ShaderPropertyType.Color) +,new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) +,new ShaderProperty("_Cutoff", ShaderPropertyType.Range) +,new ShaderProperty("_Glossiness", ShaderPropertyType.Range) +,new ShaderProperty("_GlossMapScale", ShaderPropertyType.Range) +,new ShaderProperty("_SmoothnessTextureChannel", ShaderPropertyType.Float) +,new ShaderProperty("_Metallic", ShaderPropertyType.Range) +,new ShaderProperty("_MetallicGlossMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_SpecularHighlights", ShaderPropertyType.Float) +,new ShaderProperty("_GlossyReflections", ShaderPropertyType.Float) +,new ShaderProperty("_BumpScale", ShaderPropertyType.Float) +,new ShaderProperty("_BumpMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_Parallax", ShaderPropertyType.Range) +,new ShaderProperty("_ParallaxMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_OcclusionStrength", ShaderPropertyType.Range) +,new ShaderProperty("_OcclusionMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_EmissionColor", ShaderPropertyType.Color) +,new ShaderProperty("_EmissionMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_DetailMask", ShaderPropertyType.TexEnv) +,new ShaderProperty("_DetailAlbedoMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_DetailNormalMapScale", ShaderPropertyType.Float) +,new ShaderProperty("_DetailNormalMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_UVSec", ShaderPropertyType.Float) +,new ShaderProperty("_Mode", ShaderPropertyType.Float) +,new ShaderProperty("_SrcBlend", ShaderPropertyType.Float) +,new ShaderProperty("_DstBlend", ShaderPropertyType.Float) +,new ShaderProperty("_ZWrite", ShaderPropertyType.Float) + + } + } + ); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Standard.cs.meta b/UniGLTF/Scripts/PreExportShaderProps/Standard.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Standard.cs.meta rename to UniGLTF/Scripts/PreExportShaderProps/Standard.cs.meta diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs b/UniGLTF/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs similarity index 97% rename from UniGLTF/Core/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs rename to UniGLTF/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs index 2e1731f57..ce4503a7b 100644 --- a/UniGLTF/Core/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs +++ b/UniGLTF/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs @@ -1,34 +1,34 @@ -using System.Collections.Generic; - - -namespace UniGLTF.ShaderPropExporter -{ - public static partial class PreShaderPropExporter - { - [PreExportShader] - static KeyValuePair UniGLTF_UniUnlit - { - get - { - return new KeyValuePair( - "UniGLTF/UniUnlit", - new ShaderProps - { - Properties = new ShaderProperty[]{ -new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) -,new ShaderProperty("_Color", ShaderPropertyType.Color) -,new ShaderProperty("_Cutoff", ShaderPropertyType.Range) -,new ShaderProperty("_BlendMode", ShaderPropertyType.Float) -,new ShaderProperty("_CullMode", ShaderPropertyType.Float) -,new ShaderProperty("_VColBlendMode", ShaderPropertyType.Float) -,new ShaderProperty("_SrcBlend", ShaderPropertyType.Float) -,new ShaderProperty("_DstBlend", ShaderPropertyType.Float) -,new ShaderProperty("_ZWrite", ShaderPropertyType.Float) - - } - } - ); - } - } - } -} +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair UniGLTF_UniUnlit + { + get + { + return new KeyValuePair( + "UniGLTF/UniUnlit", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) +,new ShaderProperty("_Color", ShaderPropertyType.Color) +,new ShaderProperty("_Cutoff", ShaderPropertyType.Range) +,new ShaderProperty("_BlendMode", ShaderPropertyType.Float) +,new ShaderProperty("_CullMode", ShaderPropertyType.Float) +,new ShaderProperty("_VColBlendMode", ShaderPropertyType.Float) +,new ShaderProperty("_SrcBlend", ShaderPropertyType.Float) +,new ShaderProperty("_DstBlend", ShaderPropertyType.Float) +,new ShaderProperty("_ZWrite", ShaderPropertyType.Float) + + } + } + ); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs.meta b/UniGLTF/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs.meta rename to UniGLTF/Scripts/PreExportShaderProps/UniGLTF_UniUnlit.cs.meta diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Color.cs b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Color.cs similarity index 96% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Color.cs rename to UniGLTF/Scripts/PreExportShaderProps/Unlit_Color.cs index 25c5fbc92..1ef6c3a02 100644 --- a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Color.cs +++ b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Color.cs @@ -1,26 +1,26 @@ -using System.Collections.Generic; - - -namespace UniGLTF.ShaderPropExporter -{ - public static partial class PreShaderPropExporter - { - [PreExportShader] - static KeyValuePair Unlit_Color - { - get - { - return new KeyValuePair( - "Unlit/Color", - new ShaderProps - { - Properties = new ShaderProperty[]{ -new ShaderProperty("_Color", ShaderPropertyType.Color) - - } - } - ); - } - } - } -} +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair Unlit_Color + { + get + { + return new KeyValuePair( + "Unlit/Color", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_Color", ShaderPropertyType.Color) + + } + } + ); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Color.cs.meta b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Color.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Color.cs.meta rename to UniGLTF/Scripts/PreExportShaderProps/Unlit_Color.cs.meta diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Texture.cs b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Texture.cs similarity index 96% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Texture.cs rename to UniGLTF/Scripts/PreExportShaderProps/Unlit_Texture.cs index f969aca80..ed6f487a3 100644 --- a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Texture.cs +++ b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Texture.cs @@ -1,26 +1,26 @@ -using System.Collections.Generic; - - -namespace UniGLTF.ShaderPropExporter -{ - public static partial class PreShaderPropExporter - { - [PreExportShader] - static KeyValuePair Unlit_Texture - { - get - { - return new KeyValuePair( - "Unlit/Texture", - new ShaderProps - { - Properties = new ShaderProperty[]{ -new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) - - } - } - ); - } - } - } -} +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair Unlit_Texture + { + get + { + return new KeyValuePair( + "Unlit/Texture", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) + + } + } + ); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Texture.cs.meta b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Texture.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Texture.cs.meta rename to UniGLTF/Scripts/PreExportShaderProps/Unlit_Texture.cs.meta diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent.cs b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent.cs similarity index 96% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent.cs rename to UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent.cs index d01e6a773..cad3b4b94 100644 --- a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent.cs +++ b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent.cs @@ -1,26 +1,26 @@ -using System.Collections.Generic; - - -namespace UniGLTF.ShaderPropExporter -{ - public static partial class PreShaderPropExporter - { - [PreExportShader] - static KeyValuePair Unlit_Transparent - { - get - { - return new KeyValuePair( - "Unlit/Transparent", - new ShaderProps - { - Properties = new ShaderProperty[]{ -new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) - - } - } - ); - } - } - } -} +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair Unlit_Transparent + { + get + { + return new KeyValuePair( + "Unlit/Transparent", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) + + } + } + ); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent.cs.meta b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent.cs.meta rename to UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent.cs.meta diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs similarity index 96% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs rename to UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs index d54b96ecb..ebe366b5b 100644 --- a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs +++ b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs @@ -1,27 +1,27 @@ -using System.Collections.Generic; - - -namespace UniGLTF.ShaderPropExporter -{ - public static partial class PreShaderPropExporter - { - [PreExportShader] - static KeyValuePair Unlit_Transparent_Cutout - { - get - { - return new KeyValuePair( - "Unlit/Transparent Cutout", - new ShaderProps - { - Properties = new ShaderProperty[]{ -new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) -,new ShaderProperty("_Cutoff", ShaderPropertyType.Range) - - } - } - ); - } - } - } -} +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair Unlit_Transparent_Cutout + { + get + { + return new KeyValuePair( + "Unlit/Transparent Cutout", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) +,new ShaderProperty("_Cutoff", ShaderPropertyType.Range) + + } + } + ); + } + } + } +} diff --git a/UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs.meta b/UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs.meta rename to UniGLTF/Scripts/PreExportShaderProps/Unlit_Transparent_Cutout.cs.meta diff --git a/UniGLTF/Core/Scripts/UniGLTFException.cs b/UniGLTF/Scripts/UniGLTFException.cs similarity index 96% rename from UniGLTF/Core/Scripts/UniGLTFException.cs rename to UniGLTF/Scripts/UniGLTFException.cs index 732152c19..fde2faaf8 100644 --- a/UniGLTF/Core/Scripts/UniGLTFException.cs +++ b/UniGLTF/Scripts/UniGLTFException.cs @@ -1,17 +1,17 @@ -using System; - - -namespace UniGLTF -{ - public class UniGLTFException : Exception - { - public UniGLTFException(string fmt, params object[] args) : this(string.Format(fmt, args)) { } - public UniGLTFException(string msg) : base(msg) { } - } - - public class UniGLTFNotSupportedException : UniGLTFException - { - public UniGLTFNotSupportedException(string fmt, params object[] args) : this(string.Format(fmt, args)) { } - public UniGLTFNotSupportedException(string msg) : base(msg) { } - } -} +using System; + + +namespace UniGLTF +{ + public class UniGLTFException : Exception + { + public UniGLTFException(string fmt, params object[] args) : this(string.Format(fmt, args)) { } + public UniGLTFException(string msg) : base(msg) { } + } + + public class UniGLTFNotSupportedException : UniGLTFException + { + public UniGLTFNotSupportedException(string fmt, params object[] args) : this(string.Format(fmt, args)) { } + public UniGLTFNotSupportedException(string msg) : base(msg) { } + } +} diff --git a/UniGLTF/Core/Scripts/UniGLTFException.cs.meta b/UniGLTF/Scripts/UniGLTFException.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/UniGLTFException.cs.meta rename to UniGLTF/Scripts/UniGLTFException.cs.meta diff --git a/UniGLTF/Core/Scripts/UniGLTFVersion.cs b/UniGLTF/Scripts/UniGLTFVersion.cs similarity index 94% rename from UniGLTF/Core/Scripts/UniGLTFVersion.cs rename to UniGLTF/Scripts/UniGLTFVersion.cs index 4ba87b3e9..6cc577069 100644 --- a/UniGLTF/Core/Scripts/UniGLTFVersion.cs +++ b/UniGLTF/Scripts/UniGLTFVersion.cs @@ -1,11 +1,11 @@ - -namespace UniGLTF -{ - public static partial class UniGLTFVersion - { - public const int MAJOR = 1; - public const int MINOR = 28; - - public const string VERSION = "1.28"; - } -} + +namespace UniGLTF +{ + public static partial class UniGLTFVersion + { + public const int MAJOR = 1; + public const int MINOR = 28; + + public const string VERSION = "1.28"; + } +} diff --git a/UniGLTF/Core/Scripts/UniGLTFVersion.cs.meta b/UniGLTF/Scripts/UniGLTFVersion.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/UniGLTFVersion.cs.meta rename to UniGLTF/Scripts/UniGLTFVersion.cs.meta diff --git a/UniGLTF/Core/Scripts/UniGLTFVersion_partial.cs b/UniGLTF/Scripts/UniGLTFVersion_partial.cs similarity index 94% rename from UniGLTF/Core/Scripts/UniGLTFVersion_partial.cs rename to UniGLTF/Scripts/UniGLTFVersion_partial.cs index c67c54be7..72033936a 100644 --- a/UniGLTF/Core/Scripts/UniGLTFVersion_partial.cs +++ b/UniGLTF/Scripts/UniGLTFVersion_partial.cs @@ -1,8 +1,8 @@ - -namespace UniGLTF -{ - public static partial class UniGLTFVersion - { - public const string UNIGLTF_VERSION = "UniGLTF-" + VERSION; - } -} + +namespace UniGLTF +{ + public static partial class UniGLTFVersion + { + public const string UNIGLTF_VERSION = "UniGLTF-" + VERSION; + } +} diff --git a/UniGLTF/Core/Scripts/UniGLTFVersion_partial.cs.meta b/UniGLTF/Scripts/UniGLTFVersion_partial.cs.meta similarity index 100% rename from UniGLTF/Core/Scripts/UniGLTFVersion_partial.cs.meta rename to UniGLTF/Scripts/UniGLTFVersion_partial.cs.meta