├── .gitignore ├── lib ├── assimp-vc143-mt.dll ├── assimp-vc143-mt.lib ├── assimp-vc143-mtd.dll ├── assimp-vc143-mtd.lib └── LICENSE ├── models └── animals │ ├── Pig.fbx │ ├── CowBlW.fbx │ ├── DuckWhite.fbx │ ├── ChickenBrown.fbx │ ├── SheepWhite.fbx │ └── changelog.txt ├── LICENSE ├── main.odin ├── assimp.odin └── import └── assimp.odin /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdb 2 | *.rdi 3 | *.exe 4 | 5 | *.blend1 6 | -------------------------------------------------------------------------------- /lib/assimp-vc143-mt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/lib/assimp-vc143-mt.dll -------------------------------------------------------------------------------- /lib/assimp-vc143-mt.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/lib/assimp-vc143-mt.lib -------------------------------------------------------------------------------- /models/animals/Pig.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/models/animals/Pig.fbx -------------------------------------------------------------------------------- /lib/assimp-vc143-mtd.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/lib/assimp-vc143-mtd.dll -------------------------------------------------------------------------------- /lib/assimp-vc143-mtd.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/lib/assimp-vc143-mtd.lib -------------------------------------------------------------------------------- /models/animals/CowBlW.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/models/animals/CowBlW.fbx -------------------------------------------------------------------------------- /models/animals/DuckWhite.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/models/animals/DuckWhite.fbx -------------------------------------------------------------------------------- /models/animals/ChickenBrown.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/models/animals/ChickenBrown.fbx -------------------------------------------------------------------------------- /models/animals/SheepWhite.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoolDove/odin-assimp/HEAD/models/animals/SheepWhite.fbx -------------------------------------------------------------------------------- /models/animals/changelog.txt: -------------------------------------------------------------------------------- 1 | Changelog 2 | 3 | [1.1] - 2017-08-14 4 | - Added this changelog to the asset .zip file 5 | - .fbx models rotated so that forward = +z 6 | - .fbx chicken scaled down to a more sensible size 7 | 8 | [1.0] - 2017-08-06 9 | - First release 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Doooooove 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/LICENSE: -------------------------------------------------------------------------------- 1 | Open Asset Import Library (assimp) 2 | 3 | Copyright (c) 2006-2021, assimp team 4 | All rights reserved. 5 | 6 | Redistribution and use of this software in source and binary forms, 7 | with or without modification, are permitted provided that the 8 | following conditions are met: 9 | 10 | * Redistributions of source code must retain the above 11 | copyright notice, this list of conditions and the 12 | following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the 16 | following disclaimer in the documentation and/or other 17 | materials provided with the distribution. 18 | 19 | * Neither the name of the assimp team, nor the names of its 20 | contributors may be used to endorse or promote products 21 | derived from this software without specific prior 22 | written permission of the assimp team. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | 37 | 38 | ****************************************************************************** 39 | 40 | AN EXCEPTION applies to all files in the ./test/models-nonbsd folder. 41 | These are 3d models for testing purposes, from various free sources 42 | on the internet. They are - unless otherwise stated - copyright of 43 | their respective creators, which may impose additional requirements 44 | on the use of their work. For any of these models, see 45 | .source.txt for more legal information. Contact us if you 46 | are a copyright holder and believe that we credited you inproperly or 47 | if you don't want your files to appear in the repository. 48 | 49 | 50 | ****************************************************************************** 51 | 52 | Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors 53 | http://code.google.com/p/poly2tri/ 54 | 55 | All rights reserved. 56 | Redistribution and use in source and binary forms, with or without modification, 57 | are permitted provided that the following conditions are met: 58 | 59 | * Redistributions of source code must retain the above copyright notice, 60 | this list of conditions and the following disclaimer. 61 | * Redistributions in binary form must reproduce the above copyright notice, 62 | this list of conditions and the following disclaimer in the documentation 63 | and/or other materials provided with the distribution. 64 | * Neither the name of Poly2Tri nor the names of its contributors may be 65 | used to endorse or promote products derived from this software without specific 66 | prior written permission. 67 | 68 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 69 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 70 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 71 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 72 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 73 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 74 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 75 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 76 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 77 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 78 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 79 | -------------------------------------------------------------------------------- /main.odin: -------------------------------------------------------------------------------- 1 | package assimp 2 | 3 | import "base:runtime" 4 | import "core:fmt" 5 | import "core:strings" 6 | import "core:math" 7 | import "core:math/rand" 8 | import "core:math/linalg" 9 | import "core:c/libc" 10 | 11 | import rl "vendor:raylib" 12 | 13 | import ai "import" 14 | 15 | @private 16 | main :: proc() { 17 | rl.SetTargetFPS(60) 18 | rl.InitWindow(800, 600, "Assimp Test") 19 | 20 | cam : rl.Camera3D 21 | cam.position = { 100.0, 100.0, 100.0 } 22 | cam.target = { 0.0, 0.0, 0.0 } 23 | cam.up = { 0.0, 1.0, 0.0 } 24 | cam.fovy = 45.0 25 | cam.projection = .PERSPECTIVE 26 | 27 | model_duck := rl_assimp_load("models/animals/DuckWhite.fbx") 28 | 29 | for !rl.WindowShouldClose() { 30 | rl.UpdateCamera(&cam, .ORBITAL) 31 | rl.BeginDrawing() 32 | rl.ClearBackground(rl.BLACK) 33 | rl.BeginMode3D(cam) 34 | rl.DrawLine3D({0,0,-100}, {0,0,100}, rl.DARKGRAY) 35 | rl.DrawLine3D({-100,0,0}, {100,0,0}, rl.DARKGRAY) 36 | 37 | rl.DrawCube({}, 1,1,1, rl.RED) 38 | 39 | rl.DrawModel(model_duck, {}, 1, rl.WHITE) 40 | rl.DrawModelWires(model_duck, {}, 1, {0,0,0,12}) 41 | 42 | rl.EndMode3D() 43 | rl.EndDrawing() 44 | } 45 | 46 | rl.UnloadModel(model_duck) 47 | 48 | rl.CloseWindow() 49 | } 50 | 51 | // only load the first mesh in a scene 52 | @private 53 | rl_assimp_load :: proc { 54 | rl_assimp_load_from_file, 55 | rl_assimp_load_from_data, 56 | } 57 | @private 58 | rl_assimp_load_from_file :: proc(file: string) -> rl.Model { 59 | scene := import_file_from_file(file, auto_cast ai.aiProcessPreset_TargetRealtime_Quality) 60 | defer release_import(scene) 61 | return _rl_assimp_process_scene(scene) 62 | } 63 | @private 64 | rl_assimp_load_from_data :: proc(buffer: []byte, format_hint: string) -> rl.Model { 65 | scene := import_file_from_memory(buffer, auto_cast ai.aiProcessPreset_TargetRealtime_Quality, format_hint) 66 | defer release_import(scene) 67 | return _rl_assimp_process_scene(scene) 68 | } 69 | @private 70 | _rl_assimp_process_scene :: proc(scene : ^Scene) -> rl.Model { 71 | check_scene(scene) 72 | return rl_load_model_from_aimesh(scene.mMeshes[0]) 73 | } 74 | 75 | @private 76 | rl_load_model_from_aimesh :: proc(aimesh: ^Mesh) -> rl.Model { 77 | aicolors := aimesh.mColors[0] 78 | mesh : rl.Mesh; { 79 | mesh.vertexCount = auto_cast aimesh.mNumVertices 80 | indices := cast([^]u16)rl.MemAlloc(auto_cast ( size_of(u16) * aimesh.mNumFaces * 3 )) 81 | for i in 0.. ^Scene { 31 | file_cstr := strings.clone_to_cstring(file, context.temp_allocator) 32 | return ai.import_file(file_cstr, postprocess_flags) 33 | } 34 | import_file_from_memory :: proc( 35 | buffer: []byte, 36 | postprocess_flags: u32, 37 | format_hint: string, 38 | ) -> ^Scene { 39 | hint_cstr := strings.clone_to_cstring(format_hint, context.temp_allocator) 40 | return ai.import_file_from_memory( 41 | raw_data(buffer), 42 | cast(u32)len(buffer), 43 | postprocess_flags, 44 | hint_cstr, 45 | ) 46 | } 47 | release_import :: ai.release_import 48 | 49 | copy_scene :: ai.copy_scene 50 | free_scene :: ai.free_scene 51 | export_scene :: ai.export_scene 52 | 53 | apply_post_processing :: ai.apply_post_processing 54 | is_extension_supported :: ai.is_extension_supported 55 | get_extension_list :: ai.get_extension_list 56 | get_memory_requirements :: ai.get_memory_requirements 57 | set_import_property_integer :: ai.set_import_property_integer 58 | set_import_property_float :: ai.set_import_property_float 59 | set_import_property_string :: ai.set_import_property_string 60 | create_quaternion_from_matrix :: ai.create_quaternion_from_matrix 61 | decompose_matrix :: ai.decompose_matrix 62 | transpose_matrix4 :: ai.transpose_matrix4 63 | transpose_matrix3 :: ai.transpose_matrix3 64 | transform_vec_by_matrix3 :: ai.transform_vec_by_matrix3 65 | transform_vec_by_matrix4 :: ai.transform_vec_by_matrix4 66 | multiply_matrix4 :: ai.multiply_matrix4 67 | multiply_matrix3 :: ai.multiply_matrix3 68 | identity_matrix3 :: ai.identity_matrix3 69 | identity_matrix4 :: ai.identity_matrix4 70 | get_material_property :: ai.get_material_property 71 | get_material_floatArray :: ai.get_material_floatArray 72 | get_material_integerArray :: ai.get_material_integerArray 73 | get_material_color :: ai.get_material_color 74 | get_material_string :: ai.get_material_string 75 | get_material_textureCount :: ai.get_material_textureCount 76 | get_material_texture :: ai.get_material_texture 77 | 78 | // assimp types 79 | VectorKey :: ai.aiVectorKey 80 | QuatKey :: ai.aiQuatKey 81 | AnimBehaviour :: ai.aiAnimBehaviour 82 | NodeAnim :: ai.aiNodeAnim 83 | Animation :: ai.aiAnimation 84 | Bool :: ai.aiBool 85 | String :: ai.aiString 86 | Return :: ai.aiReturn 87 | Origin :: ai.aiOrigin 88 | DefautLogStream :: ai.aiDefaultLogStream 89 | MemoryInfo :: ai.aiMemoryInfo 90 | Camera :: ai.aiCamera 91 | TextureOp :: ai.aiTextureOp 92 | TextureMapMode :: ai.aiTextureMapMode 93 | TextureMapping :: ai.aiTextureMapping 94 | TextureType :: ai.aiTextureType 95 | ShadingMode :: ai.aiShadingMode 96 | TextureFlags :: ai.aiTextureFlags 97 | BlendMode :: ai.aiBlendMode 98 | Transform :: ai.aiUVTransform 99 | PropeyTypeInfo :: ai.aiPropertyTypeInfo 100 | MaterlProperty :: ai.aiMaterialProperty 101 | Material :: ai.aiMaterial 102 | LightSourceType :: ai.aiLightSourceType 103 | Light :: ai.aiLight 104 | Face :: ai.aiFace 105 | VertexWeight :: ai.aiVertexWeight 106 | Bone :: ai.aiBone 107 | PrimitiveType :: ai.aiPrimitiveType 108 | AnimMesh :: ai.aiAnimMesh 109 | Mesh :: ai.aiMesh 110 | Vector2D :: ai.aiVector2D 111 | Vector3D :: ai.aiVector3D 112 | Quaternion :: ai.aiQuaternion 113 | Matrix3x3 :: ai.aiMatrix3x3 114 | Matrix4x4 :: ai.aiMatrix4x4 115 | Plane :: ai.aiPlane 116 | Ray :: ai.aiRay 117 | Color3D :: ai.aiColor3D 118 | Color4D :: ai.aiColor4D 119 | Texel :: ai.aiTexel 120 | Texture :: ai.aiTexture 121 | Node :: ai.aiNode 122 | SceneFlags :: ai.aiSceneFlags 123 | Scene :: ai.aiScene 124 | PostProcessSteps :: ai.aiPostProcessSteps 125 | 126 | 127 | PostProcessPreset_Quality :: ai.aiProcessPreset_TargetRealtime_Quality 128 | PostProcessPreset_MaxQuality :: ai.aiProcessPreset_TargetRealtime_MaxQuality 129 | 130 | 131 | // helper procs 132 | string_clone_from_ai_string :: proc(aistr: ^String, allocator := context.allocator) -> string { 133 | return strings.clone_from_bytes(aistr.data[:aistr.length], allocator) 134 | } 135 | 136 | string_clone_to_ai_string :: proc(text: string, aistr: ^String) { 137 | assert(aistr != nil, "You are clone to a nil aiString.") 138 | data := raw_data(text) 139 | copy(aistr.data[:], text) 140 | aistr.length = cast(u32)len(text) 141 | } 142 | 143 | matrix_convert :: proc { 144 | matrix_convert_3, 145 | matrix_convert_4, 146 | } 147 | 148 | matrix_convert_4 :: proc(using ai_matrix: Matrix4x4) -> linalg.Matrix4f32 { 149 | return linalg.Matrix4f32{a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4} 150 | } 151 | matrix_convert_3 :: proc(using ai_matrix: Matrix3x3) -> linalg.Matrix3f32 { 152 | return linalg.Matrix3f32{a1, a2, a3, b1, b2, b3, c1, c2, c3} 153 | } 154 | 155 | quaterion_convert :: proc(quat: Quaternion) -> linalg.Quaternionf32 { 156 | return quaternion(x = quat.x, y = quat.y, z = quat.z, w = quat.w) 157 | } 158 | -------------------------------------------------------------------------------- /import/assimp.odin: -------------------------------------------------------------------------------- 1 | package assimp_import 2 | 3 | import linalg "core:math/linalg" 4 | 5 | when ODIN_OS == .Windows { 6 | when ODIN_DEBUG do foreign import assimp "../lib/assimp-vc143-mtd.lib" 7 | else do foreign import assimp "../lib/assimp-vc143-mt.lib" 8 | } else when ODIN_OS == .Linux { 9 | // foreign import assimp "../compiled/libassimp.so" 10 | foreign import assimp "system:assimp" 11 | } else { 12 | #panic(true) 13 | } 14 | 15 | ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS :: #config(ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS, true) 16 | 17 | @(default_calling_convention = "c") 18 | foreign assimp { 19 | @(link_name = "aiGetErrorString") 20 | get_error_string :: proc() -> cstring --- 21 | 22 | @(link_name = "aiImportFile") 23 | import_file :: proc(file: cstring, postprocessFlags: u32) -> ^aiScene --- 24 | // -------------------------------------------------------------------------------- 25 | /** Reads the given file from a given memory buffer, 26 | * 27 | * If the call succeeds, the contents of the file are returned as a pointer to an 28 | * aiScene object. The returned data is intended to be read-only, the importer keeps 29 | * ownership of the data and will destroy it upon destruction. If the import fails, 30 | * NULL is returned. 31 | * A human-readable error description can be retrieved by calling aiGetErrorString(). 32 | * @param pBuffer Pointer to the file data 33 | * @param pLength Length of pBuffer, in bytes 34 | * @param pFlags Optional post processing steps to be executed after 35 | * a successful import. Provide a bitwise combination of the 36 | * #aiPostProcessSteps flags. If you wish to inspect the imported 37 | * scene first in order to fine-tune your post-processing setup, 38 | * consider to use #aiApplyPostProcessing(). 39 | * @param pHint An additional hint to the library. If this is a non empty string, 40 | * the library looks for a loader to support the file extension specified by pHint 41 | * and passes the file to the first matching loader. If this loader is unable to 42 | * completely the request, the library continues and tries to determine the file 43 | * format on its own, a task that may or may not be successful. 44 | * Check the return value, and you'll know ... 45 | * @return A pointer to the imported data, NULL if the import failed. 46 | * 47 | * @note This is a straightforward way to decode models from memory 48 | * buffers, but it doesn't handle model formats that spread their 49 | * data across multiple files or even directories. Examples include 50 | * OBJ or MD3, which outsource parts of their material info into 51 | * external scripts. If you need full functionality, provide 52 | * a custom IOSystem to make Assimp find these files and use 53 | * the regular aiImportFileEx()/aiImportFileExWithProperties() API. 54 | */ 55 | @(link_name = "aiImportFileFromMemory") 56 | import_file_from_memory :: proc(buffer: [^]byte, pLength, pFlags: u32, pHint: cstring) -> ^aiScene --- 57 | 58 | @(link_name = "aiReleaseImport") 59 | release_import :: proc(pScene: ^aiScene) --- 60 | // -------------------------------------------------------------------------------- 61 | /** Create a modifiable copy of a scene. 62 | * This is useful to import files via Assimp, change their topology and 63 | * export them again. Since the scene returned by the various importer functions 64 | * is const, a modifiable copy is needed. 65 | * @param pIn Valid scene to be copied 66 | * @param pOut Receives a modifiable copy of the scene. Use aiFreeScene() to 67 | * delete it again. 68 | */ 69 | @(link_name = "aiCopyScene") 70 | copy_scene :: proc(pIn: ^aiScene, pOut: ^^aiScene) --- 71 | 72 | // -------------------------------------------------------------------------------- 73 | /** Frees a scene copy created using aiCopyScene() */ 74 | @(link_name = "aiFreeScene") 75 | free_scene :: proc(pScene: ^aiScene) --- 76 | 77 | // -------------------------------------------------------------------------------- 78 | /** Exports the given scene to a chosen file format and writes the result file(s) to disk. 79 | * @param pScene The scene to export. Stays in possession of the caller, is not changed by the function. 80 | * The scene is expected to conform to Assimp's Importer output format as specified 81 | * in the @link data Data Structures Page @endlink. In short, this means the model data 82 | * should use a right-handed coordinate systems, face winding should be counter-clockwise 83 | * and the UV coordinate origin is assumed to be in the upper left. If your input data 84 | * uses different conventions, have a look at the last parameter. 85 | * @param pFormatId ID string to specify to which format you want to export to. Use 86 | * aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available. 87 | * @param pFileName Output file to write 88 | * @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated 89 | * flags, but in reality only a subset of them makes sense here. Specifying 90 | * 'preprocessing' flags is useful if the input scene does not conform to 91 | * Assimp's default conventions as specified in the @link data Data Structures Page @endlink. 92 | * In short, this means the geometry data should use a right-handed coordinate systems, face 93 | * winding should be counter-clockwise and the UV coordinate origin is assumed to be in 94 | * the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and 95 | * #aiProcess_FlipWindingOrder flags are used in the import side to allow users 96 | * to have those defaults automatically adapted to their conventions. Specifying those flags 97 | * for exporting has the opposite effect, respectively. Some other of the 98 | * #aiPostProcessSteps enumerated values may be useful as well, but you'll need 99 | * to try out what their effect on the exported file is. Many formats impose 100 | * their own restrictions on the structure of the geometry stored therein, 101 | * so some preprocessing may have little or no effect at all, or may be 102 | * redundant as exporters would apply them anyhow. A good example 103 | * is triangulation - whilst you can enforce it by specifying 104 | * the #aiProcess_Triangulate flag, most export formats support only 105 | * triangulate data so they would run the step anyway. 106 | * 107 | * If assimp detects that the input scene was directly taken from the importer side of 108 | * the library (i.e. not copied using aiCopyScene and potentially modified afterwards), 109 | * any post-processing steps already applied to the scene will not be applied again, unless 110 | * they show non-idempotent behavior (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and 111 | * #aiProcess_FlipWindingOrder). 112 | * @return a status code indicating the result of the export 113 | * @note Use aiCopyScene() to get a modifiable copy of a previously 114 | * imported scene. 115 | */ 116 | @(link_name = "aiExportScene") 117 | export_scene :: proc(pScene: ^aiScene, pFormatId, pFileName: cstring, pPreprocessing: u32) -> aiReturn --- 118 | 119 | @(link_name = "aiApplyPostProcessing") 120 | apply_post_processing :: proc(pScene: ^aiScene, pFlags: u32) -> ^aiScene --- 121 | @(link_name = "aiIsExtensionSupported") 122 | is_extension_supported :: proc(szExtension: cstring) -> aiBool --- 123 | @(link_name = "aiGetExtensionList") 124 | get_extension_list :: proc(szOut: ^aiString) --- 125 | @(link_name = "aiGetMemoryRequirements") 126 | get_memory_requirements :: proc(pIn: ^aiScene, info: ^aiMemoryInfo) --- 127 | @(link_name = "aiSetImportPropertyInteger") 128 | set_import_property_integer :: proc(szName: cstring, value: int) --- 129 | @(link_name = "aiSetImportPropertyFloat") 130 | set_import_property_float :: proc(szName: cstring, value: f64) --- 131 | @(link_name = "aiSetImportPropertyString") 132 | set_import_property_string :: proc(szName: cstring, st: ^aiString) --- 133 | @(link_name = "aiCreateQuaternionFromMatrix") 134 | create_quaternion_from_matrix :: proc(quat: ^aiQuaternion, mat: ^aiMatrix3x3) --- 135 | @(link_name = "aiDecomposeMatrix") 136 | decompose_matrix :: proc(mat: ^aiMatrix4x4, scaling: ^aiVector3D, rotation: ^aiQuaternion, position: ^aiVector3D) --- 137 | @(link_name = "aiTransposeMatrix4") 138 | transpose_matrix4 :: proc(mat: ^aiMatrix4x4) --- 139 | @(link_name = "aiTransposeMatrix3") 140 | transpose_matrix3 :: proc(mat: ^aiMatrix3x3) --- 141 | @(link_name = "aiTransformVecByMatrix3") 142 | transform_vec_by_matrix3 :: proc(vec: ^aiVector3D, mat: ^aiMatrix3x3) --- 143 | @(link_name = "aiTransformVecByMatrix4") 144 | transform_vec_by_matrix4 :: proc(vec: ^aiVector3D, mat: ^aiMatrix4x4) --- 145 | @(link_name = "aiMultiplyMatrix4") 146 | multiply_matrix4 :: proc(dst: ^aiMatrix4x4, src: ^aiMatrix4x4) --- 147 | @(link_name = "aiMultiplyMatrix3") 148 | multiply_matrix3 :: proc(dst: ^aiMatrix3x3, src: ^aiMatrix3x3) --- 149 | @(link_name = "aiIdentityMatrix3") 150 | identity_matrix3 :: proc(mat: ^aiMatrix3x3) --- 151 | @(link_name = "aiIdentityMatrix4") 152 | identity_matrix4 :: proc(mat: ^aiMatrix4x4) --- 153 | @(link_name = "aiGetMaterialProperty") 154 | get_material_property :: proc(pMat: ^aiMaterial, pKey: cstring, type: u32, index: u32, pPropOut: ^^aiMaterialProperty) -> aiReturn --- 155 | @(link_name = "aiGetMaterialFloatArray") 156 | get_material_floatArray :: proc(pMat: ^aiMaterial, pKey: cstring, type: u32, index: u32, pOut: ^f64, pMax: ^u32) -> aiReturn --- 157 | @(link_name = "aiGetMaterialIntegerArray") 158 | get_material_integerArray :: proc(pMat: ^aiMaterial, pKey: cstring, type: u32, index: u32, pOut: ^int, pMax: ^u32) -> aiReturn --- 159 | @(link_name = "aiGetMaterialColor") 160 | get_material_color :: proc(pMat: ^aiMaterial, pKey: cstring, type: u32, index: u32, pOut: ^aiColor4D) -> aiReturn --- 161 | @(link_name = "aiGetMaterialString") 162 | get_material_string :: proc(pMat: ^aiMaterial, pKey: cstring, type: u32, index: u32, pOut: ^aiString) -> aiReturn --- 163 | @(link_name = "aiGetMaterialTextureCount") 164 | get_material_textureCount :: proc(pMat: ^aiMaterial, type: aiTextureType) -> u32 --- 165 | @(link_name = "aiGetMaterialTexture") 166 | get_material_texture :: proc(mat: ^aiMaterial, type: aiTextureType, index: u32, path: ^aiString, mapping: ^aiTextureMapping, uvindex: ^u32, blend: ^f64, op: ^aiTextureOp, mapmode: ^aiTextureMapMode) -> aiReturn --- 167 | 168 | // @(link_name="aiImportFileEx") import_fileex :: proc(pFile:cstring,pFlags: u32,pFS: ^aiFileIO) -> ^aiScene ---; 169 | // @(link_name="aiGetPredefinedLogStream") get_predefined_log_stream :: proc(pStreams: aiDefaultLogStream,file:cstring) -> aiLogStream ---; 170 | // @(link_name="aiAttachLogStream") attach_log_stream :: proc(stream: ^aiLogStream) ---; 171 | // @(link_name="aiEnableVerboseLogging") enable_verbose_logging :: proc(d: aiBool) ---; 172 | // @(link_name="aiDetachLogStream") detach_log_stream :: proc(stream: ^aiLogStream) -> aiReturn ---; 173 | 174 | } 175 | 176 | AI_MAX_FACE_INDICES :: 0x7fff 177 | AI_MAX_BONE_WEIGHTS :: 0x7fffffff 178 | AI_MAX_VERTICES :: 0x7fffffff 179 | AI_MAX_FACES :: 0x7fffffff 180 | AI_MAX_NUMBER_OF_COLOR_SETS :: 0x8 181 | AI_MAX_NUMBER_OF_TEXTURECOORDS :: 0x8 182 | 183 | AI_MAX_STRING_LENGTH :: 1024 184 | 185 | aiVectorKey :: struct { 186 | mTime: f64, 187 | mValue: aiVector3D, 188 | } 189 | aiQuatKey :: struct { 190 | mTime: f64, 191 | mValue: aiQuaternion, 192 | } 193 | aiAnimBehaviour :: enum u32 { 194 | DEFAULT = 0x0, 195 | CONSTANT = 0x1, 196 | LINEAR = 0x2, 197 | REPEAT = 0x3, 198 | } 199 | 200 | aiNodeAnim :: struct { 201 | mNodeName: aiString, 202 | mNumPositionKeys: u32, 203 | mPositionKeys: [^]aiVectorKey, 204 | mNumRotationKeys: u32, 205 | mRotationKeys: [^]aiQuatKey, 206 | mNumScalingKeys: u32, 207 | mScalingKeys: [^]aiVectorKey, 208 | mPreState: aiAnimBehaviour, 209 | mPostState: aiAnimBehaviour, 210 | } 211 | 212 | aiAnimation :: struct { 213 | mName: aiString, 214 | mDuration: f64, 215 | mTicksPerSecond: f64, 216 | mNumChannels: u32, 217 | mChannels: [^]^aiNodeAnim, 218 | } 219 | 220 | aiBool :: enum int { 221 | FALSE = 0, 222 | TRUE = 1, 223 | } 224 | 225 | aiString :: struct { 226 | length: u32, 227 | data: [AI_MAX_STRING_LENGTH]u8, 228 | } 229 | 230 | aiReturn :: enum u32 { 231 | SUCCESS = 0x0, 232 | FAILURE = 0x1, 233 | OUTOFMEMORY = 0x3, 234 | } 235 | 236 | aiOrigin :: enum u32 { 237 | SET = 0x0, 238 | CUR = 0x1, 239 | END = 0x2, 240 | } 241 | 242 | aiDefaultLogStream :: enum { 243 | FILE = 0x1, 244 | STDOUT = 0x2, 245 | STDERR = 0x4, 246 | DEBUGGER = 0x8, 247 | } 248 | 249 | aiMemoryInfo :: struct { 250 | textures: u32, 251 | materials: u32, 252 | meshes: u32, 253 | nodes: u32, 254 | animations: u32, 255 | cameras: u32, 256 | lights: u32, 257 | total: u32, 258 | } 259 | 260 | aiCamera :: struct { 261 | mName: aiString, 262 | mPosition: aiVector3D, 263 | mUp: aiVector3D, 264 | mLookAt: aiVector3D, 265 | mHorizontalFOV: f32, 266 | mClipPlaneNear: f32, 267 | mClipPlaneFar: f32, 268 | mAspect: f32, 269 | } 270 | 271 | aiTextureOp :: enum u32 { 272 | Multiply = 0x0, 273 | Add = 0x1, 274 | Subtract = 0x2, 275 | Divide = 0x3, 276 | SmoothAdd = 0x4, 277 | SignedAdd = 0x5, 278 | } 279 | aiTextureMapMode :: enum u32 { 280 | Wrap = 0x0, 281 | Clamp = 0x1, 282 | Decal = 0x3, 283 | Mirror = 0x2, 284 | } 285 | aiTextureMapping :: enum u32 { 286 | UV = 0x0, 287 | SPHERE = 0x1, 288 | CYLINDER = 0x2, 289 | BOX = 0x3, 290 | PLANE = 0x4, 291 | OTHER = 0x5, 292 | } 293 | 294 | aiTextureType :: enum u32 { 295 | NONE = 0x0, 296 | DIFFUSE = 0x1, 297 | SPECULAR = 0x2, 298 | AMBIENT = 0x3, 299 | EMISSIVE = 0x4, 300 | HEIGHT = 0x5, 301 | NORMALS = 0x6, 302 | SHININESS = 0x7, 303 | OPACITY = 0x8, 304 | DISPLACEMENT = 0x9, 305 | LIGHTMAP = 0xA, 306 | REFLECTION = 0xB, 307 | UNKNOWN = 0xC, 308 | } 309 | 310 | aiShadingMode :: enum u32 { 311 | Flat = 0x1, 312 | Gouraud = 0x2, 313 | Phong = 0x3, 314 | Blinn = 0x4, 315 | Toon = 0x5, 316 | OrenNayar = 0x6, 317 | Minnaert = 0x7, 318 | CookTorrance = 0x8, 319 | NoShading = 0x9, 320 | Fresnel = 0xa, 321 | } 322 | 323 | aiTextureFlags :: enum u32 { 324 | Invert = 0x1, 325 | UseAlpha = 0x2, 326 | IgnoreAlpha = 0x4, 327 | } 328 | 329 | aiBlendMode :: enum { 330 | Default = 0x0, 331 | Additive = 0x1, 332 | } 333 | 334 | aiUVTransform :: struct { 335 | mTranslation: aiVector2D, 336 | mScaling: aiVector2D, 337 | mRotation: f32, 338 | } 339 | 340 | aiPropertyTypeInfo :: enum u32 { 341 | Float = 0x1, 342 | String = 0x3, 343 | Integer = 0x4, 344 | Buffer = 0x5, 345 | } 346 | 347 | aiMaterialProperty :: struct { 348 | mKey: aiString, 349 | mSemantic: u32, 350 | mIndex: u32, 351 | mDataLength: u32, 352 | mType: aiPropertyTypeInfo, 353 | mData: cstring, 354 | } 355 | aiMaterial :: struct { 356 | mProperties: [^]^aiMaterialProperty, 357 | mNumProperties: u32, 358 | mNumAllocated: u32, 359 | } 360 | 361 | aiLightSourceType :: enum u32 { 362 | UNDEFINED = 0x0, 363 | DIRECTIONAL = 0x1, 364 | POINT = 0x2, 365 | SPOT = 0x3, 366 | } 367 | 368 | aiLight :: struct { 369 | mName: aiString, 370 | mType: aiLightSourceType, 371 | mPosition: aiVector3D, 372 | mDirection: aiVector3D, 373 | mAttenuationConstant: f32, 374 | mAttenuationLinear: f32, 375 | mAttenuationQuadratic: f32, 376 | mColorDiffuse: aiColor3D, 377 | mColorSpecular: aiColor3D, 378 | mColorAmbient: aiColor3D, 379 | mAngleInnerCone: f32, 380 | mAngleOuterCone: f32, 381 | } 382 | 383 | // aiFileIO :: struct { 384 | // OpenProc : aiFileOpenProc, 385 | // CloseProc : aiFileCloseProc, 386 | // UserData : aiUserData, 387 | // } 388 | // aiFile :: struct { 389 | // ReadProc : aiFileReadProc, 390 | // WriteProc : aiFileWriteProc, 391 | // TellProc : aiFileTellProc, 392 | // FileSizeProc : aiFileTellProc, 393 | // SeekProc : aiFileSeek, 394 | // FlushProc : aiFileFlushProc, 395 | // UserData : aiUserData, 396 | // } 397 | 398 | aiFace :: struct { 399 | mNumIndices: u32, 400 | mIndices: [^]u32, 401 | } 402 | 403 | aiReal :: f32 404 | 405 | aiVertexWeight :: struct { 406 | mVertexId: u32, 407 | mWeight: aiReal, 408 | } 409 | 410 | when ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS { 411 | aiBone :: struct { 412 | mName: aiString, 413 | mNumWeights: u32, 414 | mArmature: ^aiNode, 415 | mNode: ^aiNode, 416 | mWeights: [^]aiVertexWeight, 417 | mOffsetMatrix: aiMatrix4x4, 418 | } 419 | } else { 420 | aiBone :: struct { 421 | mName: aiString, 422 | mNumWeights: u32, 423 | mWeights: [^]aiVertexWeight, 424 | mOffsetMatrix: aiMatrix4x4, 425 | } 426 | } 427 | 428 | aiPrimitiveType :: enum u32 { 429 | POINT = 0x1, 430 | LINE = 0x2, 431 | TRIANGLE = 0x4, 432 | POLYGON = 0x8, 433 | } 434 | 435 | aiAnimMesh :: struct { 436 | mVertices: [^]aiVector3D, 437 | mNormals: [^]aiVector3D, 438 | mTangents: [^]aiVector3D, 439 | mBitangents: [^]aiVector3D, 440 | mColors: [AI_MAX_NUMBER_OF_COLOR_SETS][^]aiColor4D, 441 | mTextureCoords: [AI_MAX_NUMBER_OF_TEXTURECOORDS][^]aiVector3D, 442 | mNumVertices: u32, 443 | } 444 | 445 | aiMesh :: struct { 446 | mPrimitiveTypes: u32, 447 | mNumVertices: u32, 448 | mNumFaces: u32, 449 | mVertices: [^]aiVector3D, 450 | mNormals: [^]aiVector3D, 451 | mTangents: [^]aiVector3D, 452 | mBitangents: [^]aiVector3D, 453 | /** Vertex color sets. 454 | * A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex 455 | * colors per vertex. nullptr if not present. Each array is 456 | * mNumVertices in size if present. 457 | */ 458 | mColors: [AI_MAX_NUMBER_OF_COLOR_SETS][^]aiColor4D, 459 | /** Vertex texture coordinates, also known as UV channels. 460 | * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per 461 | * vertex. nullptr if not present. The array is mNumVertices in size. 462 | */ 463 | mTextureCoords: [AI_MAX_NUMBER_OF_TEXTURECOORDS][^]aiVector3D, 464 | /** Specifies the number of components for a given UV channel. 465 | * Up to three channels are supported (UVW, for accessing volume 466 | * or cube maps). If the value is 2 for a given channel n, the 467 | * component p.z of mTextureCoords[n][p] is set to 0.0f. 468 | * If the value is 1 for a given channel, p.y is set to 0.0f, too. 469 | * @note 4D coordinates are not supported 470 | */ 471 | mNumUVComponents: [AI_MAX_NUMBER_OF_TEXTURECOORDS]u32, 472 | mFaces: [^]aiFace, 473 | mNumBones: u32, 474 | mBones: [^]^aiBone, 475 | mMaterialIndex: u32, 476 | mName: aiString, 477 | mNumAnimMeshes: u32, 478 | mAnimMeshes: [^]^aiAnimMesh, 479 | mMethod: u32, 480 | } 481 | 482 | aiVector2D :: linalg.Vector2f32 483 | 484 | aiVector3D :: linalg.Vector3f32 485 | 486 | // aiQuaternion :: linalg.Quaternionf32 487 | aiQuaternion :: struct { 488 | w, x, y, z: f32, 489 | } 490 | 491 | aiMatrix3x3 :: struct { 492 | a1, a2, a3: f32, 493 | b1, b2, b3: f32, 494 | c1, c2, c3: f32, 495 | } 496 | 497 | aiMatrix4x4 :: struct { 498 | a1, a2, a3, a4: f32, 499 | b1, b2, b3, b4: f32, 500 | c1, c2, c3, c4: f32, 501 | d1, d2, d3, d4: f32, 502 | } 503 | 504 | // aiMatrix3x3 :: linalg.Matrix3x3f32 505 | // aiMatrix4x4 :: linalg.Matrix4x4f32 506 | 507 | aiPlane :: linalg.Vector4f32 508 | 509 | aiRay :: struct { 510 | pos: aiVector3D, 511 | dir: aiVector3D, 512 | } 513 | 514 | aiColor3D :: linalg.Vector3f32 515 | 516 | aiColor4D :: linalg.Vector4f32 517 | 518 | aiTexel :: struct { 519 | b: byte, 520 | } 521 | 522 | aiTexture :: struct { 523 | mWidth: u32, 524 | mHeight: u32, 525 | achFormatHint: [4]u8, 526 | pcData: ^aiTexel, 527 | } 528 | 529 | aiNode :: struct { 530 | mName: aiString, 531 | mTransformation: aiMatrix4x4, 532 | mParent: ^aiNode, 533 | mNumChildren: u32, 534 | mChildren: [^]^aiNode, 535 | mNumMeshes: u32, 536 | mMeshes: [^]u32, 537 | mMetaData: rawptr, // TODO: aiNode.mMetaData 538 | } 539 | 540 | aiSceneFlags :: enum u32 { 541 | INCOMPLETE = 0x1, 542 | VALIDATED = 0x2, 543 | VALIDATION_WARNING = 0x4, 544 | NON_VERBOSE_FORMAT = 0x8, 545 | FLAGS_TERRAIN = 0x10, 546 | } 547 | 548 | aiScene :: struct { 549 | mFlags: u32, 550 | mRootNode: ^aiNode, 551 | mNumMeshes: u32, 552 | mMeshes: [^]^aiMesh, 553 | mNumMaterials: u32, 554 | mMaterials: [^]^aiMaterial, 555 | mNumAnimations: u32, 556 | mAnimations: [^]^aiAnimation, 557 | mNumTextures: u32, 558 | mTextures: [^]^aiTexture, 559 | mNumLights: u32, 560 | mLights: [^]^aiLight, 561 | mNumCameras: u32, 562 | mCameras: [^]^aiCamera, 563 | } 564 | 565 | aiSkeletons :: struct {} // TODO: aiSkeletons 566 | 567 | aiMetaData :: struct {} // TODO: aiMetaData 568 | 569 | 570 | // flags 571 | aiPostProcessSteps :: enum u32 { 572 | CalcTangentSpace = 0x1, 573 | JoinIdenticalVertices = 0x2, 574 | MakeLeftHanded = 0x4, 575 | Triangulate = 0x8, 576 | RemoveComponent = 0x10, 577 | GenNormals = 0x20, 578 | GenSmoothNormals = 0x40, 579 | SplitLargeMeshes = 0x80, 580 | PreTransformVertices = 0x100, 581 | LimitBoneWeights = 0x200, 582 | ValidateDataStructure = 0x400, 583 | ImproveCacheLocality = 0x800, 584 | RemoveRedundantMaterials = 0x1000, 585 | FixInfacingNormals = 0x2000, 586 | SortByPType = 0x8000, 587 | FindDegenerates = 0x10000, 588 | FindInvalidData = 0x20000, 589 | GenUVCoords = 0x40000, 590 | TransformUVCoords = 0x80000, 591 | FindInstances = 0x100000, 592 | OptimizeMeshes = 0x200000, 593 | OptimizeGraph = 0x400000, 594 | FlipUVs = 0x800000, 595 | FlipWindingOrder = 0x1000000, 596 | } 597 | 598 | aiProcessPreset_TargetRealtime_Quality :: 599 | aiPostProcessSteps.CalcTangentSpace | 600 | aiPostProcessSteps.GenSmoothNormals | 601 | aiPostProcessSteps.JoinIdenticalVertices | 602 | aiPostProcessSteps.ImproveCacheLocality | 603 | aiPostProcessSteps.LimitBoneWeights | 604 | aiPostProcessSteps.RemoveRedundantMaterials | 605 | aiPostProcessSteps.SplitLargeMeshes | 606 | aiPostProcessSteps.Triangulate | 607 | aiPostProcessSteps.GenUVCoords | 608 | aiPostProcessSteps.SortByPType | 609 | aiPostProcessSteps.FindDegenerates | 610 | aiPostProcessSteps.FindInvalidData 611 | 612 | aiProcessPreset_TargetRealtime_MaxQuality :: 613 | aiProcessPreset_TargetRealtime_Quality | 614 | aiPostProcessSteps.FindInstances | 615 | aiPostProcessSteps.ValidateDataStructure | 616 | aiPostProcessSteps.OptimizeMeshes 617 | --------------------------------------------------------------------------------