├── .gitattributes ├── .gitignore ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── LICENSE.md ├── LICENSE.md.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── Code.meta ├── Code │ ├── AssemblyInfo.cs │ ├── AssemblyInfo.cs.meta │ ├── AssimpLoader.cs │ ├── AssimpLoader.cs.meta │ ├── At.Ac.FhStp.Import3D.asmdef │ ├── At.Ac.FhStp.Import3D.asmdef.meta │ ├── Common.meta │ ├── Common │ │ ├── Conversion.cs │ │ ├── Conversion.cs.meta │ │ ├── DataCopy.cs │ │ ├── DataCopy.cs.meta │ │ ├── Instantiation.cs │ │ └── Instantiation.cs.meta │ ├── Config.meta │ ├── Config │ │ ├── GroupNodeImportConfig.cs │ │ ├── GroupNodeImportConfig.cs.meta │ │ ├── ImportConfig.cs │ │ ├── ImportConfig.cs.meta │ │ ├── MeshImportConfig.cs │ │ └── MeshImportConfig.cs.meta │ ├── INamedModel.cs │ ├── INamedModel.cs.meta │ ├── Import.cs │ ├── Import.cs.meta │ ├── Materials.meta │ ├── Materials │ │ ├── DataCopy.cs │ │ ├── DataCopy.cs.meta │ │ ├── Import.cs │ │ ├── Import.cs.meta │ │ ├── Instantiation.cs │ │ ├── Instantiation.cs.meta │ │ ├── ModelConversion.cs │ │ ├── ModelConversion.cs.meta │ │ ├── Models.cs │ │ └── Models.cs.meta │ ├── Meshes.meta │ ├── Meshes │ │ ├── DataCopy.cs │ │ ├── DataCopy.cs.meta │ │ ├── Import.cs │ │ ├── Import.cs.meta │ │ ├── Instantiation.cs │ │ ├── Instantiation.cs.meta │ │ ├── ModelConversion.cs │ │ ├── ModelConversion.cs.meta │ │ ├── Models.cs │ │ └── Models.cs.meta │ ├── Nodes.meta │ ├── Nodes │ │ ├── DataCopy.cs │ │ ├── DataCopy.cs.meta │ │ ├── Import.cs │ │ ├── Import.cs.meta │ │ ├── ModelConversion.cs │ │ ├── ModelConversion.cs.meta │ │ ├── Models.cs │ │ └── Models.cs.meta │ ├── ResourceCache.cs │ ├── ResourceCache.cs.meta │ ├── Scenes.meta │ ├── Scenes │ │ ├── Import.cs │ │ └── Import.cs.meta │ ├── TaskManagement.cs │ ├── TaskManagement.cs.meta │ ├── Textures.meta │ └── Textures │ │ ├── DataCopy.cs │ │ ├── DataCopy.cs.meta │ │ ├── Import.cs │ │ ├── Import.cs.meta │ │ ├── Instantiation.cs │ │ ├── Instantiation.cs.meta │ │ ├── ModelConversion.cs │ │ ├── ModelConversion.cs.meta │ │ ├── Models.cs │ │ └── Models.cs.meta ├── Plugins.meta ├── Plugins │ ├── Assimp.meta │ └── Assimp │ │ ├── AssimpNet.dll │ │ ├── AssimpNet.dll.meta │ │ ├── Native.meta │ │ └── Native │ │ ├── android.meta │ │ ├── android │ │ ├── arm64-v8a.meta │ │ ├── arm64-v8a │ │ │ ├── libassimp.so │ │ │ └── libassimp.so.meta │ │ ├── armeabi-v7a.meta │ │ └── armeabi-v7a │ │ │ ├── libassimp.so │ │ │ └── libassimp.so.meta │ │ ├── win.meta │ │ └── win │ │ ├── x86_64.meta │ │ └── x86_64 │ │ ├── assimp.dll │ │ └── assimp.dll.meta ├── Resources.meta └── Resources │ ├── ForceShaderToBeIncludedInBuild.mat │ └── ForceShaderToBeIncludedInBuild.mat.meta ├── Samples~ ├── ImportTester.meta └── ImportTester │ ├── CHANGELOG.md │ ├── CHANGELOG.md.meta │ ├── Code.meta │ ├── Code │ ├── At.Ac.FhStp.Import3D.ImportTester.asmdef │ ├── At.Ac.FhStp.Import3D.ImportTester.asmdef.meta │ ├── AutoTileMaterial.cs │ ├── AutoTileMaterial.cs.meta │ ├── FloorFitter.cs │ ├── FloorFitter.cs.meta │ ├── Importer.cs │ ├── Importer.cs.meta │ ├── InputListener.cs │ ├── InputListener.cs.meta │ ├── ModelDisplayer.cs │ ├── ModelDisplayer.cs.meta │ ├── Types.cs │ └── Types.cs.meta │ ├── ImportTester.unity │ ├── ImportTester.unity.meta │ ├── Pink Checkers.mat │ ├── Pink Checkers.mat.meta │ ├── Pink Checkers.png │ ├── Pink Checkers.png.meta │ ├── README.md │ └── README.md.meta ├── Tests.meta ├── Tests ├── AssimpMeshBuilding.cs ├── AssimpMeshBuilding.cs.meta ├── AssimpNodeBuilding.cs ├── AssimpNodeBuilding.cs.meta ├── AssimpTextureBuilding.cs ├── AssimpTextureBuilding.cs.meta ├── At.Ac.FhStp.Import3D.Tests.asmdef ├── At.Ac.FhStp.Import3D.Tests.asmdef.meta ├── CompressedTextureImportTests.cs ├── CompressedTextureImportTests.cs.meta ├── GroupNodeImportTests.cs ├── GroupNodeImportTests.cs.meta ├── MaterialImportTests.cs ├── MaterialImportTests.cs.meta ├── MeshImportTests.cs ├── MeshImportTests.cs.meta ├── MeshNodeImportTests.cs ├── MeshNodeImportTests.cs.meta ├── NonCompressedTextureImportTests.cs └── NonCompressedTextureImportTests.cs.meta ├── package.json └── package.json.meta /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 |  2 | # Some global gitignores ignore meta files by default. Negate that 3 | !*.meta 4 | 5 | # Some global gitignores ignore folders with ~ in them 6 | 7 | !Documentation~/ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 4 | and this project adheres 5 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## Upcoming 8 | 9 | ## 0.11.1 10 | 11 | ### Changed 12 | 13 | - Project structure. All runtime related files are now inside 14 | the Runtime folder. All Code files have been moved into a Code 15 | subfolder. 16 | 17 | ## 0.10.1 18 | 19 | ### Added 20 | 21 | - Sample-info in readme 22 | 23 | ## 0.10.0 24 | 25 | ### Added 26 | 27 | - Import-tester sample 28 | - Invisible importing 29 | - Helper function to check if file import is supported 30 | 31 | ## 0.9.0 32 | 33 | ### Fixed 34 | 35 | - Fbx-scaling issue 36 | 37 | ## 0.8.0 38 | 39 | ### Added 40 | 41 | - Usage info in readme 42 | - Import materials 43 | - Name 44 | - Albedo color 45 | - Opacity 46 | - Specular color 47 | - Emission 48 | - Smoothness/Glossiness 49 | 50 | ### Changed 51 | 52 | - Config mutation syntax. Removed mutation methods. 53 | Use record `with` syntax instead 54 | 55 | ## 0.7.0 56 | 57 | ### Added 58 | 59 | - Import node transforms 60 | 61 | ### Changed 62 | 63 | - Bump Opt-unity to 3.4.0 64 | 65 | ## 0.6.2 66 | 67 | ### Added 68 | 69 | - Configure scene parent-gameobject after import 70 | - Option to import only meshes from file 71 | 72 | ## 0.6.1 73 | 74 | ### Added 75 | 76 | - Configure Assimp post-process-steps for imports 77 | - Configure scene-name 78 | 79 | ## 0.6.0 80 | 81 | ### Changed 82 | 83 | - Bump target Unity version to 2021.3 84 | - Remove assembly-validation warning as its no longer needed 85 | 86 | ## 0.5.1 87 | 88 | ### Fixed 89 | 90 | - Readme claimed that win x32 was supported when that was not true 91 | 92 | ### Changed 93 | 94 | - Assembly-definition file-name to match assembly name 95 | 96 | ## 0.5.0 97 | 98 | ### Added 99 | 100 | - Android support (v7 and arm64) 101 | - Win32 support 102 | 103 | ### Fixed 104 | 105 | - Wrong term in readme 106 | 107 | ## 0.4.0 108 | 109 | ### Fixed 110 | 111 | - Missing meta files 112 | 113 | ### Added 114 | 115 | - Note about assembly validation in readme 116 | 117 | ## 0.3.0 118 | 119 | ### Fixed 120 | 121 | - Missing shader in build 122 | 123 | ### Added 124 | 125 | - Package keywords in manifest 126 | 127 | ### Fixed 128 | 129 | - Missing 0.2.0 version header in changelog 130 | 131 | ## 0.2.0 132 | 133 | ### Added 134 | 135 | - Root-node now has scene file-name as name 136 | 137 | ### Fixed 138 | 139 | - Missing 0.1.0 version header in changelog 140 | 141 | ## 0.1.0 142 | 143 | ### Added 144 | 145 | - Import textures 146 | - Import basic meshes (without UVs or tangents) 147 | - Import scenes (Nodes with meshes. No materials yet) -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3c121860ebc6af647adc8a8b7907c68d 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 105a1ae3db94ee6428fa06d4345cb22f 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Import3D 2 | 3 | [![openupm](https://img.shields.io/npm/v/at.ac.fhstp.import3d?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/at.ac.fhstp.import3d/) 4 | 5 | An asynchronous runtime 3D-model importer for Unity 6 | 7 | Check out the changelog [here](./CHANGELOG.md). 8 | 9 | **⚠️ Development is paused ⚠️** 10 | No new features will be added or bugs fixed unless requested through an issue. 11 | If you wish to fork this repository and continue the work, you are very welcome 12 | to do so. 13 | 14 | ## Features 15 | 16 | Import3D supports most common 3D-model formats 17 | as it uses [Assimp](https://github.com/assimp/assimp) 18 | internally. 19 | 20 | Imports a scene's node-structure and geometry. 21 | Materials and textures are not imported yet. 22 | 23 | ## Usage 24 | 25 | Import functions are located on the static `Import` class. 26 | 27 | ```csharp 28 | // using At.Ac.FhStp.Import3D 29 | 30 | // Import a single file asynchronously 31 | var importedGameObject = await Import.SingleAsync(filePath); 32 | ``` 33 | 34 | ### Config 35 | 36 | Some properties of the import process can be configured using 37 | a `ImportConfig` object, which can be passed as a second argument 38 | to all import functions. Refer to the `ImportConfig` XML-docs to 39 | learn more. 40 | 41 | ```csharp 42 | var config = ImportConfig.Default; 43 | _ = await Import.SingleAsync(filePath, config); 44 | ``` 45 | 46 | ## Targets 47 | 48 | Import3D uses the C-library [Assimp](https://github.com/assimp/assimp) 49 | internally. Because of this, not all target devices are supported 50 | out of the box as binaries for these platforms have to built and included 51 | in the package. 52 | 53 | Currently Import3D supports the following platforms: 54 | 55 | - Windows x64 56 | - Android v7 / arm64 57 | 58 | ## Installation 59 | 60 | Best way to install is via [OpenUPM](https://openupm.com/) 61 | using `openupm add at.ac.fhstp.import3d`. 62 | 63 | You can also install manually as a git-dependency from 64 | `https://github.com/fhstp/UnityImport3D.git`. Make sure to add 65 | the following scoped-registry if you choose to do so: 66 | 67 | ```json 68 | { 69 | "name": "package.openupm.com", 70 | "url": "https://package.openupm.com", 71 | "scopes": [ 72 | "com.openupm", 73 | "dev.comradevanti.opt-unity", 74 | "dev.comradevanti.rect-constraints", 75 | "org.nuget.comradevanti.csharptools.opt", 76 | "org.nuget.dev.comradevanti.nothing", 77 | "org.nuget.system.buffers", 78 | "org.nuget.system.collections.immutable", 79 | "org.nuget.system.memory", 80 | "org.nuget.system.numerics.vectors", 81 | "org.nuget.system.runtime.compilerservices.unsafe" 82 | ] 83 | } 84 | ``` 85 | 86 | ## Samples 87 | 88 | The package also includes a sample to show how the import process can be started. 89 | Have a look at `/Samples~/ImportTester`. 90 | 91 | ## Roadmap 92 | 93 | - Texture import 94 | - Better error-handling 95 | - Optimizations 96 | - More build targets 97 | 98 | ## Compatibility 99 | 100 | Developed for/with Unity 2021.3 101 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b7794d66a3db110469fcd57efd018966 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6170b64c74e16104f8b62367616dbbca 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0723876dc1c72d44afeaaa3d9172cf2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Runtime.CompilerServices; 3 | 4 | [assembly: InternalsVisibleTo("At.Ac.FhStp.Import3D.Tests")] 5 | 6 | // ReSharper disable once CheckNamespace 7 | namespace System.Runtime.CompilerServices 8 | { 9 | [EditorBrowsable(EditorBrowsableState.Never)] 10 | internal class IsExternalInit{} 11 | } -------------------------------------------------------------------------------- /Runtime/Code/AssemblyInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5886add2cab12cd4885f105f37280b4c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/AssimpLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Assimp; 5 | using Assimp.Unmanaged; 6 | using UnityEngine; 7 | using AssimpScene = Assimp.Scene; 8 | using static At.Ac.FhStp.Import3D.TaskManagement; 9 | 10 | namespace At.Ac.FhStp.Import3D 11 | { 12 | internal static class AssimpLoader 13 | { 14 | [SuppressMessage("ReSharper", "BitwiseOperatorOnEnumWithoutFlags")] 15 | private const RuntimePlatform EditorPlatforms = 16 | RuntimePlatform.LinuxEditor 17 | | RuntimePlatform.WindowsEditor 18 | | RuntimePlatform.OSXEditor; 19 | 20 | private static bool? prevLoadAttemptSucceeded; 21 | 22 | 23 | private static bool PlatformIsEditor => 24 | EditorPlatforms.HasFlag(Application.platform); 25 | 26 | private static string EditorNativesPath 27 | { 28 | get 29 | { 30 | var packagePath = 31 | Path.GetFullPath("Packages/at.ac.fhstp.import3d"); 32 | var pluginsPath = Path.Combine(packagePath, "Runtime", "Plugins"); 33 | return Path.Combine(pluginsPath, "Assimp", "Native"); 34 | } 35 | } 36 | 37 | private static string PlayerDataPath => 38 | Application.dataPath; 39 | 40 | 41 | private static string PlayerPluginsPath => 42 | Path.Combine(PlayerDataPath, "Plugins"); 43 | 44 | 45 | private static LibPaths? TryFindPaths() 46 | { 47 | LibPaths ForWindowsEditor() 48 | { 49 | var nativesPath = Path.Combine(EditorNativesPath, "win"); 50 | return new LibPaths( 51 | Path.Combine(nativesPath, "x86", "assimp.dll"), 52 | Path.Combine(nativesPath, "x86_64", "assimp.dll")); 53 | } 54 | 55 | LibPaths ForWindowsPlayer() 56 | { 57 | var pluginsPath = PlayerPluginsPath; 58 | return new LibPaths( 59 | Path.Combine(pluginsPath, "x86", "assimp.dll"), 60 | Path.Combine(pluginsPath, "x86_64", "assimp.dll")); 61 | } 62 | 63 | LibPaths ForAndroidPlayer() => 64 | // On Android its enough to specify the lib-name 65 | // The OS finds the path on its own 66 | LibPaths.ForBoth("libassimp.so"); 67 | 68 | return Application.platform switch 69 | { 70 | RuntimePlatform.WindowsEditor => ForWindowsEditor(), 71 | RuntimePlatform.WindowsPlayer => ForWindowsPlayer(), 72 | RuntimePlatform.Android => ForAndroidPlayer(), 73 | _ => null 74 | }; 75 | } 76 | 77 | private static bool AttemptLoad(UnmanagedLibrary library) 78 | { 79 | var maybePaths = TryFindPaths(); 80 | 81 | if (maybePaths == null) 82 | { 83 | Debug.LogError("Import3D does not support " + 84 | Application.platform); 85 | return false; 86 | } 87 | 88 | var paths = maybePaths.Value; 89 | return library.LoadLibrary(paths.X32, paths.X64); 90 | } 91 | 92 | private static bool ConfirmLibraryLoadedAndConfigured() 93 | { 94 | if (prevLoadAttemptSucceeded != null) 95 | return prevLoadAttemptSucceeded.Value; 96 | 97 | var library = AssimpLibrary.Instance; 98 | prevLoadAttemptSucceeded = 99 | library.IsLibraryLoaded || AttemptLoad(library); 100 | 101 | return prevLoadAttemptSucceeded.Value; 102 | } 103 | 104 | internal static AssimpContext MakeContext() 105 | { 106 | ConfirmLibraryLoadedAndConfigured(); 107 | return new AssimpContext(); 108 | } 109 | 110 | internal static async Task LoadSceneFrom( 111 | string path, 112 | PostProcessSteps extraPostProcessSteps) 113 | { 114 | var ctx = MakeContext(); 115 | var scene = await InBackground( 116 | () => ctx.ImportFile(path, 117 | // PostProcessSteps.Triangulate is required 118 | extraPostProcessSteps | PostProcessSteps.Triangulate)); 119 | ctx.Dispose(); 120 | return scene; 121 | } 122 | 123 | private struct LibPaths 124 | { 125 | public string X32 { get; } 126 | 127 | public string X64 { get; } 128 | 129 | 130 | public LibPaths(string x32, string x64) 131 | { 132 | X32 = x32; 133 | X64 = x64; 134 | } 135 | 136 | public static LibPaths ForBoth(string path) => 137 | new LibPaths(path, path); 138 | } 139 | } 140 | } -------------------------------------------------------------------------------- /Runtime/Code/AssimpLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6114f7de9f222ac42a9f81b4e3bf9be9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/At.Ac.FhStp.Import3D.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "At.Ac.FhStp.Import3D", 3 | "rootNamespace": "At.Ac.FhStp.Import3D", 4 | "references": [ 5 | "GUID:abae1860b9cc9c84289013571e170b12" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [], 15 | "noEngineReferences": false 16 | } -------------------------------------------------------------------------------- /Runtime/Code/At.Ac.FhStp.Import3D.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39e22437faf958a4fbeee0bc8495a90b 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Code/Common.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cb793e6803947b4ba0afaa07a69f49c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code/Common/Conversion.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using AssimpVector = Assimp.Vector3D; 3 | 4 | namespace At.Ac.FhStp.Import3D 5 | { 6 | public static class Conversion 7 | { 8 | public static Vector3 ConvertVector(AssimpVector v) => 9 | new Vector3(v.X, v.Y, v.Z); 10 | } 11 | } -------------------------------------------------------------------------------- /Runtime/Code/Common/Conversion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 08f343d66dee44b89bc8ed77c3b044a2 3 | timeCreated: 1677493907 -------------------------------------------------------------------------------- /Runtime/Code/Common/DataCopy.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Dev.ComradeVanti; 3 | using UnityObject = UnityEngine.Object; 4 | using static At.Ac.FhStp.Import3D.TaskManagement; 5 | 6 | namespace At.Ac.FhStp.Import3D.Common 7 | { 8 | internal static class DataCopy 9 | { 10 | internal static Task CopyName(INamedModel model, UnityObject obj) => 11 | DoAsync(() => obj.name = model.Name); 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/Code/Common/DataCopy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95f6bb20a1b8cc44bb7e30ec2df2bb8c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Common/Instantiation.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using UnityEngine; 3 | using static At.Ac.FhStp.Import3D.TaskManagement; 4 | 5 | namespace At.Ac.FhStp.Import3D.Common 6 | { 7 | internal static class Instantiation 8 | { 9 | internal static Task MakeGameObject(string name, bool active) => 10 | CalcAsync(() => 11 | { 12 | var gameObject = new GameObject(name); 13 | gameObject.SetActive(active); 14 | return gameObject; 15 | }); 16 | } 17 | } -------------------------------------------------------------------------------- /Runtime/Code/Common/Instantiation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1288f5ac6e25f2b4c9b5b84a675de8d3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Config.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc319090c4fe0184c99537431cc2e77f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code/Config/GroupNodeImportConfig.cs: -------------------------------------------------------------------------------- 1 | namespace At.Ac.FhStp.Import3D 2 | { 3 | public record GroupNodeImportConfig( 4 | float ScalingFactor, 5 | bool Hidden) 6 | { 7 | public static readonly GroupNodeImportConfig Default = new GroupNodeImportConfig(1, true); 8 | }; 9 | } -------------------------------------------------------------------------------- /Runtime/Code/Config/GroupNodeImportConfig.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a716fd70cb00410f9e0e9b283f0372eb 3 | timeCreated: 1697447210 -------------------------------------------------------------------------------- /Runtime/Code/Config/ImportConfig.cs: -------------------------------------------------------------------------------- 1 | using Assimp; 2 | using ComradeVanti.CSharpTools; 3 | using UnityEngine; 4 | 5 | namespace At.Ac.FhStp.Import3D 6 | { 7 | /// 8 | /// Allows the user to configure the import of files 9 | /// 10 | public record ImportConfig 11 | { 12 | /// 13 | /// A default configuration that works for most imports 14 | /// 15 | /// Uses no extra post-process steps 16 | /// Uses the file-name for the scene-name 17 | /// Instantiated scene is not attached to any game-object 18 | /// 19 | /// 20 | public static readonly ImportConfig Default = 21 | new ImportConfig 22 | { 23 | ExtraAssimpPostProcessSteps = PostProcessSteps.None, 24 | SceneNameOverride = Opt.None(), 25 | ActivateRoot = true, 26 | Hidden = true, 27 | Parent = Opt.None() 28 | }; 29 | 30 | /// 31 | /// Extra post-process-steps that assimp applies during import. 32 | /// Triangulate is enforced for every import by default 33 | /// 34 | /// Assimp documentation 35 | public PostProcessSteps ExtraAssimpPostProcessSteps { get; init; } 36 | 37 | /// 38 | /// By default the name of the scene is taken to be name name of the imported file. 39 | /// If this property is set so Some string it will override this behaviour. 40 | /// 41 | public IOpt SceneNameOverride { get; init; } 42 | 43 | /// 44 | /// A transform to parent the instantiated scene to 45 | /// 46 | public IOpt Parent { get; init; } 47 | 48 | /// 49 | /// Whether the root game-object should be activated or not 50 | /// 51 | public bool ActivateRoot { get; init; } 52 | 53 | /// 54 | /// Whether the model should be invisible during the import process 55 | /// 56 | public bool Hidden { get; init; } 57 | } 58 | } -------------------------------------------------------------------------------- /Runtime/Code/Config/ImportConfig.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9fa07c8ae02336148a0c2c3337ebf759 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Config/MeshImportConfig.cs: -------------------------------------------------------------------------------- 1 | namespace At.Ac.FhStp.Import3D 2 | { 3 | public record MeshImportConfig(float ScalingFactor) 4 | { 5 | public static readonly MeshImportConfig Default = new MeshImportConfig(1); 6 | }; 7 | } -------------------------------------------------------------------------------- /Runtime/Code/Config/MeshImportConfig.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51ed61ad9da74d67977b4604001e98ab 3 | timeCreated: 1697446506 -------------------------------------------------------------------------------- /Runtime/Code/INamedModel.cs: -------------------------------------------------------------------------------- 1 | namespace At.Ac.FhStp.Import3D 2 | { 3 | internal interface INamedModel 4 | { 5 | string Name { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /Runtime/Code/INamedModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3480c341ec9ffb34cbf614b830c8a0b6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Import.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using JetBrains.Annotations; 6 | using UnityEngine; 7 | using static At.Ac.FhStp.Import3D.Scenes.Import; 8 | using static At.Ac.FhStp.Import3D.Meshes.Import; 9 | using static At.Ac.FhStp.Import3D.TaskManagement; 10 | 11 | namespace At.Ac.FhStp.Import3D 12 | { 13 | /// 14 | /// Contains functions for importing 3D objects 15 | /// 16 | public static class Import 17 | { 18 | /// 19 | /// Imports a 3D-model file from a given path 20 | /// 21 | /// The path to the file 22 | /// Configuration for this import 23 | /// A task, producing the imported scene 24 | public static async Task SingleAsync(string path, [CanBeNull] ImportConfig config = null) 25 | { 26 | config ??= ImportConfig.Default; 27 | var assimpScene = await AssimpLoader.LoadSceneFrom(path, 28 | config.ExtraAssimpPostProcessSteps); 29 | return await ImportScene(assimpScene, path, config); 30 | } 31 | 32 | /// 33 | /// Imports all meshes from 3D-model file at a given path 34 | /// 35 | /// The path to the file 36 | /// Configuration for this import 37 | /// A task, producing the meshes 38 | public static async Task> MeshesFromSingleAsync(string path, [CanBeNull] ImportConfig config = null) 39 | { 40 | config ??= ImportConfig.Default; 41 | var assimpScene = await AssimpLoader.LoadSceneFrom(path, 42 | config.ExtraAssimpPostProcessSteps); 43 | var meshImportConfig = new MeshImportConfig( 44 | assimpScene.GetScalingFactor()); 45 | 46 | return await InParallel( 47 | assimpScene.Meshes.Select(mesh => ImportMesh(mesh, meshImportConfig))); 48 | } 49 | 50 | /// 51 | /// Checks if a file is supported for import 52 | /// 53 | /// The file of the path 54 | /// Whether the file can be imported 55 | public static bool SupportsFileExtension(string path) 56 | { 57 | var extension = Path.GetExtension(path); 58 | /* 59 | NOTE: Every time this function is called, an 60 | AssimpContext is created and I don't know if that is bad. 61 | */ 62 | return AssimpLoader.MakeContext().IsImportFormatSupported(extension); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /Runtime/Code/Import.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4848079300a2ec4c9bdb97e2ffb76d3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 298b87c0c0e0d3042a0384c405a15cce 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code/Materials/DataCopy.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Dev.ComradeVanti; 3 | using UnityEngine; 4 | using static At.Ac.FhStp.Import3D.TaskManagement; 5 | 6 | namespace At.Ac.FhStp.Import3D.Materials 7 | { 8 | internal static class DataCopy 9 | { 10 | private static readonly int colorId = Shader.PropertyToID("_Color"); 11 | private static readonly int specColorId = Shader.PropertyToID("_SpecColor"); 12 | private static readonly int srcBlendId = Shader.PropertyToID("_SrcBlend"); 13 | private static readonly int dstBlendId = Shader.PropertyToID("_DstBlend"); 14 | private static readonly int zWriteId = Shader.PropertyToID("_ZWrite"); 15 | private static readonly int emissionColorId = Shader.PropertyToID("_EmissionColor"); 16 | private static readonly int glossinessId = Shader.PropertyToID("_Glossiness"); 17 | 18 | internal static Task CopyColor(Color color, Material material) => 19 | DoAsync(() => material.SetColor(colorId, color)); 20 | 21 | internal static Task CopySpecColor(Color color, Material material) => 22 | DoAsync(() => material.SetColor(specColorId, color)); 23 | 24 | internal static Task CopyTransparency(Material material, bool isTransparent) => 25 | DoAsync(() => 26 | { 27 | material.SetOverrideTag("RenderType", isTransparent ? "Transparent" : ""); 28 | 29 | material.SetInt(srcBlendId, (int) UnityEngine.Rendering.BlendMode.One); 30 | material.SetInt(dstBlendId, isTransparent 31 | ? (int) UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha 32 | : (int) UnityEngine.Rendering.BlendMode.Zero); 33 | 34 | material.SetInt(zWriteId, isTransparent ? 0 : 1); 35 | 36 | material.DisableKeyword("_ALPHATEST_ON"); 37 | material.DisableKeyword("_ALPHABLEND_ON"); 38 | if (isTransparent) 39 | material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); 40 | else 41 | material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); 42 | 43 | material.renderQueue = isTransparent ? 3000 : -1; 44 | }); 45 | 46 | internal static Task CopyEmissiveColor(Color color, Material material) => 47 | DoAsync(() => 48 | { 49 | material.EnableKeyword("_EMISSION"); 50 | material.SetColor(emissionColorId, color); 51 | }); 52 | 53 | internal static Task CopySmoothness(float smoothness, Material material) => 54 | DoAsync(() => material.SetFloat(glossinessId, smoothness)); 55 | } 56 | } -------------------------------------------------------------------------------- /Runtime/Code/Materials/DataCopy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c23bfcc85ae4d68a8c69fb96bdaba90 3 | timeCreated: 1677593841 -------------------------------------------------------------------------------- /Runtime/Code/Materials/Import.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Dev.ComradeVanti; 3 | using UnityEngine; 4 | using static At.Ac.FhStp.Import3D.Common.DataCopy; 5 | using static At.Ac.FhStp.Import3D.Materials.DataCopy; 6 | using static At.Ac.FhStp.Import3D.Materials.Instantiation; 7 | using static At.Ac.FhStp.Import3D.Materials.ModelConversion; 8 | using static At.Ac.FhStp.Import3D.TaskManagement; 9 | 10 | namespace At.Ac.FhStp.Import3D.Materials 11 | { 12 | internal static class Import 13 | { 14 | internal static async Task ImportMeshFromModel(MaterialModel model) 15 | { 16 | var material = await MakeMaterial(); 17 | 18 | await InParallel( 19 | CopyName(model, material), 20 | CopyColor(model.Color, material), 21 | CopySpecColor(model.SpecularColor, material), 22 | model.EmissiveColor.Match( 23 | onSome: it => CopyEmissiveColor(it, material), 24 | onNone: () => Task.FromResult(Nothing.atAll)), 25 | CopyTransparency(material, model.IsTransparent), 26 | CopySmoothness(model.Smoothness, material)); 27 | 28 | return material; 29 | } 30 | 31 | internal static async Task ImportMaterial(Assimp.Material assimpMaterial) 32 | { 33 | var model = await InBackground(() => ConvertToModel(assimpMaterial)); 34 | return await ImportMeshFromModel(model); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Runtime/Code/Materials/Import.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50ee775a82af4ef8aae5b8e598a2e1d3 3 | timeCreated: 1677574933 -------------------------------------------------------------------------------- /Runtime/Code/Materials/Instantiation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using UnityEngine; 4 | using static At.Ac.FhStp.Import3D.TaskManagement; 5 | 6 | namespace At.Ac.FhStp.Import3D.Materials 7 | { 8 | internal static class Instantiation 9 | { 10 | 11 | private static readonly Lazy standardShader = 12 | new Lazy(() => Shader.Find("Standard (Specular setup)")); 13 | 14 | 15 | internal static Task MakeMaterial() => 16 | CalcAsync(() => new Material(standardShader.Value)); 17 | 18 | } 19 | } -------------------------------------------------------------------------------- /Runtime/Code/Materials/Instantiation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7bc4fb1d62854eeeb869d43414b8d204 3 | timeCreated: 1677575892 -------------------------------------------------------------------------------- /Runtime/Code/Materials/ModelConversion.cs: -------------------------------------------------------------------------------- 1 | using ComradeVanti.CSharpTools; 2 | using UnityEngine; 3 | 4 | namespace At.Ac.FhStp.Import3D.Materials 5 | { 6 | internal static class ModelConversion 7 | { 8 | private static Color ConvertColor(Assimp.Color4D color) 9 | { 10 | return new Color(color.R, color.G, color.B, color.A); 11 | } 12 | 13 | private static Color MultRGB(this Color c, float f) => 14 | new Color(c.r * f, c.g * f, c.b * f, c.a); 15 | 16 | internal static MaterialModel ConvertToModel(Assimp.Material assimpMaterial) 17 | { 18 | var diffuse = assimpMaterial.HasColorDiffuse 19 | ? ConvertColor(assimpMaterial.ColorDiffuse) 20 | : Color.black; 21 | var ambient = assimpMaterial.HasColorAmbient 22 | ? ConvertColor(assimpMaterial.ColorAmbient) 23 | : Color.black; 24 | var color = diffuse + ambient; 25 | color.a *= assimpMaterial.Opacity; 26 | 27 | var specular = assimpMaterial.HasColorSpecular 28 | ? ConvertColor(assimpMaterial.ColorSpecular) 29 | : Color.black; 30 | specular = specular.MultRGB(assimpMaterial.ShininessStrength); 31 | 32 | var emissive = assimpMaterial.HasColorEmissive 33 | ? Opt.Some(ConvertColor(assimpMaterial.ColorEmissive)) 34 | : Opt.None(); 35 | 36 | /* I dont know if reflectivity is actually the right property 37 | * to use here. There is pretty much no documentation about it, 38 | * but at least it is [0,1] or at least seems that way. */ 39 | var smoothness = assimpMaterial.HasReflectivity 40 | ? assimpMaterial.Reflectivity 41 | : 0.5f; 42 | 43 | return new MaterialModel( 44 | assimpMaterial.Name, color, specular, emissive, smoothness); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/Code/Materials/ModelConversion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d94ff48272204c1daebefd03cdd50cfb 3 | timeCreated: 1677574734 -------------------------------------------------------------------------------- /Runtime/Code/Materials/Models.cs: -------------------------------------------------------------------------------- 1 | using ComradeVanti.CSharpTools; 2 | using UnityEngine; 3 | 4 | namespace At.Ac.FhStp.Import3D.Materials 5 | { 6 | internal class MaterialModel : INamedModel 7 | { 8 | public string Name { get; } 9 | 10 | public Color Color { get; } 11 | 12 | public Color SpecularColor { get; } 13 | 14 | public IOpt EmissiveColor { get; } 15 | 16 | public float Smoothness { get; } 17 | 18 | public bool IsTransparent => Color.a < 1; 19 | 20 | 21 | public MaterialModel(string name, Color color, Color specularColor, IOpt emissiveColor, float smoothness) 22 | { 23 | Name = name; 24 | Color = color; 25 | SpecularColor = specularColor; 26 | EmissiveColor = emissiveColor; 27 | Smoothness = smoothness; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Runtime/Code/Materials/Models.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcfb0f734d9d4f3c99105264d4d57cc7 3 | timeCreated: 1677574626 -------------------------------------------------------------------------------- /Runtime/Code/Meshes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0af951a59429ac479783f152864c09d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code/Meshes/DataCopy.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Dev.ComradeVanti; 3 | using UnityEngine; 4 | using static At.Ac.FhStp.Import3D.TaskManagement; 5 | 6 | namespace At.Ac.FhStp.Import3D.Meshes 7 | { 8 | internal static class DataCopy 9 | { 10 | internal static Task CopyVertices(MeshModel model, Mesh mesh) => 11 | DoAsync(async () => 12 | { 13 | var vertices = await InBackground(() => model.Vertices.Value); 14 | mesh.vertices = vertices; 15 | }); 16 | 17 | internal static Task CopyTriangles(MeshModel model, Mesh mesh) => 18 | DoAsync(async () => 19 | { 20 | var triangles = await InBackground(() => model.Triangles.Value); 21 | mesh.triangles = triangles; 22 | }); 23 | 24 | internal static Task CopyNormals(MeshModel model, Mesh mesh) => 25 | DoAsync(async () => 26 | { 27 | var normals = await InBackground(() => model.Normals.Value); 28 | mesh.normals = normals; 29 | }); 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/Code/Meshes/DataCopy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e80ff39f8f37a044f98284a0d3c1711a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Meshes/Import.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System.Threading.Tasks; 4 | using UnityEngine; 5 | using AssimpMesh = Assimp.Mesh; 6 | using static At.Ac.FhStp.Import3D.Meshes.Instantiation; 7 | using static At.Ac.FhStp.Import3D.Meshes.ModelConversion; 8 | using static At.Ac.FhStp.Import3D.Common.DataCopy; 9 | using static At.Ac.FhStp.Import3D.Meshes.DataCopy; 10 | using static At.Ac.FhStp.Import3D.TaskManagement; 11 | 12 | namespace At.Ac.FhStp.Import3D.Meshes 13 | { 14 | internal static class Import 15 | { 16 | internal static async Task ImportMeshFromModel(MeshModel model) 17 | { 18 | var mesh = await MakeEmptyMesh(); 19 | 20 | await InParallel( 21 | CopyName(model, mesh), 22 | CopyVertices(model, mesh)); 23 | await CopyTriangles(model, mesh); 24 | await CopyNormals(model, mesh); 25 | 26 | return mesh; 27 | } 28 | 29 | internal static async Task ImportMesh(AssimpMesh assimpMesh, MeshImportConfig config) 30 | { 31 | var model = await InBackground( 32 | () => ConvertToModel(assimpMesh, config.ScalingFactor)); 33 | return await ImportMeshFromModel(model); 34 | } 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /Runtime/Code/Meshes/Import.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 11a08354310a28643b122d98d068b52b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Meshes/Instantiation.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using UnityEngine; 3 | using static At.Ac.FhStp.Import3D.TaskManagement; 4 | 5 | namespace At.Ac.FhStp.Import3D.Meshes 6 | { 7 | internal static class Instantiation 8 | { 9 | internal static Task MakeEmptyMesh() => 10 | CalcAsync(() => new Mesh()); 11 | } 12 | } -------------------------------------------------------------------------------- /Runtime/Code/Meshes/Instantiation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e080956a9ef5bfd418ffec6f928d4e44 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Meshes/ModelConversion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UnityEngine; 5 | using static At.Ac.FhStp.Import3D.Conversion; 6 | using AssimpMesh = Assimp.Mesh; 7 | using AssimpVector = Assimp.Vector3D; 8 | using AssimpFace = Assimp.Face; 9 | 10 | namespace At.Ac.FhStp.Import3D.Meshes 11 | { 12 | internal static class ModelConversion 13 | { 14 | private static IEnumerable FaceTriangles(AssimpFace face) => 15 | face.Indices; 16 | 17 | internal static MeshModel ConvertToModel(AssimpMesh assimpMesh, float scalingFactor = 1) 18 | { 19 | var vertices = new Lazy( 20 | () => assimpMesh.Vertices 21 | .Select(ConvertVector) 22 | .Select(v => v * scalingFactor) 23 | .ToArray()); 24 | 25 | var triangles = new Lazy( 26 | () => assimpMesh.Faces.SelectMany(FaceTriangles).ToArray()); 27 | 28 | var normals = new Lazy( 29 | () => assimpMesh.Normals.Select(ConvertVector).ToArray()); 30 | 31 | return new MeshModel(assimpMesh.Name, vertices, triangles, normals); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Runtime/Code/Meshes/ModelConversion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6ec4e3f64ac37d4a9a716741a903405 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Meshes/Models.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace At.Ac.FhStp.Import3D.Meshes 5 | { 6 | internal class MeshModel : INamedModel 7 | { 8 | internal MeshModel( 9 | string name, Lazy vertices, Lazy triangles, Lazy normals) 10 | { 11 | Name = name; 12 | Vertices = vertices; 13 | Triangles = triangles; 14 | Normals = normals; 15 | } 16 | 17 | internal Lazy Vertices { get; } 18 | 19 | internal Lazy Triangles { get; } 20 | 21 | internal Lazy Normals { get; } 22 | 23 | public string Name { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /Runtime/Code/Meshes/Models.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 91163635614f6944da1f319f0e4d923b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Nodes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d27ea71bc16bdd4c8308e7284673d4c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code/Nodes/DataCopy.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Dev.ComradeVanti; 3 | using UnityEngine; 4 | using static At.Ac.FhStp.Import3D.TaskManagement; 5 | 6 | namespace At.Ac.FhStp.Import3D.Nodes 7 | { 8 | internal static class DataCopy 9 | { 10 | internal static Task CopyMesh( 11 | Mesh mesh, GameObject gameObject) => 12 | DoAsync(() => 13 | { 14 | var meshFilter = gameObject.AddComponent(); 15 | meshFilter.mesh = mesh; 16 | }); 17 | 18 | internal static Task CopyMaterial( 19 | Material material, GameObject gameObject) => 20 | DoAsync(() => 21 | { 22 | var meshRenderer = gameObject.AddComponent(); 23 | meshRenderer.material = material; 24 | }); 25 | 26 | internal static Task CopyRelationship( 27 | GameObject parent, GameObject child) => 28 | DoAsync(() => child.transform.SetParent(parent.transform, false)); 29 | 30 | internal static Task CopyPosition( 31 | Vector3 position, GameObject gameObject) => 32 | DoAsync(() => gameObject.transform.localPosition = position); 33 | 34 | internal static Task CopyRotation( 35 | Quaternion quaternion, GameObject gameObject) => 36 | DoAsync(() => gameObject.transform.localRotation = quaternion); 37 | 38 | internal static Task CopyScale( 39 | Vector3 scale, GameObject gameObject) => 40 | DoAsync(() => gameObject.transform.localScale = scale); 41 | 42 | internal static Task CopyIsActive( 43 | bool isActive, GameObject gameObject) => 44 | DoAsync(() => gameObject.SetActive(isActive)); 45 | } 46 | } -------------------------------------------------------------------------------- /Runtime/Code/Nodes/DataCopy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd56a20c703e2d144b0f916fa0d0b0b4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Nodes/Import.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using UnityEngine; 6 | using AssimpMesh = Assimp.Mesh; 7 | using AssimpNode = Assimp.Node; 8 | using static At.Ac.FhStp.Import3D.Common.Instantiation; 9 | using static At.Ac.FhStp.Import3D.TaskManagement; 10 | using static At.Ac.FhStp.Import3D.Nodes.DataCopy; 11 | using static At.Ac.FhStp.Import3D.Nodes.ModelConversion; 12 | 13 | namespace At.Ac.FhStp.Import3D.Nodes 14 | { 15 | internal static class Import 16 | { 17 | internal static async Task ImportMeshNode( 18 | MeshNode node, 19 | MeshCache meshCache, MaterialCache materialCache) 20 | { 21 | var mesh = await meshCache.Resolve(node.MeshIndex); 22 | var material = await materialCache.Resolve(node.MaterialIndex); 23 | 24 | var gameObject = await MakeGameObject(mesh.name, false); 25 | 26 | await InParallel( 27 | CopyMesh(mesh, gameObject), 28 | CopyMaterial(material, gameObject)); 29 | 30 | return gameObject; 31 | } 32 | 33 | internal static Task ImportNode( 34 | AssimpNode node, Func resolveMaterialIndex, 35 | MeshCache meshCache, MaterialCache materialCache, 36 | GroupNodeImportConfig config) 37 | { 38 | async Task ImportFromModel(GroupNodeModel model) 39 | { 40 | var (gameObject, childNodes, meshNodes) = await InParallel( 41 | MakeGameObject(model.Name, !config.Hidden), 42 | InParallel(model.Children.Select(ImportFromModel)), 43 | InParallel(model.MeshNodes.Select( 44 | meshNode => ImportMeshNode(meshNode, meshCache, materialCache)))); 45 | 46 | var allChildren = childNodes.Concat(meshNodes).ToHashSet(); 47 | 48 | await InParallel(allChildren.Select(child => CopyRelationship(gameObject, child))); 49 | await InParallel(allChildren.Select(child => CopyIsActive(true, child))); 50 | 51 | await InParallel( 52 | CopyPosition(model.Position, gameObject), 53 | CopyRotation(model.Rotation, gameObject), 54 | CopyScale(model.Scale, gameObject)); 55 | 56 | return gameObject; 57 | } 58 | 59 | var model = ConvertToModel(node, resolveMaterialIndex, config.ScalingFactor); 60 | return ImportFromModel(model); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /Runtime/Code/Nodes/Import.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ed97310b8b6a014e88e8060e3a713dc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Nodes/ModelConversion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Immutable; 4 | using System.Linq; 5 | using UnityEngine; 6 | using static At.Ac.FhStp.Import3D.Conversion; 7 | using AssimpNode = Assimp.Node; 8 | 9 | namespace At.Ac.FhStp.Import3D.Nodes 10 | { 11 | internal static class ModelConversion 12 | { 13 | private static bool IsXInverted(Matrix4x4 matrix) => 14 | Vector3.Cross(matrix.GetColumn(0), matrix.GetColumn(1)).normalized != (Vector3) matrix.GetColumn(2).normalized; 15 | 16 | private static Vector3 PositionIn(Matrix4x4 matrix) => 17 | new Vector3(matrix.m03, 18 | matrix.m13, 19 | matrix.m23); 20 | 21 | private static Quaternion RotationIn(Matrix4x4 matrix) 22 | { 23 | var forward = new Vector3( 24 | matrix.m02, 25 | matrix.m12, 26 | matrix.m22); 27 | 28 | var upwards = new Vector3( 29 | matrix.m01, 30 | matrix.m11, 31 | matrix.m21); 32 | 33 | return Quaternion.LookRotation(forward, upwards); 34 | } 35 | 36 | private static Vector3 ScaleIn(this Matrix4x4 matrix) 37 | { 38 | var scale = new Vector3( 39 | matrix.GetColumn(0).magnitude, 40 | matrix.GetColumn(1).magnitude, 41 | matrix.GetColumn(2).magnitude); 42 | 43 | if (IsXInverted(matrix)) scale.x *= -1; 44 | 45 | return scale; 46 | } 47 | 48 | private static Matrix4x4 ConvertMatrix(Assimp.Matrix4x4 matrix) => 49 | new Matrix4x4( 50 | new Vector4(matrix.A1, matrix.B1, matrix.C1, matrix.D1), 51 | new Vector4(matrix.A2, matrix.B2, matrix.C2, matrix.D2), 52 | new Vector4(matrix.A3, matrix.B3, matrix.C3, matrix.D3), 53 | new Vector4(matrix.A4, matrix.B4, matrix.C4, matrix.D4)); 54 | 55 | internal static GroupNodeModel ConvertToModel(AssimpNode assimpNode, Func resolveMaterialIndex, float scalingFactor) 56 | { 57 | var children = 58 | assimpNode.Children 59 | .Select(child => ConvertToModel(child, resolveMaterialIndex, scalingFactor)) 60 | .ToImmutableArray(); 61 | var meshNodes = 62 | assimpNode.MeshIndices 63 | .Select(meshIndex => 64 | { 65 | var materialIndex = resolveMaterialIndex(meshIndex); 66 | return new MeshNode(meshIndex, materialIndex); 67 | }).ToImmutableArray(); 68 | var matrix = ConvertMatrix(assimpNode.Transform); 69 | var position = PositionIn(matrix) * scalingFactor; 70 | var rotation = RotationIn(matrix); 71 | var scale = ScaleIn(matrix); 72 | 73 | return new GroupNodeModel( 74 | assimpNode.Name, children, meshNodes, position, rotation, scale); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Runtime/Code/Nodes/ModelConversion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f1d6b5afcd2ba1459bdbee73dd2d55f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Nodes/Models.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using UnityEngine; 3 | 4 | namespace At.Ac.FhStp.Import3D.Nodes 5 | { 6 | 7 | internal class MeshNode 8 | { 9 | 10 | public int MeshIndex { get; } 11 | 12 | public int MaterialIndex { get; } 13 | 14 | 15 | public MeshNode(int meshIndex, int materialIndex) 16 | { 17 | MeshIndex = meshIndex; 18 | MaterialIndex = materialIndex; 19 | } 20 | } 21 | 22 | internal class GroupNodeModel : INamedModel 23 | { 24 | public GroupNodeModel( 25 | string name, 26 | ImmutableArray children, 27 | ImmutableArray meshNodes, 28 | Vector3 position, Quaternion rotation, Vector3 scale) 29 | { 30 | Name = name; 31 | Children = children; 32 | MeshNodes = meshNodes; 33 | Position = position; 34 | Rotation = rotation; 35 | Scale = scale; 36 | } 37 | 38 | public ImmutableArray Children { get; } 39 | 40 | public ImmutableArray MeshNodes { get; } 41 | 42 | public Vector3 Position { get; } 43 | 44 | public Quaternion Rotation { get; } 45 | 46 | public Vector3 Scale { get; } 47 | 48 | public string Name { get; } 49 | } 50 | } -------------------------------------------------------------------------------- /Runtime/Code/Nodes/Models.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c438ee75b16c401469e11c62423fe84b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/ResourceCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using UnityEngine; 5 | 6 | namespace At.Ac.FhStp.Import3D 7 | { 8 | internal abstract class ResourceCache 9 | { 10 | private readonly Dictionary> importTasks = new(); 11 | 12 | private readonly Func> startImport; 13 | 14 | 15 | protected ResourceCache(Func> startImport) => 16 | this.startImport = startImport; 17 | 18 | 19 | internal Task Resolve(TKey key) 20 | { 21 | if (!importTasks.ContainsKey(key)) 22 | importTasks[key] = startImport(key); 23 | return importTasks[key]; 24 | } 25 | } 26 | 27 | internal class MeshCache : ResourceCache 28 | { 29 | public MeshCache(Func> startImport) 30 | : base(startImport) 31 | { 32 | } 33 | } 34 | 35 | internal class MaterialCache : ResourceCache 36 | { 37 | public MaterialCache(Func> startImport) 38 | : base(startImport) 39 | { 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Runtime/Code/ResourceCache.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41555ae83722914469ba6cde6cd22d80 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b1338ab3926f784d8bee13224004e6b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code/Scenes/Import.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using At.Ac.FhStp.Import3D.Nodes; 4 | using ComradeVanti.CSharpTools; 5 | using UnityEngine; 6 | using static At.Ac.FhStp.Import3D.Materials.Import; 7 | using AssimpScene = Assimp.Scene; 8 | using static At.Ac.FhStp.Import3D.Meshes.Import; 9 | using static At.Ac.FhStp.Import3D.Nodes.Import; 10 | 11 | namespace At.Ac.FhStp.Import3D.Scenes 12 | { 13 | internal static class Import 14 | { 15 | private static string MakeSceneNameFrom(string filePath) => 16 | Path.GetFileNameWithoutExtension(filePath); 17 | 18 | 19 | internal static float GetScalingFactor(this AssimpScene scene) => 20 | scene.Metadata["UnitScaleFactor"].DataAs() / 100f ?? 1; 21 | 22 | internal static async Task ImportScene( 23 | AssimpScene scene, 24 | string filePath, ImportConfig config) 25 | { 26 | var scalingFactor = scene.GetScalingFactor(); 27 | var meshImportConfig = new MeshImportConfig(scalingFactor); 28 | var groupNodeImportConfig = new GroupNodeImportConfig( 29 | scalingFactor, config.Hidden); 30 | 31 | var sceneName = config.SceneNameOverride 32 | .DefaultWith(() => MakeSceneNameFrom(filePath)); 33 | 34 | Task ImportMeshWithIndex(int index) => 35 | ImportMesh(scene.Meshes[index], meshImportConfig); 36 | 37 | 38 | Task ImportMaterialWithIndex(int index) => 39 | ImportMaterial(scene.Materials[index]); 40 | 41 | var meshCache = new MeshCache(ImportMeshWithIndex); 42 | var materialCache = new MaterialCache(ImportMaterialWithIndex); 43 | 44 | int ResolveMaterialIndex(int meshIndex) => 45 | scene.Meshes[meshIndex].MaterialIndex; 46 | 47 | var root = await ImportNode( 48 | scene.RootNode, ResolveMaterialIndex, 49 | meshCache, materialCache, groupNodeImportConfig); 50 | root.name = sceneName; 51 | config.Parent.Iter(it => root.transform.SetParent(it, false)); 52 | 53 | if (config.ActivateRoot) 54 | await DataCopy.CopyIsActive(true, root); 55 | 56 | return root; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Runtime/Code/Scenes/Import.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2cf6705f350711d499b0fc311092efac 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/TaskManagement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Dev.ComradeVanti; 5 | 6 | namespace At.Ac.FhStp.Import3D 7 | { 8 | internal static class TaskManagement 9 | { 10 | internal static readonly Task noResult = 11 | Task.FromResult(Nothing.atAll); 12 | 13 | internal static async Task InParallel(params Task[] tasks) 14 | { 15 | await Task.WhenAll(tasks); 16 | return Nothing.atAll; 17 | } 18 | 19 | internal static async Task<(T1, T2)> InParallel(Task t1, Task t2) 20 | { 21 | var v1 = await t1; 22 | var v2 = await t2; 23 | return (v1, v2); 24 | } 25 | 26 | internal static async Task<(T1, T2, T3)> InParallel(Task t1, Task t2, Task t3) 27 | { 28 | var v1 = await t1; 29 | var v2 = await t2; 30 | var v3 = await t3; 31 | return (v1, v2, v3); 32 | } 33 | 34 | internal static async Task> InParallel(IEnumerable> tasks) 35 | { 36 | var values = await Task.WhenAll(tasks); 37 | return values; 38 | } 39 | 40 | internal static async Task CalcAsync(Func func) 41 | { 42 | await Task.Yield(); 43 | return func(); 44 | } 45 | 46 | internal static async Task CalcAsync(Func> func) 47 | { 48 | await Task.Yield(); 49 | return await func(); 50 | } 51 | 52 | internal static async Task DoAsync(Action action) 53 | { 54 | await Task.Yield(); 55 | action(); 56 | return Nothing.atAll; 57 | } 58 | 59 | internal static async Task DoAsync(Func action) 60 | { 61 | await Task.Yield(); 62 | await action(); 63 | return Nothing.atAll; 64 | } 65 | 66 | 67 | internal static Task InBackground(Func func) => 68 | Task.Run(func); 69 | } 70 | } -------------------------------------------------------------------------------- /Runtime/Code/TaskManagement.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e882ed91e2fb0204fb447f5a092207f3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e10a5a9b28bfcde4198216204c2a8f5f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Code/Textures/DataCopy.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading.Tasks; 3 | using Dev.ComradeVanti; 4 | using UnityEngine; 5 | using UnityTexture = UnityEngine.Texture2D; 6 | using static At.Ac.FhStp.Import3D.TaskManagement; 7 | 8 | namespace At.Ac.FhStp.Import3D.Textures 9 | { 10 | internal static class DataCopy 11 | { 12 | internal static Task CopyTextureBytes( 13 | CompressedTextureModel model, UnityTexture texture) => 14 | DoAsync(() => texture.LoadImage(model.Bytes.ToArray())); 15 | 16 | internal static Task CopyTexturePixels( 17 | NonCompressedTextureModel model, UnityTexture texture) => 18 | DoAsync(() => 19 | { 20 | texture.SetPixels(model.Pixels.ToArray()); 21 | texture.Apply(); 22 | }); 23 | } 24 | } -------------------------------------------------------------------------------- /Runtime/Code/Textures/DataCopy.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af9fa95528480014f8e057fd6e04ba9d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Textures/Import.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using UnityEngine; 4 | using AssimpTexture = Assimp.EmbeddedTexture; 5 | using static At.Ac.FhStp.Import3D.Textures.ModelConversion; 6 | using static At.Ac.FhStp.Import3D.Textures.Instantiation; 7 | using static At.Ac.FhStp.Import3D.TaskManagement; 8 | using static At.Ac.FhStp.Import3D.Common.DataCopy; 9 | using static At.Ac.FhStp.Import3D.Textures.DataCopy; 10 | 11 | namespace At.Ac.FhStp.Import3D.Textures 12 | { 13 | internal static class Import 14 | { 15 | internal static async Task ImportTexture(AssimpTexture assimpTexture) 16 | { 17 | var model = await InBackground(() => ConvertToModel(assimpTexture)); 18 | switch (model) 19 | { 20 | case CompressedTextureModel compressed: 21 | { 22 | var texture = await MakeEmptyTexture2D(); 23 | await InParallel( 24 | CopyName(model, texture), 25 | CopyTextureBytes(compressed, texture)); 26 | return texture; 27 | } 28 | case NonCompressedTextureModel nonCompressed: 29 | { 30 | var texture = await MakeTexture2DWithSize( 31 | nonCompressed.Width, nonCompressed.Height); 32 | await InParallel( 33 | CopyName(model, texture), 34 | CopyTexturePixels(nonCompressed, texture)); 35 | return texture; 36 | } 37 | default: throw new ArgumentException("Unknown texture type!"); 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Runtime/Code/Textures/Import.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68d3be0f1d4cbd247b12bfbec41bd0fa 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Textures/Instantiation.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using UnityEngine; 3 | using UnityObject = UnityEngine.Object; 4 | using static At.Ac.FhStp.Import3D.TaskManagement; 5 | 6 | namespace At.Ac.FhStp.Import3D.Textures 7 | { 8 | internal static class Instantiation 9 | { 10 | internal static Task MakeTexture2DWithSize(int width, int height) => 11 | CalcAsync(() => new Texture2D(width, height)); 12 | 13 | internal static Task MakeEmptyTexture2D() => 14 | MakeTexture2DWithSize(0, 0); 15 | } 16 | } -------------------------------------------------------------------------------- /Runtime/Code/Textures/Instantiation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eddaacae49cbb0842bb47cdb4df789c8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Textures/ModelConversion.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using System.IO; 3 | using System.Linq; 4 | using UnityEngine; 5 | using AssimpEmbeddedTexture = Assimp.EmbeddedTexture; 6 | using AssimpTexel = Assimp.Texel; 7 | 8 | namespace At.Ac.FhStp.Import3D.Textures 9 | { 10 | internal static class ModelConversion 11 | { 12 | private static string FileNameOf(AssimpEmbeddedTexture assimpTexture) => 13 | Path.GetFileNameWithoutExtension(assimpTexture.Filename); 14 | 15 | private static float NormalizeByte01(byte b) => 16 | b / 255f; 17 | 18 | private static Color ConvertToModel(AssimpTexel texel) => 19 | new(NormalizeByte01(texel.R), 20 | NormalizeByte01(texel.G), 21 | NormalizeByte01(texel.B), 22 | NormalizeByte01(texel.A)); 23 | 24 | private static TextureModel ConvertCompressedTexture(AssimpEmbeddedTexture assimpTexture) 25 | { 26 | var name = FileNameOf(assimpTexture); 27 | 28 | // TODO: Use format hint to determine if texture type is supported 29 | var bytes = assimpTexture.CompressedData.ToImmutableArray(); 30 | return new CompressedTextureModel(name, bytes); 31 | } 32 | 33 | private static TextureModel ConvertNonCompressedTexture(AssimpEmbeddedTexture assimpTexture) 34 | { 35 | var name = FileNameOf(assimpTexture); 36 | 37 | var width = assimpTexture.Width; 38 | var height = assimpTexture.Height; 39 | var pixels = assimpTexture.NonCompressedData 40 | .Select(ConvertToModel) 41 | .ToImmutableArray(); 42 | return new NonCompressedTextureModel(name, width, height, pixels); 43 | } 44 | 45 | internal static TextureModel ConvertToModel(AssimpEmbeddedTexture assimpTexture) => 46 | assimpTexture.IsCompressed 47 | ? ConvertCompressedTexture(assimpTexture) 48 | : ConvertNonCompressedTexture(assimpTexture); 49 | } 50 | } -------------------------------------------------------------------------------- /Runtime/Code/Textures/ModelConversion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 820ce6664dc778b4882d273c50a0612c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Code/Textures/Models.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using UnityEngine; 3 | 4 | namespace At.Ac.FhStp.Import3D.Textures 5 | { 6 | internal abstract class TextureModel : INamedModel 7 | { 8 | protected TextureModel(string name) => 9 | Name = name; 10 | 11 | public string Name { get; } 12 | } 13 | 14 | internal class CompressedTextureModel : TextureModel 15 | { 16 | public CompressedTextureModel(string name, ImmutableArray bytes) 17 | : base(name) => Bytes = bytes; 18 | 19 | internal ImmutableArray Bytes { get; } 20 | } 21 | 22 | internal class NonCompressedTextureModel : TextureModel 23 | { 24 | public NonCompressedTextureModel(string name, int width, int height, ImmutableArray pixels) 25 | : base(name) 26 | { 27 | Width = width; 28 | Height = height; 29 | Pixels = pixels; 30 | } 31 | 32 | public int Width { get; } 33 | 34 | public int Height { get; } 35 | 36 | public ImmutableArray Pixels { get; } 37 | } 38 | } -------------------------------------------------------------------------------- /Runtime/Code/Textures/Models.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2fcdd1bd7178b1a499380f1607c29ae2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9d43517b47799449918237b122c9f6e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 175081c63f414f94c94a1e95c0ab1d2d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/AssimpNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fhstp/UnityImport3D/48021cff8b64b0c343fddfd49fa21c8f0281a1eb/Runtime/Plugins/Assimp/AssimpNet.dll -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/AssimpNet.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5e8964cf498e14a429ddf7f32dede07f 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 1 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51dc5f9b7d5130142954a67f7ba0bc21 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/android.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8b13613497bac6348a8e3e464afc7c15 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/android/arm64-v8a.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 78a91fb20314e4648b03cd3659492329 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/android/arm64-v8a/libassimp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fhstp/UnityImport3D/48021cff8b64b0c343fddfd49fa21c8f0281a1eb/Runtime/Plugins/Assimp/Native/android/arm64-v8a/libassimp.so -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/android/arm64-v8a/libassimp.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 393d49dbf9c3c8b46b923d88877d2af5 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 0 20 | Exclude Editor: 1 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude WebGL: 1 24 | Exclude Win: 1 25 | Exclude Win64: 1 26 | Exclude WindowsStoreApps: 1 27 | - first: 28 | Android: Android 29 | second: 30 | enabled: 1 31 | settings: 32 | CPU: ARM64 33 | - first: 34 | Any: 35 | second: 36 | enabled: 0 37 | settings: {} 38 | - first: 39 | Editor: Editor 40 | second: 41 | enabled: 0 42 | settings: 43 | CPU: AnyCPU 44 | DefaultValueInitialized: true 45 | OS: AnyOS 46 | - first: 47 | Standalone: Linux64 48 | second: 49 | enabled: 0 50 | settings: 51 | CPU: None 52 | - first: 53 | Standalone: OSXUniversal 54 | second: 55 | enabled: 0 56 | settings: 57 | CPU: x86 58 | - first: 59 | Standalone: Win 60 | second: 61 | enabled: 0 62 | settings: 63 | CPU: None 64 | - first: 65 | Standalone: Win64 66 | second: 67 | enabled: 0 68 | settings: 69 | CPU: None 70 | - first: 71 | WebGL: WebGL 72 | second: 73 | enabled: 0 74 | settings: {} 75 | - first: 76 | Windows Store Apps: WindowsStoreApps 77 | second: 78 | enabled: 0 79 | settings: 80 | CPU: AnyCPU 81 | DontProcess: false 82 | PlaceholderPath: 83 | SDK: AnySDK 84 | ScriptingBackend: AnyScriptingBackend 85 | userData: 86 | assetBundleName: 87 | assetBundleVariant: 88 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/android/armeabi-v7a.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 958c54e87f36711468497ba544e07c21 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/android/armeabi-v7a/libassimp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fhstp/UnityImport3D/48021cff8b64b0c343fddfd49fa21c8f0281a1eb/Runtime/Plugins/Assimp/Native/android/armeabi-v7a/libassimp.so -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/android/armeabi-v7a/libassimp.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ac27fb2a15fafc459ef2b0288f598ad 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 0 20 | Exclude Editor: 0 21 | Exclude Linux64: 0 22 | Exclude OSXUniversal: 0 23 | Exclude WebGL: 0 24 | Exclude Win: 0 25 | Exclude Win64: 0 26 | Exclude WindowsStoreApps: 1 27 | - first: 28 | Android: Android 29 | second: 30 | enabled: 1 31 | settings: 32 | CPU: ARMv7 33 | - first: 34 | Any: 35 | second: 36 | enabled: 1 37 | settings: {} 38 | - first: 39 | Editor: Editor 40 | second: 41 | enabled: 1 42 | settings: 43 | CPU: AnyCPU 44 | DefaultValueInitialized: true 45 | OS: AnyOS 46 | - first: 47 | Standalone: Linux64 48 | second: 49 | enabled: 1 50 | settings: 51 | CPU: None 52 | - first: 53 | Standalone: OSXUniversal 54 | second: 55 | enabled: 1 56 | settings: 57 | CPU: x86 58 | - first: 59 | Standalone: Win 60 | second: 61 | enabled: 1 62 | settings: 63 | CPU: None 64 | - first: 65 | Standalone: Win64 66 | second: 67 | enabled: 1 68 | settings: 69 | CPU: None 70 | - first: 71 | WebGL: WebGL 72 | second: 73 | enabled: 1 74 | settings: {} 75 | userData: 76 | assetBundleName: 77 | assetBundleVariant: 78 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/win.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1066d1abafbf8194db6f472960f6800b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/win/x86_64.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b0e98214a67cfb4f8c617427e30743e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/win/x86_64/assimp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fhstp/UnityImport3D/48021cff8b64b0c343fddfd49fa21c8f0281a1eb/Runtime/Plugins/Assimp/Native/win/x86_64/assimp.dll -------------------------------------------------------------------------------- /Runtime/Plugins/Assimp/Native/win/x86_64/assimp.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 873e56492b7077f4381de09ccca3abb1 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Android: 1 20 | Exclude Editor: 0 21 | Exclude Linux: 0 22 | Exclude Linux64: 0 23 | Exclude LinuxUniversal: 0 24 | Exclude OSXUniversal: 0 25 | Exclude WebGL: 1 26 | Exclude Win: 1 27 | Exclude Win64: 0 28 | - first: 29 | Android: Android 30 | second: 31 | enabled: 0 32 | settings: 33 | CPU: ARMv7 34 | - first: 35 | Any: 36 | second: 37 | enabled: 0 38 | settings: {} 39 | - first: 40 | Editor: Editor 41 | second: 42 | enabled: 1 43 | settings: 44 | CPU: x86_64 45 | DefaultValueInitialized: true 46 | OS: Windows 47 | - first: 48 | Facebook: Win 49 | second: 50 | enabled: 0 51 | settings: 52 | CPU: None 53 | - first: 54 | Facebook: Win64 55 | second: 56 | enabled: 0 57 | settings: 58 | CPU: AnyCPU 59 | - first: 60 | Standalone: Linux 61 | second: 62 | enabled: 1 63 | settings: 64 | CPU: x86 65 | - first: 66 | Standalone: Linux64 67 | second: 68 | enabled: 1 69 | settings: 70 | CPU: AnyCPU 71 | - first: 72 | Standalone: LinuxUniversal 73 | second: 74 | enabled: 1 75 | settings: 76 | CPU: AnyCPU 77 | - first: 78 | Standalone: OSXUniversal 79 | second: 80 | enabled: 1 81 | settings: 82 | CPU: AnyCPU 83 | - first: 84 | Standalone: Win 85 | second: 86 | enabled: 0 87 | settings: 88 | CPU: None 89 | - first: 90 | Standalone: Win64 91 | second: 92 | enabled: 1 93 | settings: 94 | CPU: AnyCPU 95 | userData: 96 | assetBundleName: 97 | assetBundleVariant: 98 | -------------------------------------------------------------------------------- /Runtime/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a1d370f58ef4a6b478fa3ad505922140 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Resources/ForceShaderToBeIncludedInBuild.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: ForceShaderToBeIncludedInBuild 11 | m_Shader: {fileID: 45, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 4 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 0} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | - _SpecGlossMap: 60 | m_Texture: {fileID: 0} 61 | m_Scale: {x: 1, y: 1} 62 | m_Offset: {x: 0, y: 0} 63 | m_Ints: [] 64 | m_Floats: 65 | - _BumpScale: 1 66 | - _Cutoff: 0.5 67 | - _DetailNormalMapScale: 1 68 | - _DstBlend: 0 69 | - _GlossMapScale: 1 70 | - _Glossiness: 0.5 71 | - _GlossyReflections: 1 72 | - _Metallic: 0 73 | - _Mode: 0 74 | - _OcclusionStrength: 1 75 | - _Parallax: 0.02 76 | - _SmoothnessTextureChannel: 0 77 | - _SpecularHighlights: 1 78 | - _SrcBlend: 1 79 | - _UVSec: 0 80 | - _ZWrite: 1 81 | m_Colors: 82 | - _Color: {r: 1, g: 1, b: 1, a: 1} 83 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 84 | - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} 85 | m_BuildTextureStacks: [] 86 | -------------------------------------------------------------------------------- /Runtime/Resources/ForceShaderToBeIncludedInBuild.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 049d73406e6448949b75ae9590a99e09 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/ImportTester.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8fe23beab8b678c49a56f8627062efcb 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/ImportTester/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 4 | and this project adheres 5 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## Upcoming 8 | 9 | ## 0.11.1 10 | 11 | ### Changed 12 | 13 | - Constant y-scale of 1 for floor 14 | 15 | ### Fixed 16 | 17 | - Floor scale not matching mesh 18 | 19 | ## 0.10.1 20 | 21 | ### Added 22 | 23 | - Floor with auto-tiling texture 24 | - Input listener 25 | - Manually reload models 26 | - Cycle through displayed models 27 | - Fit floor to displayed model -------------------------------------------------------------------------------- /Samples~/ImportTester/CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc6a902334384616949567c96f2b948c 3 | timeCreated: 1702891139 -------------------------------------------------------------------------------- /Samples~/ImportTester/Code.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cb44fc79018f0c7428280126162ed6af 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/At.Ac.FhStp.Import3D.ImportTester.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "At.Ac.FhStp.Import3D.ImportTester", 3 | "rootNamespace": "At.Ac.FhStp.Import3D.ImportTester", 4 | "references": [ 5 | "GUID:39e22437faf958a4fbeee0bc8495a90b" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [], 15 | "noEngineReferences": false 16 | } -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/At.Ac.FhStp.Import3D.ImportTester.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e499f173bc10fa43b0fc1b90df76056 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/AutoTileMaterial.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using UnityEngine; 4 | 5 | namespace At.Ac.FhStp.Import3D.ImportTester 6 | { 7 | [RequireComponent(typeof(Renderer))] 8 | [ExecuteInEditMode] 9 | public class AutoTileMaterial : MonoBehaviour 10 | { 11 | private static readonly int mainTexScaleKey = 12 | Shader.PropertyToID("_MainTex_ST"); 13 | 14 | [SerializeField] private float baseMeshSize; 15 | 16 | private MaterialPropertyBlock propertyBlock = null!; 17 | private new Renderer renderer = null!; 18 | 19 | 20 | private void AutoTile() 21 | { 22 | var size = transform.lossyScale * baseMeshSize; 23 | 24 | propertyBlock.SetVector(mainTexScaleKey, new Vector4(size.x, size.z, 0, 0)); 25 | renderer.SetPropertyBlock(propertyBlock); 26 | } 27 | 28 | private void Update() 29 | { 30 | AutoTile(); 31 | } 32 | 33 | private void OnEnable() 34 | { 35 | renderer = GetComponent(); 36 | propertyBlock = new MaterialPropertyBlock(); 37 | AutoTile(); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/AutoTileMaterial.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a39ca1dbce08b0c4088cd325f14122c1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/FloorFitter.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System; 4 | using System.Linq; 5 | using UnityEngine; 6 | 7 | namespace At.Ac.FhStp.Import3D.ImportTester 8 | { 9 | public class FloorFitter : MonoBehaviour 10 | { 11 | [SerializeField] private float floorMeshSize; 12 | 13 | private new Transform transform = null!; 14 | 15 | private void Awake() 16 | { 17 | transform = base.transform; 18 | } 19 | 20 | public void Fit(Transform? model) 21 | { 22 | var renderers = 23 | model 24 | ? model!.GetComponentsInChildren() 25 | : Array.Empty(); 26 | 27 | var meshBounds = renderers.Select(it => it.bounds); 28 | 29 | var bound = meshBounds.Aggregate(new Bounds(), (bounds, meshBound) => 30 | { 31 | bounds.Encapsulate(meshBound); 32 | return bounds; 33 | }); 34 | 35 | 36 | var scale = (bound.size + new Vector3(1, 0, 1)) / floorMeshSize; 37 | transform.localScale = new Vector3(scale.x, 1, scale.z); 38 | transform.position = bound.center - new Vector3(0, bound.size.y / 2f + 0.05f, 0); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/FloorFitter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0408594da7abc2a4683e3b96b77375ad 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/Importer.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using UnityEngine; 9 | using UnityEngine.Events; 10 | 11 | namespace At.Ac.FhStp.Import3D.ImportTester 12 | { 13 | public class Importer : MonoBehaviour 14 | { 15 | [SerializeField] private Transform modelParent = null!; 16 | [SerializeField] private UnityEvent modelsLoaded = new UnityEvent(); 17 | 18 | private CancellationTokenSource? importCancelSource; 19 | 20 | private void ClearCurrentModels() 21 | { 22 | for (var i = 0; i < modelParent.childCount; i++) 23 | { 24 | var child = modelParent.GetChild(i); 25 | Destroy(child.gameObject); 26 | } 27 | } 28 | 29 | private async Task ImportModels(CancellationToken ct) 30 | { 31 | var modelDirectory = Path.Combine( 32 | System.Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), 33 | "3D Objects/ImportTester"); 34 | 35 | if (!Directory.Exists(modelDirectory)) 36 | { 37 | Debug.LogError($"Directory \"{modelDirectory}\" does not exist!"); 38 | return; 39 | } 40 | 41 | var config = ImportConfig.Default with 42 | { 43 | ActivateRoot = false, 44 | }; 45 | 46 | async Task ImportSingle(string path) 47 | { 48 | try 49 | { 50 | var model = await Import.SingleAsync(path, config); 51 | 52 | if (ct.IsCancellationRequested) 53 | { 54 | DestroyImmediate(model); 55 | return null; 56 | } 57 | 58 | return model; 59 | } 60 | catch (Exception e) 61 | { 62 | Debug.LogError(e); 63 | } 64 | 65 | return null; 66 | } 67 | 68 | var filePaths = Directory.GetFiles(modelDirectory) 69 | .Where(Import.SupportsFileExtension); 70 | var importTasks = filePaths.Select(ImportSingle); 71 | var models = await Task.WhenAll(importTasks); 72 | 73 | ClearCurrentModels(); 74 | 75 | foreach (var model in models) 76 | { 77 | if (model == null) continue; 78 | model.transform.SetParent(modelParent, true); 79 | } 80 | 81 | modelsLoaded.Invoke(); 82 | } 83 | 84 | private void CancelImport() 85 | { 86 | importCancelSource?.Cancel(); 87 | importCancelSource = null; 88 | } 89 | 90 | public void StartImportingModels() 91 | { 92 | CancelImport(); 93 | 94 | importCancelSource = new CancellationTokenSource(); 95 | _ = ImportModels(importCancelSource.Token); 96 | } 97 | 98 | private void OnDisable() 99 | { 100 | CancelImport(); 101 | } 102 | 103 | private void Start() 104 | { 105 | StartImportingModels(); 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/Importer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 727a74c1848dfd940ad92393489260e7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/InputListener.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.Events; 3 | 4 | namespace At.Ac.FhStp.Import3D.ImportTester 5 | { 6 | public class InputListener : MonoBehaviour 7 | { 8 | [SerializeField] private UnityEvent modelSwitchInput = 9 | new UnityEvent(); 10 | [SerializeField] private UnityEvent reloadModelsInput = 11 | new UnityEvent(); 12 | 13 | private void Update() 14 | { 15 | if (Input.GetKeyDown(KeyCode.Q)) 16 | modelSwitchInput.Invoke(LinearDirection.Previous); 17 | else if (Input.GetKeyDown(KeyCode.E)) 18 | modelSwitchInput.Invoke(LinearDirection.Next); 19 | else if(Input.GetKeyDown(KeyCode.R)) 20 | reloadModelsInput.Invoke(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/InputListener.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 19365aea92fe2b242ba10d3dc00f9fa2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/ModelDisplayer.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using UnityEngine; 4 | using UnityEngine.Events; 5 | 6 | namespace At.Ac.FhStp.Import3D.ImportTester 7 | { 8 | public class ModelDisplayer : MonoBehaviour 9 | { 10 | [SerializeField] private Transform modelParent = null!; 11 | 12 | [SerializeField] private UnityEvent displayedModelChanged = 13 | new UnityEvent(); 14 | 15 | private int modelCount; 16 | private int? modelIndex; 17 | 18 | 19 | private void UpdateDisplayedModel() 20 | { 21 | if (modelIndex == null) return; 22 | 23 | var current = modelParent.GetChild(modelIndex.Value); 24 | current.gameObject.SetActive(true); 25 | 26 | displayedModelChanged.Invoke(current); 27 | } 28 | 29 | public void OnModelsLoaded() 30 | { 31 | modelCount = modelParent.childCount; 32 | modelIndex = modelCount > 0 ? 0 : null; 33 | 34 | if (modelIndex != null) 35 | UpdateDisplayedModel(); 36 | else 37 | displayedModelChanged.Invoke(null); 38 | } 39 | 40 | public void OnModelSwitchInput(LinearDirection direction) 41 | { 42 | if (modelIndex == null) return; 43 | 44 | var prev = modelParent.GetChild(modelIndex.Value); 45 | prev.gameObject.SetActive(false); 46 | 47 | modelIndex = (int) Mathf.Repeat(modelIndex.Value + (int) direction, modelCount); 48 | UpdateDisplayedModel(); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/ModelDisplayer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a040459e241ee7d4dbebf3b5817c300d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/Types.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | namespace At.Ac.FhStp.Import3D.ImportTester 4 | { 5 | public enum LinearDirection 6 | { 7 | Next = 1, 8 | Previous = -1 9 | } 10 | } -------------------------------------------------------------------------------- /Samples~/ImportTester/Code/Types.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 965a5c17a1764fa8b5b18c19484d0ab2 3 | timeCreated: 1702891263 -------------------------------------------------------------------------------- /Samples~/ImportTester/ImportTester.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &443370778 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 443370779} 135 | m_Layer: 0 136 | m_Name: Models 137 | m_TagString: Untagged 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 2147483647 141 | m_IsActive: 1 142 | --- !u!4 &443370779 143 | Transform: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 443370778} 149 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 150 | m_LocalPosition: {x: 0, y: 0, z: 0} 151 | m_LocalScale: {x: 1, y: 1, z: 1} 152 | m_ConstrainProportionsScale: 0 153 | m_Children: [] 154 | m_Father: {fileID: 0} 155 | m_RootOrder: 4 156 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 157 | --- !u!1 &480975986 158 | GameObject: 159 | m_ObjectHideFlags: 0 160 | m_CorrespondingSourceObject: {fileID: 0} 161 | m_PrefabInstance: {fileID: 0} 162 | m_PrefabAsset: {fileID: 0} 163 | serializedVersion: 6 164 | m_Component: 165 | - component: {fileID: 480975988} 166 | - component: {fileID: 480975987} 167 | m_Layer: 0 168 | m_Name: Directional Light 169 | m_TagString: Untagged 170 | m_Icon: {fileID: 0} 171 | m_NavMeshLayer: 0 172 | m_StaticEditorFlags: 0 173 | m_IsActive: 1 174 | --- !u!108 &480975987 175 | Light: 176 | m_ObjectHideFlags: 0 177 | m_CorrespondingSourceObject: {fileID: 0} 178 | m_PrefabInstance: {fileID: 0} 179 | m_PrefabAsset: {fileID: 0} 180 | m_GameObject: {fileID: 480975986} 181 | m_Enabled: 1 182 | serializedVersion: 10 183 | m_Type: 1 184 | m_Shape: 0 185 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 186 | m_Intensity: 1 187 | m_Range: 10 188 | m_SpotAngle: 30 189 | m_InnerSpotAngle: 21.80208 190 | m_CookieSize: 10 191 | m_Shadows: 192 | m_Type: 2 193 | m_Resolution: -1 194 | m_CustomResolution: -1 195 | m_Strength: 1 196 | m_Bias: 0.05 197 | m_NormalBias: 0.4 198 | m_NearPlane: 0.2 199 | m_CullingMatrixOverride: 200 | e00: 1 201 | e01: 0 202 | e02: 0 203 | e03: 0 204 | e10: 0 205 | e11: 1 206 | e12: 0 207 | e13: 0 208 | e20: 0 209 | e21: 0 210 | e22: 1 211 | e23: 0 212 | e30: 0 213 | e31: 0 214 | e32: 0 215 | e33: 1 216 | m_UseCullingMatrixOverride: 0 217 | m_Cookie: {fileID: 0} 218 | m_DrawHalo: 0 219 | m_Flare: {fileID: 0} 220 | m_RenderMode: 0 221 | m_CullingMask: 222 | serializedVersion: 2 223 | m_Bits: 4294967295 224 | m_RenderingLayerMask: 1 225 | m_Lightmapping: 4 226 | m_LightShadowCasterMode: 0 227 | m_AreaSize: {x: 1, y: 1} 228 | m_BounceIntensity: 1 229 | m_ColorTemperature: 6570 230 | m_UseColorTemperature: 0 231 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 232 | m_UseBoundingSphereOverride: 0 233 | m_UseViewFrustumForShadowCasterCull: 1 234 | m_ShadowRadius: 0 235 | m_ShadowAngle: 0 236 | --- !u!4 &480975988 237 | Transform: 238 | m_ObjectHideFlags: 0 239 | m_CorrespondingSourceObject: {fileID: 0} 240 | m_PrefabInstance: {fileID: 0} 241 | m_PrefabAsset: {fileID: 0} 242 | m_GameObject: {fileID: 480975986} 243 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 244 | m_LocalPosition: {x: 0, y: 3, z: 0} 245 | m_LocalScale: {x: 1, y: 1, z: 1} 246 | m_ConstrainProportionsScale: 0 247 | m_Children: [] 248 | m_Father: {fileID: 0} 249 | m_RootOrder: 2 250 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 251 | --- !u!1 &675400949 252 | GameObject: 253 | m_ObjectHideFlags: 0 254 | m_CorrespondingSourceObject: {fileID: 0} 255 | m_PrefabInstance: {fileID: 0} 256 | m_PrefabAsset: {fileID: 0} 257 | serializedVersion: 6 258 | m_Component: 259 | - component: {fileID: 675400952} 260 | - component: {fileID: 675400951} 261 | - component: {fileID: 675400950} 262 | m_Layer: 0 263 | m_Name: Main Camera 264 | m_TagString: MainCamera 265 | m_Icon: {fileID: 0} 266 | m_NavMeshLayer: 0 267 | m_StaticEditorFlags: 0 268 | m_IsActive: 1 269 | --- !u!81 &675400950 270 | AudioListener: 271 | m_ObjectHideFlags: 0 272 | m_CorrespondingSourceObject: {fileID: 0} 273 | m_PrefabInstance: {fileID: 0} 274 | m_PrefabAsset: {fileID: 0} 275 | m_GameObject: {fileID: 675400949} 276 | m_Enabled: 1 277 | --- !u!20 &675400951 278 | Camera: 279 | m_ObjectHideFlags: 0 280 | m_CorrespondingSourceObject: {fileID: 0} 281 | m_PrefabInstance: {fileID: 0} 282 | m_PrefabAsset: {fileID: 0} 283 | m_GameObject: {fileID: 675400949} 284 | m_Enabled: 1 285 | serializedVersion: 2 286 | m_ClearFlags: 1 287 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 288 | m_projectionMatrixMode: 1 289 | m_GateFitMode: 2 290 | m_FOVAxisMode: 0 291 | m_SensorSize: {x: 36, y: 24} 292 | m_LensShift: {x: 0, y: 0} 293 | m_FocalLength: 50 294 | m_NormalizedViewPortRect: 295 | serializedVersion: 2 296 | x: 0 297 | y: 0 298 | width: 1 299 | height: 1 300 | near clip plane: 0.3 301 | far clip plane: 1000 302 | field of view: 60 303 | orthographic: 0 304 | orthographic size: 5 305 | m_Depth: -1 306 | m_CullingMask: 307 | serializedVersion: 2 308 | m_Bits: 4294967295 309 | m_RenderingPath: -1 310 | m_TargetTexture: {fileID: 0} 311 | m_TargetDisplay: 0 312 | m_TargetEye: 3 313 | m_HDR: 1 314 | m_AllowMSAA: 1 315 | m_AllowDynamicResolution: 0 316 | m_ForceIntoRT: 0 317 | m_OcclusionCulling: 1 318 | m_StereoConvergence: 10 319 | m_StereoSeparation: 0.022 320 | --- !u!4 &675400952 321 | Transform: 322 | m_ObjectHideFlags: 0 323 | m_CorrespondingSourceObject: {fileID: 0} 324 | m_PrefabInstance: {fileID: 0} 325 | m_PrefabAsset: {fileID: 0} 326 | m_GameObject: {fileID: 675400949} 327 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 328 | m_LocalPosition: {x: 0, y: 1, z: -10} 329 | m_LocalScale: {x: 1, y: 1, z: 1} 330 | m_ConstrainProportionsScale: 0 331 | m_Children: [] 332 | m_Father: {fileID: 0} 333 | m_RootOrder: 1 334 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 335 | --- !u!1 &791141843 336 | GameObject: 337 | m_ObjectHideFlags: 0 338 | m_CorrespondingSourceObject: {fileID: 0} 339 | m_PrefabInstance: {fileID: 0} 340 | m_PrefabAsset: {fileID: 0} 341 | serializedVersion: 6 342 | m_Component: 343 | - component: {fileID: 791141844} 344 | - component: {fileID: 791141845} 345 | - component: {fileID: 791141846} 346 | - component: {fileID: 791141847} 347 | m_Layer: 0 348 | m_Name: Global 349 | m_TagString: Untagged 350 | m_Icon: {fileID: 0} 351 | m_NavMeshLayer: 0 352 | m_StaticEditorFlags: 0 353 | m_IsActive: 1 354 | --- !u!4 &791141844 355 | Transform: 356 | m_ObjectHideFlags: 0 357 | m_CorrespondingSourceObject: {fileID: 0} 358 | m_PrefabInstance: {fileID: 0} 359 | m_PrefabAsset: {fileID: 0} 360 | m_GameObject: {fileID: 791141843} 361 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 362 | m_LocalPosition: {x: 0, y: 0, z: 0} 363 | m_LocalScale: {x: 1, y: 1, z: 1} 364 | m_ConstrainProportionsScale: 0 365 | m_Children: [] 366 | m_Father: {fileID: 0} 367 | m_RootOrder: 0 368 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 369 | --- !u!114 &791141845 370 | MonoBehaviour: 371 | m_ObjectHideFlags: 0 372 | m_CorrespondingSourceObject: {fileID: 0} 373 | m_PrefabInstance: {fileID: 0} 374 | m_PrefabAsset: {fileID: 0} 375 | m_GameObject: {fileID: 791141843} 376 | m_Enabled: 1 377 | m_EditorHideFlags: 0 378 | m_Script: {fileID: 11500000, guid: 19365aea92fe2b242ba10d3dc00f9fa2, type: 3} 379 | m_Name: 380 | m_EditorClassIdentifier: 381 | modelSwitchInput: 382 | m_PersistentCalls: 383 | m_Calls: 384 | - m_Target: {fileID: 791141847} 385 | m_TargetAssemblyTypeName: At.Ac.FhStp.Import3D.ImportTester.ModelDisplayer, 386 | At.Ac.FhStp.Import3D.ImportTester 387 | m_MethodName: OnModelSwitchInput 388 | m_Mode: 0 389 | m_Arguments: 390 | m_ObjectArgument: {fileID: 0} 391 | m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine 392 | m_IntArgument: 0 393 | m_FloatArgument: 0 394 | m_StringArgument: 395 | m_BoolArgument: 0 396 | m_CallState: 2 397 | reloadModelsInput: 398 | m_PersistentCalls: 399 | m_Calls: 400 | - m_Target: {fileID: 791141846} 401 | m_TargetAssemblyTypeName: At.Ac.FhStp.Import3D.ImportTester.Importer, At.Ac.FhStp.Import3D.ImportTester 402 | m_MethodName: StartImportingModels 403 | m_Mode: 1 404 | m_Arguments: 405 | m_ObjectArgument: {fileID: 0} 406 | m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine 407 | m_IntArgument: 0 408 | m_FloatArgument: 0 409 | m_StringArgument: 410 | m_BoolArgument: 0 411 | m_CallState: 2 412 | --- !u!114 &791141846 413 | MonoBehaviour: 414 | m_ObjectHideFlags: 0 415 | m_CorrespondingSourceObject: {fileID: 0} 416 | m_PrefabInstance: {fileID: 0} 417 | m_PrefabAsset: {fileID: 0} 418 | m_GameObject: {fileID: 791141843} 419 | m_Enabled: 1 420 | m_EditorHideFlags: 0 421 | m_Script: {fileID: 11500000, guid: 727a74c1848dfd940ad92393489260e7, type: 3} 422 | m_Name: 423 | m_EditorClassIdentifier: 424 | modelParent: {fileID: 443370779} 425 | modelsLoaded: 426 | m_PersistentCalls: 427 | m_Calls: 428 | - m_Target: {fileID: 791141847} 429 | m_TargetAssemblyTypeName: At.Ac.FhStp.Import3D.ImportTester.ModelDisplayer, 430 | At.Ac.FhStp.Import3D.ImportTester 431 | m_MethodName: OnModelsLoaded 432 | m_Mode: 1 433 | m_Arguments: 434 | m_ObjectArgument: {fileID: 0} 435 | m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine 436 | m_IntArgument: 0 437 | m_FloatArgument: 0 438 | m_StringArgument: 439 | m_BoolArgument: 0 440 | m_CallState: 2 441 | --- !u!114 &791141847 442 | MonoBehaviour: 443 | m_ObjectHideFlags: 0 444 | m_CorrespondingSourceObject: {fileID: 0} 445 | m_PrefabInstance: {fileID: 0} 446 | m_PrefabAsset: {fileID: 0} 447 | m_GameObject: {fileID: 791141843} 448 | m_Enabled: 1 449 | m_EditorHideFlags: 0 450 | m_Script: {fileID: 11500000, guid: a040459e241ee7d4dbebf3b5817c300d, type: 3} 451 | m_Name: 452 | m_EditorClassIdentifier: 453 | modelParent: {fileID: 443370779} 454 | displayedModelChanged: 455 | m_PersistentCalls: 456 | m_Calls: 457 | - m_Target: {fileID: 1713683997} 458 | m_TargetAssemblyTypeName: At.Ac.FhStp.Import3D.ImportTester.FloorFitter, 459 | At.Ac.FhStp.Import3D.ImportTester 460 | m_MethodName: Fit 461 | m_Mode: 0 462 | m_Arguments: 463 | m_ObjectArgument: {fileID: 0} 464 | m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine 465 | m_IntArgument: 0 466 | m_FloatArgument: 0 467 | m_StringArgument: 468 | m_BoolArgument: 0 469 | m_CallState: 2 470 | --- !u!1 &1713683991 471 | GameObject: 472 | m_ObjectHideFlags: 0 473 | m_CorrespondingSourceObject: {fileID: 0} 474 | m_PrefabInstance: {fileID: 0} 475 | m_PrefabAsset: {fileID: 0} 476 | serializedVersion: 6 477 | m_Component: 478 | - component: {fileID: 1713683995} 479 | - component: {fileID: 1713683994} 480 | - component: {fileID: 1713683993} 481 | - component: {fileID: 1713683996} 482 | - component: {fileID: 1713683997} 483 | m_Layer: 0 484 | m_Name: Floor 485 | m_TagString: Untagged 486 | m_Icon: {fileID: 0} 487 | m_NavMeshLayer: 0 488 | m_StaticEditorFlags: 0 489 | m_IsActive: 1 490 | --- !u!23 &1713683993 491 | MeshRenderer: 492 | m_ObjectHideFlags: 0 493 | m_CorrespondingSourceObject: {fileID: 0} 494 | m_PrefabInstance: {fileID: 0} 495 | m_PrefabAsset: {fileID: 0} 496 | m_GameObject: {fileID: 1713683991} 497 | m_Enabled: 1 498 | m_CastShadows: 1 499 | m_ReceiveShadows: 1 500 | m_DynamicOccludee: 1 501 | m_StaticShadowCaster: 0 502 | m_MotionVectors: 1 503 | m_LightProbeUsage: 1 504 | m_ReflectionProbeUsage: 1 505 | m_RayTracingMode: 2 506 | m_RayTraceProcedural: 0 507 | m_RenderingLayerMask: 1 508 | m_RendererPriority: 0 509 | m_Materials: 510 | - {fileID: 2100000, guid: bc8c05260bb96a8439f1fe042b87e01b, type: 2} 511 | m_StaticBatchInfo: 512 | firstSubMesh: 0 513 | subMeshCount: 0 514 | m_StaticBatchRoot: {fileID: 0} 515 | m_ProbeAnchor: {fileID: 0} 516 | m_LightProbeVolumeOverride: {fileID: 0} 517 | m_ScaleInLightmap: 1 518 | m_ReceiveGI: 1 519 | m_PreserveUVs: 0 520 | m_IgnoreNormalsForChartDetection: 0 521 | m_ImportantGI: 0 522 | m_StitchLightmapSeams: 1 523 | m_SelectedEditorRenderState: 3 524 | m_MinimumChartSize: 4 525 | m_AutoUVMaxDistance: 0.5 526 | m_AutoUVMaxAngle: 89 527 | m_LightmapParameters: {fileID: 0} 528 | m_SortingLayerID: 0 529 | m_SortingLayer: 0 530 | m_SortingOrder: 0 531 | m_AdditionalVertexStreams: {fileID: 0} 532 | --- !u!33 &1713683994 533 | MeshFilter: 534 | m_ObjectHideFlags: 0 535 | m_CorrespondingSourceObject: {fileID: 0} 536 | m_PrefabInstance: {fileID: 0} 537 | m_PrefabAsset: {fileID: 0} 538 | m_GameObject: {fileID: 1713683991} 539 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} 540 | --- !u!4 &1713683995 541 | Transform: 542 | m_ObjectHideFlags: 0 543 | m_CorrespondingSourceObject: {fileID: 0} 544 | m_PrefabInstance: {fileID: 0} 545 | m_PrefabAsset: {fileID: 0} 546 | m_GameObject: {fileID: 1713683991} 547 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 548 | m_LocalPosition: {x: 0, y: 0, z: 0} 549 | m_LocalScale: {x: 0.1, y: 1, z: 0.1} 550 | m_ConstrainProportionsScale: 0 551 | m_Children: [] 552 | m_Father: {fileID: 0} 553 | m_RootOrder: 3 554 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 555 | --- !u!114 &1713683996 556 | MonoBehaviour: 557 | m_ObjectHideFlags: 0 558 | m_CorrespondingSourceObject: {fileID: 0} 559 | m_PrefabInstance: {fileID: 0} 560 | m_PrefabAsset: {fileID: 0} 561 | m_GameObject: {fileID: 1713683991} 562 | m_Enabled: 1 563 | m_EditorHideFlags: 0 564 | m_Script: {fileID: 11500000, guid: a39ca1dbce08b0c4088cd325f14122c1, type: 3} 565 | m_Name: 566 | m_EditorClassIdentifier: 567 | baseMeshSize: 10 568 | --- !u!114 &1713683997 569 | MonoBehaviour: 570 | m_ObjectHideFlags: 0 571 | m_CorrespondingSourceObject: {fileID: 0} 572 | m_PrefabInstance: {fileID: 0} 573 | m_PrefabAsset: {fileID: 0} 574 | m_GameObject: {fileID: 1713683991} 575 | m_Enabled: 1 576 | m_EditorHideFlags: 0 577 | m_Script: {fileID: 11500000, guid: 0408594da7abc2a4683e3b96b77375ad, type: 3} 578 | m_Name: 579 | m_EditorClassIdentifier: 580 | floorMeshSize: 10 581 | -------------------------------------------------------------------------------- /Samples~/ImportTester/ImportTester.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1837075bb2b1dd74daa33632ed104222 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Pink Checkers.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 8 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Pink Checkers 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ValidKeywords: [] 13 | m_InvalidKeywords: [] 14 | m_LightmapFlags: 4 15 | m_EnableInstancingVariants: 0 16 | m_DoubleSidedGI: 0 17 | m_CustomRenderQueue: -1 18 | stringTagMap: {} 19 | disabledShaderPasses: [] 20 | m_SavedProperties: 21 | serializedVersion: 3 22 | m_TexEnvs: 23 | - _BumpMap: 24 | m_Texture: {fileID: 0} 25 | m_Scale: {x: 1, y: 1} 26 | m_Offset: {x: 0, y: 0} 27 | - _DetailAlbedoMap: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | - _DetailMask: 32 | m_Texture: {fileID: 0} 33 | m_Scale: {x: 1, y: 1} 34 | m_Offset: {x: 0, y: 0} 35 | - _DetailNormalMap: 36 | m_Texture: {fileID: 0} 37 | m_Scale: {x: 1, y: 1} 38 | m_Offset: {x: 0, y: 0} 39 | - _EmissionMap: 40 | m_Texture: {fileID: 0} 41 | m_Scale: {x: 1, y: 1} 42 | m_Offset: {x: 0, y: 0} 43 | - _MainTex: 44 | m_Texture: {fileID: 2800000, guid: fbee57dd1fb44c54bbb2737ee1875637, type: 3} 45 | m_Scale: {x: 1, y: 1} 46 | m_Offset: {x: 0, y: 0} 47 | - _MetallicGlossMap: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | - _OcclusionMap: 52 | m_Texture: {fileID: 0} 53 | m_Scale: {x: 1, y: 1} 54 | m_Offset: {x: 0, y: 0} 55 | - _ParallaxMap: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | m_Ints: [] 60 | m_Floats: 61 | - _BumpScale: 1 62 | - _Cutoff: 0.5 63 | - _DetailNormalMapScale: 1 64 | - _DstBlend: 0 65 | - _GlossMapScale: 1 66 | - _Glossiness: 0.05 67 | - _GlossyReflections: 1 68 | - _Metallic: 0 69 | - _Mode: 0 70 | - _OcclusionStrength: 1 71 | - _Parallax: 0.02 72 | - _SmoothnessTextureChannel: 0 73 | - _SpecularHighlights: 1 74 | - _SrcBlend: 1 75 | - _UVSec: 0 76 | - _ZWrite: 1 77 | m_Colors: 78 | - _Color: {r: 1, g: 1, b: 1, a: 1} 79 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 80 | m_BuildTextureStacks: [] 81 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Pink Checkers.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc8c05260bb96a8439f1fe042b87e01b 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/ImportTester/Pink Checkers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fhstp/UnityImport3D/48021cff8b64b0c343fddfd49fa21c8f0281a1eb/Samples~/ImportTester/Pink Checkers.png -------------------------------------------------------------------------------- /Samples~/ImportTester/Pink Checkers.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fbee57dd1fb44c54bbb2737ee1875637 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 0 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 0 40 | wrapV: 0 41 | wrapW: 0 42 | nPOTScale: 1 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 0 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 0 55 | spriteTessellationDetail: -1 56 | textureType: 0 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 32 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | spriteSheet: 105 | serializedVersion: 2 106 | sprites: [] 107 | outline: [] 108 | physicsShape: [] 109 | bones: [] 110 | spriteID: 111 | internalID: 0 112 | vertices: [] 113 | indices: 114 | edges: [] 115 | weights: [] 116 | secondaryTextures: [] 117 | nameFileIdTable: {} 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 0 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | -------------------------------------------------------------------------------- /Samples~/ImportTester/README.md: -------------------------------------------------------------------------------- 1 | # Import Tester Sample 2 | 3 | In this sample you can test the importing functionality 4 | of the package as well as get to know the API. 5 | 6 | ## Usage 7 | 8 | On start-up the sample will load all models inside 9 | `[User-folder]/3D Models/ImportTester`. You also manually 10 | reload models by pressing [R]. 11 | 12 | You can cycle through the loaded models using the [Q] and 13 | [E] keys. 14 | 15 | -------------------------------------------------------------------------------- /Samples~/ImportTester/README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b413415eecb04a539b89da82fee8c50e 3 | timeCreated: 1702888745 -------------------------------------------------------------------------------- /Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c18e72a8e5ff4c34d9e3d41413772c88 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests/AssimpMeshBuilding.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Assimp; 4 | using AssimpMesh = Assimp.Mesh; 5 | 6 | namespace At.Ac.FhStp.Import3D 7 | { 8 | internal static class AssimpMeshBuilding 9 | { 10 | internal static AssimpMesh MakeEmptyMesh(string name) => new(name); 11 | 12 | internal static AssimpMesh MakePointMesh( 13 | string name, IEnumerable points) 14 | { 15 | var mesh = new AssimpMesh(name, PrimitiveType.Point); 16 | mesh.Vertices.AddRange(points); 17 | return mesh; 18 | } 19 | 20 | internal static AssimpMesh MakeTriangleMesh( 21 | string name, IEnumerable vertices, 22 | IEnumerable<(int, int, int)> triangles) 23 | { 24 | var mesh = new AssimpMesh(name, PrimitiveType.Triangle); 25 | var faces = triangles.Select(tri => new Face(new[] 26 | { 27 | tri.Item1, tri.Item2, tri.Item3 28 | })); 29 | 30 | mesh.Vertices.AddRange(vertices); 31 | mesh.Faces.AddRange(faces); 32 | return mesh; 33 | } 34 | 35 | internal static AssimpMesh Make01Quad(string name) => 36 | MakeTriangleMesh(name, new[] 37 | { 38 | new Vector3D(0, 0, 0), 39 | new Vector3D(0, 1, 0), 40 | new Vector3D(1, 1, 0), 41 | new Vector3D(1, 0, 0) 42 | }, new[] 43 | { 44 | (0, 1, 2), 45 | (2, 3, 0) 46 | }); 47 | 48 | internal static AssimpMesh MakeQuadWithNormals( 49 | string name, Vector3D normal1, Vector3D normal2, Vector3D normal3, 50 | Vector3D normal4) 51 | { 52 | var mesh = Make01Quad(name); 53 | mesh.Normals.AddRange(new[] {normal1, normal2, normal3, normal4}); 54 | return mesh; 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Tests/AssimpMeshBuilding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b47f648fcb80a8b4193cd380b5ab0153 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests/AssimpNodeBuilding.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using AssimpNode = Assimp.Node; 4 | 5 | namespace At.Ac.FhStp.Import3D 6 | { 7 | internal static class AssimpNodeBuilding 8 | { 9 | internal static AssimpNode MakeTree( 10 | string name, 11 | IEnumerable meshIndices, 12 | IEnumerable children) 13 | { 14 | var node = new AssimpNode(name); 15 | foreach (var child in children) node.Children.Add(child); 16 | node.MeshIndices.AddRange(meshIndices); 17 | return node; 18 | } 19 | 20 | internal static AssimpNode MakeTree( 21 | string name, 22 | IEnumerable children) => 23 | MakeTree(name, Enumerable.Empty(), children); 24 | 25 | internal static AssimpNode MakeLeaf(string name, IEnumerable meshIndices) => 26 | MakeTree(name, meshIndices, Enumerable.Empty()); 27 | 28 | internal static AssimpNode MakeLeaf(string name) => 29 | MakeLeaf(name, Enumerable.Empty()); 30 | } 31 | } -------------------------------------------------------------------------------- /Tests/AssimpNodeBuilding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3d78c6b4574c515429142acc422b45e0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests/AssimpTextureBuilding.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UnityEngine; 3 | using AssimpTexel = Assimp.Texel; 4 | using AssimpEmbeddedTexture = Assimp.EmbeddedTexture; 5 | 6 | namespace At.Ac.FhStp.Import3D 7 | { 8 | internal static class AssimpTextureBuilding 9 | { 10 | private static AssimpTexel[] MakeSolidTexels(int width, int height, AssimpTexel texel) => 11 | Enumerable.Repeat(texel, width * height).ToArray(); 12 | 13 | private static Color[] MakeSolidPixels(int width, int height, Color color) => 14 | Enumerable.Repeat(color, width * height).ToArray(); 15 | 16 | private static byte[] MakePngBytes( 17 | int width, int height, Color color) 18 | { 19 | var tex = new Texture2D(width, height, TextureFormat.RGB24, false); 20 | var pixels = MakeSolidPixels(width, height, color); 21 | tex.SetPixels(pixels); 22 | var bytes = tex.EncodeToPNG(); 23 | Object.Destroy(tex); 24 | return bytes; 25 | } 26 | 27 | internal static AssimpEmbeddedTexture MakeSolidColorTexture(string name, int width, int height, 28 | AssimpTexel texel) 29 | { 30 | var texels = MakeSolidTexels(width, height, texel); 31 | return new AssimpEmbeddedTexture(width, height, texels, name); 32 | } 33 | 34 | internal static AssimpEmbeddedTexture MakeSolidBlackTexture(string name, int width, int height) => 35 | MakeSolidColorTexture(name, width, height, new AssimpTexel(0, 0, 0, 255)); 36 | 37 | internal static AssimpEmbeddedTexture MakePngFromBytes(string name, byte[] bytes) => new("png", bytes, name); 38 | 39 | internal static AssimpEmbeddedTexture MakeColorPng( 40 | string name, int width, int height, Color color) 41 | { 42 | var bytes = MakePngBytes(width, height, color); 43 | return MakePngFromBytes(name, bytes); 44 | } 45 | 46 | internal static AssimpEmbeddedTexture Make1x1Png(string name, Color color) => 47 | MakeColorPng(name, 1, 1, color); 48 | } 49 | } -------------------------------------------------------------------------------- /Tests/AssimpTextureBuilding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 88a3381bbc000b04aa4ac435be6acf2d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests/At.Ac.FhStp.Import3D.Tests.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "At.Ac.FhStp.Import3D.Tests", 3 | "rootNamespace": "At.Ac.FhStp.Import3D", 4 | "references": [ 5 | "UnityEditor.TestRunner", 6 | "UnityEngine.TestRunner", 7 | "At.Ac.FhStp.Import3D" 8 | ], 9 | "includePlatforms": [], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": true, 13 | "precompiledReferences": [ 14 | "nunit.framework.dll", 15 | "AssimpNet.dll", 16 | "System.Collections.Immutable.dll", 17 | "System.Memory.dll" 18 | ], 19 | "autoReferenced": false, 20 | "defineConstraints": [ 21 | "UNITY_INCLUDE_TESTS" 22 | ], 23 | "versionDefines": [], 24 | "noEngineReferences": false 25 | } -------------------------------------------------------------------------------- /Tests/At.Ac.FhStp.Import3D.Tests.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd7f77fc11df2fe419406b5539e99887 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Tests/CompressedTextureImportTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using NUnit.Framework; 3 | using UnityEngine; 4 | using UnityEngine.TestTools; 5 | using static At.Ac.FhStp.Import3D.AssimpTextureBuilding; 6 | using static At.Ac.FhStp.Import3D.Textures.Import; 7 | 8 | namespace At.Ac.FhStp.Import3D 9 | { 10 | [RequiresPlayMode] 11 | public class CompressedTextureImportTests 12 | { 13 | [Test] 14 | public async Task Texture_Name_Is_Assimp_Name() 15 | { 16 | const string name = "image"; 17 | var assimpTexture = Make1x1Png(name, Color.black); 18 | 19 | var texture = await ImportTexture(assimpTexture); 20 | 21 | Assert.AreEqual(name, texture.name); 22 | } 23 | 24 | [Test] 25 | public async Task Texture_Size_Comes_From_Assimp_Bytes() 26 | { 27 | const int width = 2; 28 | const int height = 4; 29 | var assimpTexture = MakeColorPng("image", width, height, Color.black); 30 | 31 | var texture = await ImportTexture(assimpTexture); 32 | 33 | Assert.AreEqual(width, texture.width, "Width"); 34 | Assert.AreEqual(height, texture.height, "Height"); 35 | } 36 | 37 | [Test] 38 | public async Task Texture_Pixels_Come_From_Assimp_Bytes() 39 | { 40 | const int width = 1; 41 | const int height = 1; 42 | var assimpTexture = MakeColorPng("image", width, height, Color.green); 43 | 44 | var texture = await ImportTexture(assimpTexture); 45 | 46 | Assert.AreEqual(Color.green, texture.GetPixel(0, 0)); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Tests/CompressedTextureImportTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad8f1f394d144f044acee2733629cb6d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests/GroupNodeImportTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using NUnit.Framework; 5 | using UnityEngine; 6 | using UnityEngine.TestTools; 7 | using static At.Ac.FhStp.Import3D.AssimpNodeBuilding; 8 | using static At.Ac.FhStp.Import3D.Nodes.Import; 9 | 10 | namespace At.Ac.FhStp.Import3D 11 | { 12 | [RequiresPlayMode] 13 | public class GroupNodeImportTests 14 | { 15 | private readonly Mesh mesh0; 16 | private readonly Mesh mesh1; 17 | private readonly MeshCache meshCache; 18 | private readonly MaterialCache materialCache; 19 | 20 | public GroupNodeImportTests() 21 | { 22 | mesh0 = new Mesh {name = "Mesh 0"}; 23 | mesh1 = new Mesh {name = "Mesh 1"}; 24 | meshCache = new MeshCache(i => 25 | { 26 | return i switch 27 | { 28 | 0 => Task.FromResult(mesh0), 29 | 1 => Task.FromResult(mesh1), 30 | _ => throw new ArgumentException() 31 | }; 32 | }); 33 | materialCache = new MaterialCache( 34 | _ => Task.FromResult(new Material(Shader.Find("Standard")))); 35 | } 36 | 37 | private static int ResolveMaterialIndex(int meshIndex) => 0; 38 | 39 | 40 | [Test] 41 | public async Task GroupNode_Name_Is_Assimp_Name() 42 | { 43 | var assimpNode = MakeLeaf("My Root"); 44 | 45 | var node = await ImportNode( 46 | assimpNode, ResolveMaterialIndex, meshCache, 47 | materialCache, GroupNodeImportConfig.Default); 48 | 49 | Assert.AreEqual(assimpNode.Name, node.name); 50 | } 51 | 52 | [Test] 53 | public async Task GroupNode_Tree_Has_Same_Structure_As_Assimp() 54 | { 55 | var assimpNode = 56 | MakeTree("A", new[] 57 | { 58 | MakeLeaf("B"), 59 | MakeTree("C", new[] 60 | { 61 | MakeLeaf("D") 62 | }) 63 | }); 64 | 65 | var a = await ImportNode( 66 | assimpNode, ResolveMaterialIndex, 67 | meshCache, materialCache, GroupNodeImportConfig.Default); 68 | Assert.True(a, "A"); 69 | AssertChildCount(a, 2); 70 | AssertForChild(a, 1, c => AssertChildCount(c, 1)); 71 | } 72 | 73 | [Test] 74 | public async Task GroupNode_Tree_Has_Same_MeshNodes_As_Assimp() 75 | { 76 | var assimpNode = 77 | MakeTree("A", new[] 78 | { 79 | 0 80 | }, new[] 81 | { 82 | MakeLeaf("B", new[] 83 | { 84 | 0, 1 85 | }) 86 | }); 87 | 88 | var a = await ImportNode( 89 | assimpNode, ResolveMaterialIndex, meshCache, 90 | materialCache, GroupNodeImportConfig.Default); 91 | Assert.True(a, "A"); 92 | AssertChildCount(a, 2); 93 | 94 | AssertForChild(a, 1, meshNodeA0 => 95 | AssertIsMeshNodeWith(meshNodeA0, mesh0)); 96 | AssertForChild(a, 0, b => 97 | { 98 | AssertChildCount(b, 2); 99 | AssertForChild(b, 0, meshNodeB0 => 100 | AssertIsMeshNodeWith(meshNodeB0, mesh0)); 101 | AssertForChild(b, 1, meshNodeB1 => 102 | AssertIsMeshNodeWith(meshNodeB1, mesh1)); 103 | }); 104 | } 105 | 106 | private static void AssertForChild(GameObject g, int index, Action assert) 107 | { 108 | var child = g.transform.GetChild(index); 109 | Assert.True(child, $"{g.name} has child at {index}"); 110 | assert(child.gameObject); 111 | } 112 | 113 | private static void AssertChildCount(GameObject g, int count) => 114 | Assert.AreEqual(count, g.transform.childCount, $"{g.name} child-count"); 115 | 116 | private static void AssertIsMeshNodeWith(GameObject g, Mesh mesh) 117 | { 118 | var meshFilter = g.GetComponent(); 119 | Assert.True(meshFilter, $"{g.name} is mesh-node"); 120 | Assert.AreEqual(mesh, meshFilter.mesh); 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /Tests/GroupNodeImportTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb3e69173f753a844bc8991f2c1dbb86 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests/MaterialImportTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using NUnit.Framework; 3 | using UnityEngine.TestTools; 4 | using static At.Ac.FhStp.Import3D.Materials.Import; 5 | 6 | namespace At.Ac.FhStp.Import3D 7 | { 8 | [RequiresPlayMode] 9 | public class MaterialImportTests 10 | { 11 | 12 | [Test] 13 | public async Task Material_Name_Is_Assimp_Name() 14 | { 15 | var assimpMaterial = new Assimp.Material 16 | { 17 | Name = "MyMaterial" 18 | }; 19 | 20 | var material = await ImportMaterial(assimpMaterial); 21 | 22 | Assert.AreEqual(assimpMaterial.Name, material.name); 23 | } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /Tests/MaterialImportTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a522f3ff099a43099e3b166b9af2c63f 3 | timeCreated: 1677574763 -------------------------------------------------------------------------------- /Tests/MeshImportTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading.Tasks; 3 | using Assimp; 4 | using NUnit.Framework; 5 | using UnityEngine; 6 | using UnityEngine.TestTools; 7 | using static At.Ac.FhStp.Import3D.AssimpMeshBuilding; 8 | using static At.Ac.FhStp.Import3D.Meshes.Import; 9 | 10 | namespace At.Ac.FhStp.Import3D 11 | { 12 | [RequiresPlayMode] 13 | public class MeshImportTests 14 | { 15 | [Test] 16 | public async Task Mesh_Name_Is_Assimp_Name() 17 | { 18 | const string name = "Super mesh"; 19 | var assimpMesh = MakeEmptyMesh(name); 20 | 21 | var mesh = await ImportMesh(assimpMesh, MeshImportConfig.Default); 22 | 23 | Assert.AreEqual(name, mesh.name); 24 | } 25 | 26 | [Test] 27 | public async Task Mesh_Vertices_Are_Converted_Assimp_Vertices() 28 | { 29 | var assimpMesh = MakePointMesh("My mesh", new[] 30 | { 31 | new Vector3D(1, 2, 3), 32 | new Vector3D(4.5f, -6.7f, -8) 33 | }); 34 | 35 | var mesh = await ImportMesh(assimpMesh, MeshImportConfig.Default); 36 | var vertices = mesh.vertices; 37 | 38 | Assert.AreEqual(2, vertices.Length, "Length"); 39 | Assert.AreEqual(new Vector3(1, 2, 3), vertices[0], "Vertex 1"); 40 | Assert.AreEqual(new Vector3(4.5f, -6.7f, -8), vertices[1], "Vertex 2"); 41 | } 42 | 43 | [Test] 44 | public async Task Mesh_Triangles_Are_Assimp_Triangles() 45 | { 46 | var assimpMesh = MakeTriangleMesh( 47 | "My mesh", 48 | new[] 49 | { 50 | new Vector3D(1, 0, 0), 51 | new Vector3D(0, 1, 0), 52 | new Vector3D(0, 0, 1), 53 | new Vector3D(0, 0, 0) 54 | }, new[] 55 | { 56 | (0, 1, 2), 57 | (1, 2, 3) 58 | }); 59 | 60 | var mesh = await ImportMesh(assimpMesh, MeshImportConfig.Default); 61 | var triangles = mesh.triangles; 62 | 63 | Assert.AreEqual(6, triangles.Length, "Length"); 64 | Assert.AreEqual(new[] {0, 1, 2}, triangles.Skip(0).Take(3)); 65 | Assert.AreEqual(new[] {1, 2, 3}, triangles.Skip(3).Take(3)); 66 | } 67 | 68 | 69 | [Test] 70 | public async Task Mesh_Normals_Are_Converted_Assimp_Normals() 71 | { 72 | var assimpMesh = MakeQuadWithNormals( 73 | "My mesh", 74 | new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 75 | new Vector3D(0, 0, 1), new Vector3D(1, 1, 0) 76 | ); 77 | 78 | var mesh = await ImportMesh(assimpMesh, MeshImportConfig.Default); 79 | var normals = mesh.normals; 80 | 81 | Assert.AreEqual(4, normals.Length, "Length"); 82 | Assert.AreEqual(new Vector3(1, 0, 0), normals[0], "Normal 1"); 83 | Assert.AreEqual(new Vector3(0, 1, 0), normals[1], "Normal 2"); 84 | Assert.AreEqual(new Vector3(0, 0, 1), normals[2], "Normal 3"); 85 | Assert.AreEqual(new Vector3(1, 1, 0), normals[3], "Normal 4"); 86 | } 87 | 88 | [Test] 89 | public async Task Correct_Scaling_Is_Applied() 90 | { 91 | var assimpMesh = Make01Quad("My mesh"); 92 | var conf = new MeshImportConfig(10); 93 | 94 | var mesh = await ImportMesh(assimpMesh, conf); 95 | 96 | Assert.AreEqual(new Vector3(0, 0, 0), mesh.vertices[0]); 97 | Assert.AreEqual(new Vector3(10, 10, 0), mesh.vertices[2]); 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /Tests/MeshImportTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ade7c36c570d74458b0ab1d1ad5c70d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests/MeshNodeImportTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using At.Ac.FhStp.Import3D.Nodes; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | using static At.Ac.FhStp.Import3D.Nodes.Import; 7 | 8 | namespace At.Ac.FhStp.Import3D 9 | { 10 | [RequiresPlayMode] 11 | public class MeshNodeImportTests 12 | { 13 | private readonly Mesh mesh; 14 | private readonly Material material; 15 | private readonly MeshCache meshCache; 16 | private readonly MaterialCache materialCache; 17 | 18 | 19 | public MeshNodeImportTests() 20 | { 21 | mesh = new Mesh 22 | { 23 | name = "My Mesh" 24 | }; 25 | material = new Material(Shader.Find("Standard")); 26 | meshCache = new MeshCache(_ => Task.FromResult(mesh)); 27 | materialCache = new MaterialCache(_ => Task.FromResult(material)); 28 | } 29 | 30 | 31 | [Test] 32 | public async Task MeshNode_Name_Is_Mesh_Name() 33 | { 34 | var meshNode = new MeshNode(0, 0); 35 | var gameObject = await ImportMeshNode(meshNode, meshCache, materialCache); 36 | 37 | Assert.AreEqual(mesh.name, gameObject.name); 38 | } 39 | 40 | [Test] 41 | public async Task MeshNode_Has_MeshFilter_With_Mesh() 42 | { 43 | var meshNode = new MeshNode(0, 0); 44 | var gameObject = await ImportMeshNode(meshNode, meshCache, materialCache); 45 | 46 | var meshFilter = gameObject.GetComponent(); 47 | Assert.True(meshFilter, "Has mesh-filter"); 48 | 49 | Assert.AreEqual(mesh, meshFilter.mesh); 50 | } 51 | 52 | [Test] 53 | public async Task MeshNode_Has_MeshRenderer_With_Default_Material() 54 | { 55 | var meshNode = new MeshNode(0, 0); 56 | var gameObject = await ImportMeshNode(meshNode, meshCache, materialCache); 57 | 58 | var meshRenderer = gameObject.GetComponent(); 59 | Assert.True(meshRenderer, "Has mesh-renderer"); 60 | 61 | Assert.True(meshRenderer.material); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /Tests/MeshNodeImportTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3141a066ce782f64b9229954b5107c9d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests/NonCompressedTextureImportTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using NUnit.Framework; 3 | using AssimpTexel = Assimp.Texel; 4 | using static At.Ac.FhStp.Import3D.AssimpTextureBuilding; 5 | using static At.Ac.FhStp.Import3D.Textures.Import; 6 | 7 | namespace At.Ac.FhStp.Import3D 8 | { 9 | public class NonCompressedTextureImportTests 10 | { 11 | [Test] 12 | public async Task Texture_Name_Is_Assimp_Name_Without_Extension() 13 | { 14 | var assimpTexture = MakeSolidBlackTexture("image.png", 1, 1); 15 | 16 | var texture = await ImportTexture(assimpTexture); 17 | 18 | Assert.AreEqual("image", texture.name); 19 | } 20 | 21 | [Test] 22 | public async Task Texture_Size_Is_Assimp_Size() 23 | { 24 | const int width = 2; 25 | const int height = 4; 26 | var assimpTexture = MakeSolidBlackTexture("image.png", width, height); 27 | 28 | var texture = await ImportTexture(assimpTexture); 29 | 30 | Assert.AreEqual(width, texture.width, "Width"); 31 | Assert.AreEqual(height, texture.height, "Height"); 32 | } 33 | 34 | [Test] 35 | public async Task Texture_Pixels_Are_Normalized_Assimp_Texels() 36 | { 37 | var texel = new AssimpTexel(10, 20, 30, 40); 38 | var assimpTexture = MakeSolidColorTexture("image.png", 1, 1, texel); 39 | 40 | var texture = await ImportTexture(assimpTexture); 41 | var pixel = texture.GetPixel(0, 0); 42 | 43 | Assert.AreEqual(30 / 255f, pixel.r, "R"); 44 | Assert.AreEqual(20 / 255f, pixel.g, "G"); 45 | Assert.AreEqual(10 / 255f, pixel.b, "B"); 46 | Assert.AreEqual(40 / 255f, pixel.a, "A"); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Tests/NonCompressedTextureImportTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b7323eac59cd1b34ea8d321e18544673 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "at.ac.fhstp.import3d", 3 | "version": "0.11.0", 4 | "displayName": "Import3D", 5 | "description": "An asynchronous runtime 3D-model importer for Unity", 6 | "unity": "2021.3", 7 | "author": { 8 | "name": "Ramon Brullo" 9 | }, 10 | "dependencies": { 11 | "com.unity.test-framework": "2.0.1-exp.2", 12 | "org.nuget.system.collections.immutable": "7.0.0", 13 | "org.nuget.dev.comradevanti.nothing": "1.0.0", 14 | "dev.comradevanti.opt-unity": "3.4.0" 15 | }, 16 | "keywords": [ 17 | "import", 18 | "3d-model", 19 | "async", 20 | "runtime" 21 | ], 22 | "samples": [ 23 | { 24 | "displayName": "Import Tester", 25 | "description": "In this sample you can test the importing functionality of the package as well as get to know the API.", 26 | "path": "Samples~/ImportTester" 27 | } 28 | ], 29 | "hideInEditor": false 30 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79d36fc32598f5447953629864d365e0 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------