### vcpkg: Install Assimp Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/about/quickstart This sequence of commands uses the vcpkg dependency manager to clone the repository, bootstrap the installation, integrate it with your system, and finally install the Assimp library. This is a convenient way to manage Assimp as a dependency. ```bash git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh ./vcpkg integrate install vcpkg install assimp ``` -------------------------------- ### Logging Setup - C++ Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/developer/developer Sets up verbose logging to a file named 'AssimpLog.txt' using the DefaultLogger class. This is crucial for debugging importer issues and understanding the parsing process. ```cpp DefaultLogger::create("AssimpLog.txt", Logger::VERBOSE) ``` -------------------------------- ### Filling Materials Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Details on how to set and query keys in `#ai_material` structures using definitions from `MaterialSystem.h`. Includes examples for setting shininess, name, and diffuse textures. ```APIDOC ## Filling Materials The required definitions to set/remove/query keys in `#ai_material` structures are declared in `MaterialSystem.h`, in a `#aiMaterial` derivate called `#aiMaterial`. The header is included by AssimpPCH.h, so you don't need to bother. :: aiMaterial* mat = new aiMaterial(); const float spec = 16.f; mat->AddProperty(&spec, 1, AI_MATKEY_SHININESS); //set the name of the material: NewMaterial->AddProperty(&aiString(MaterialName.c_str()), AI_MATKEY_NAME);//MaterialName is a std::string //set the first diffuse texture NewMaterial->AddProperty(&aiString(Texturename.c_str()), AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));//again, Texturename is a std::string ``` -------------------------------- ### Assimp Profiling Report Example Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib A sample log output demonstrating Assimp's basic profiling results when the GLOB_MEASURE_TIME configuration switch is enabled. It shows the timing breakdown for different stages of the import and post-processing pipeline. ```log Debug, T5488: START `total` Info, T5488: Found a matching importer for this file format Debug, T5488: START `import` Info, T5488: BlendModifier: Applied the `Subdivision` modifier to `OBMonkey` Debug, T5488: END `import`, dt= 3.516 s Debug, T5488: START `preprocess` Debug, T5488: END `preprocess`, dt= 0.001 s Info, T5488: Entering post processing pipeline Debug, T5488: START `postprocess` Debug, T5488: RemoveRedundantMatsProcess begin Debug, T5488: RemoveRedundantMatsProcess finished Debug, T5488: END `postprocess`, dt= 0.001 s Debug, T5488: START `postprocess` Debug, T5488: TriangulateProcess begin Info, T5488: TriangulateProcess finished. All polygons have been triangulated. Debug, T5488: END `postprocess`, dt= 3.415 s Debug, T5488: START `postprocess` Debug, T5488: SortByPTypeProcess begin Info, T5488: Points: 0, Lines: 0, Triangles: 1, Polygons: 0 (Meshes, X = removed) Debug, T5488: SortByPTypeProcess finished Debug, T5488: START `postprocess` Debug, T5488: JoinVerticesProcess begin ``` -------------------------------- ### C++: Assimp Android Integration Example Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/about/quickstart This C++ code snippet demonstrates how to integrate Assimp with an Android application using the AndroidJNIIOSystem. It shows the initialization of the Assimp importer and setting the custom IO handler for Android asset access. ```cpp #include Assimp::Importer* importer = new Assimp::Importer(); Assimp::AndroidJNIIOSystem *ioSystem = new Assimp::AndroidJNIIOSystem(app->activity); if ( nullptr != iosSystem ) { importer->SetIOHandler(ioSystem); } ``` -------------------------------- ### Exporting Models with Assimp Exporter Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Provides an example of exporting a scene loaded by Assimp into a specified file format. It demonstrates initializing the Assimp Importer and Exporter, reading a model file, and then exporting the scene to a new file, such as an OBJ. ```cpp bool exporterTest() override { ::Assimp::Importer importer; ::Assimp::Exporter exporter; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", aiProcess_ValidateDataStructure); exporter.Export(scene, "obj", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_out.obj"); return true; } ``` -------------------------------- ### Pseudo Code: Evaluate Texture Stack Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib A pseudo-code example illustrating how to evaluate multiple textures stacked on top of each other for a specific material property, like diffuse color. It handles different blend operations such as addition and multiplication. ```pseudo // --------------------------------------------------------------------------------------- // Evaluate multiple textures stacked on top of each other float3 EvaluateStack(stack) { // For the 'diffuse' stack.base_color would be COLOR_DIFFUSE // and TEXTURE(aiTextureType_DIFFUSE,n) the n'th texture. float3 base = stack.base_color; for (every texture in the stack) { // assuming we have explicit & pre transformed UVs for this texture float3 color = SampleTexture(texture,uv); // scale by texture blend factor color *= texture.blend; if (texture.op == add) base += color; else if (texture.op == multiply) base *= color; else // other blend ops go here } return base; } ``` -------------------------------- ### Custom Importer Implementation Example (C++) Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/developer/developer This example shows a basic implementation of a custom Assimp importer. It inherits from BaseImporter and overrides CanRead and InternReadFile methods. The CanRead method checks the file extension for format detection. Error handling and logging mechanisms are also mentioned. ```cpp class MyyImporter : public BaseImporter { public: MyyImporter() : BaseImporter = default; MyyImporter() override = default; bool CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const override { if (checkSig) { // Check the signature and return the result } else { const std::string extension = GetExtension(filename)); if ( extension == "myExt) { return true; } } return false; } void InternReadFile() { // Add your code here } }; ``` -------------------------------- ### C++ Custom IOStream and IOSystem Implementation for Assimp Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Demonstrates creating custom IOStream and IOSystem classes that inherit from Assimp's base classes. These custom implementations allow Assimp to read and write files using user-defined logic. The example includes methods for reading, writing, seeking, and file size, as well as checking file existence and opening/closing custom streams. ```cpp #include #include // My own implementation of IOStream class MyIOStream : public Assimp::IOStream { friend class MyIOSystem; protected: // Constructor protected for private usage by MyIOSystem MyIOStream(); public: ~MyIOStream(); size_t Read( void* pvBuffer, size_t pSize, size_t pCount) { /* ... */ return 0; } size_t Write( const void* pvBuffer, size_t pSize, size_t pCount) { /* ... */ return 0; } aiReturn Seek( size_t pOffset, aiOrigin pOrigin) { /* ... */ return AI_SUCCESS; } size_t Tell() const { /* ... */ return 0; } size_t FileSize() const { /* ... */ return 0; } void Flush () { /* ... */ } }; // Fisher Price - My First Filesystem class MyIOSystem : public Assimp::IOSystem { MyIOSystem() { /* ... */ } ~MyIOSystem() { /* ... */ } // Check whether a specific file exists bool Exists( const std::string& pFile) const { // ... return false; } // Get the path delimiter character we'd like to see char GetOsSeparator() const { return '/'; } // ... and finally a method to open a custom stream IOStream* Open( const std::string& pFile, const std::string& pMode) { return new MyIOStream( /* ... */ ); } void Close( IOStream* pFile) { delete pFile; } }; ``` -------------------------------- ### Unit Test Structure for Importer/Exporter - C++ Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/developer/developer Defines a unit test class `utMyImporter` that inherits from `AbstractImportExportBase`. The `importerTest` method demonstrates how to load a file using Assimp::Importer and validate the scene structure, essential for verifying custom importers. ```cpp #include "AbstractImportExportBase.h" #include "UnitTestPCH.h" // Add more depending includes based on your test class utMyImporter : public AbstractImportExportBase { public: bool importerTest() override { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MyFormat/Wuson.myformat", aiProcess_ValidateDataStructure); return nullptr != scene; } }; TEST_F(utMyImporter, importTest) { EXPECT_TRUE(importerTest()); } ``` -------------------------------- ### Implementing a Custom Importer Base Class - C++ Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/developer/developer Provides a basic structure for a custom importer by inheriting from Assimp::BaseImporter. It includes the essential CanRead and InternReadFile methods, along with GetExtensionList, demonstrating format detection and file parsing logic. ```cpp class MyyImporter : public BaseImporter { public: MyyImporter() : BaseImporter = default; MyyImporter() override = default; bool CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const override { if (checkSig) { // Check the signature and return the result } else { const std::string extension = GetExtension(filename)); if ( extension == "myExt) { return true; } } return false; } void InternReadFile() { // Add your code here } }; ``` -------------------------------- ### C++ Importer: Get Handled File Extensions Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Retrieves a set of file extensions that this importer class can handle. This is used to efficiently filter files based on their extensions. ```cpp // ------------------------------------------------------------------------------- // Get list of file extensions handled by this loader void xxxxImporter::GetExtensionList(std::set& extensions) { extensions.insert("xxx"); } ``` -------------------------------- ### Registering a New Importer - C++ Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/developer/developer This code demonstrates how to conditionally include a new importer's source file in the ImporterRegistry.cpp, guarded by a preprocessor directive. It ensures the importer is only compiled when specific build configurations are enabled. ```cpp #if (!defined assimp_BUILD_NO_FormatName_IMPORTER) ... #endif ``` -------------------------------- ### Parse XML Data and Iterate Nodes with C++ XMLParser Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/developer/developer This C++ snippet demonstrates how to use the XMLParser to load and parse data from a stream, retrieve the root node, find a specific child node, and iterate over its children. It requires including the 'XmlParser.h' header. ```cpp #include void parse_and_validate_xml(Stream *mySteam) { // Read the data and parse the XML-File XMLParser xmlParser; if (xmlParser.parse(stream)) { // Get the root node XmlNode node = xmlParser.getRootNode(); // Find one special child node XmlNode colladaNode = node.child("COLLADA"); // Iterate over all children for ( auto child : colladaNode.children()) { } } } ``` -------------------------------- ### Iterate Over XML Nodes with XML-Parser Iterator in C++ Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/developer/developer This C++ code illustrates how to use the XmlNodeIterator to traverse all XML nodes in a pre-order fashion. It initializes an iterator with a given node and mode, then retrieves and processes each node sequentially using getNext(). ```cpp XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); XmlNode currentNode; while (xmlIt.getNext(currentNode)) { // all nodes will be iterated level wise } ``` -------------------------------- ### Parse and Validate XML with XML-Parser in C++ Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/developer/developer This C++ snippet demonstrates how to include the XMLParser header, create an XMLParser instance, parse an input stream, retrieve the root node, find a specific child node, and iterate over its children. It assumes the existence of a Stream object and basic XmlNode functionality. ```cpp #include void parse_and_validate_xml(Stream *mySteam) { // Read the data and parse the XML-File XMLParser xmlParser; if (xmlParser.parse(stream)) { // Get the root node XmlNode node = xmlParser.getRootNode(); // Find one special child node XmlNode colladaNode = node.child("COLLADA"); // Iterate over all children for ( auto child : colladaNode.children()) { } } } ``` -------------------------------- ### Enabling and Interpreting Assimp Profiling Output Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Shows how to enable Assimp's built-in profiling by setting the GLOB_MEASURE_TIME configuration switch to true. It includes a sample log output detailing the time spent in different stages of the import and post-processing pipeline. This helps in identifying performance bottlenecks. ```text Debug, T5488: START `total` Info, T5488: Found a matching importer for this file format Debug, T5488: START `import` Info, T5488: BlendModifier: Applied the `Subdivision` modifier to `OBMonkey` Debug, T5488: END `import`, dt= 3.516 s Debug, T5488: START `preprocess` Debug, T5488: END `preprocess`, dt= 0.001 s Info, T5488: Entering post processing pipeline Debug, T5488: START `postprocess` Debug, T5488: RemoveRedundantMatsProcess begin Debug, T5488: RemoveRedundantMatsProcess finished Debug, T5488: END `postprocess`, dt= 0.001 s Debug, T5488: START `postprocess` Debug, T5488: TriangulateProcess begin Info, T5488: TriangulateProcess finished. All polygons have been triangulated. Debug, T5488: END `postprocess`, dt= 3.415 s Debug, T5488: START `postprocess` Debug, T5488: SortByPTypeProcess begin Info, T5488: Points: 0, Lines: 0, Triangles: 1, Polygons: 0 (Meshes, X = removed) Debug, T5488: SortByPTypeProcess finished Debug, T5488: START `postprocess` Debug, T5488: JoinVerticesProcess begin Debug, T5488: Mesh 0 (unnamed) | Verts in: 503808 out: 126345 | ~74.922 Info, T5488: JoinVerticesProcess finished | Verts in: 503808 out: 126345 | ~74.9 Debug, T5488: END `postprocess`, dt= 2.052 s Debug, T5488: START `postprocess` Debug, T5488: FlipWindingOrderProcess begin Debug, T5488: FlipWindingOrderProcess finished Debug, T5488: END `postprocess`, dt= 0.006 s Debug, T5488: START `postprocess` Debug, T5488: LimitBoneWeightsProcess begin Debug, T5488: LimitBoneWeightsProcess end Debug, T5488: END `postprocess`, dt= 0.001 s Debug, T5488: START `postprocess` Debug, T5488: ImproveCacheLocalityProcess begin Debug, T5488: Mesh 0 | ACMR in: 0.851622 out: 0.718139 | ~15.7 Info, T5488: Cache relevant are 1 meshes (251904 faces). Average output ACMR is 0.718139 Debug, T5488: ImproveCacheLocalityProcess finished. Debug, T5488: END `postprocess`, dt= 1.903 s Info, T5488: Leaving post processing pipeline Debug, T5488: END `total`, dt= 11.269 s ``` -------------------------------- ### Material System Overview Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Provides an overview of the material system, including how materials are stored and referenced by meshes. ```APIDOC ## Material System Overview ### Description Details the structure and organization of materials within the `aiScene`, emphasizing their property-based definition. ### General Overview - **Storage**: Materials are stored in an array of `aiMaterial` within the `aiScene`. - **Mesh Reference**: Each `aiMesh` references a material by its index in the `aiMaterial` array. - **Definition**: Materials are defined by a set of properties accessible by name, rather than a rigid structure. Refer to `assimp/material.h` for property definitions and retrieval functions. ``` -------------------------------- ### General Importer Properties and Notes Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib General guidelines for developing text importers and how to handle properties within the assimp framework. ```APIDOC ## Properties You can use properties to change the behavior of your importer. Override `BaseImporter::SetupProperties` and specify custom properties in `config.h`. Consult other `AI_CONFIG_IMPORT_*` defines for examples. Properties can be set with `Importer::SetProperty***()` and accessed with `Importer::GetProperty***()`. They can be stored as member variables and are thread-safe. ## Notes for text importers * Make your parser flexible, avoiding reliance on specific layout or whitespace unless the file format strictly defines it. Warn about spec violations but be strict in writing and tolerant in accepting. * Call `Assimp::BaseImporter::ConvertToUTF8()` before parsing to convert foreign encodings to UTF-8. This is not necessary for XML importers that use the provided XML-Parser. ``` -------------------------------- ### Detaching Log Messages from Assimp Logger Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Illustrates how to detach specific log message severities from a custom log stream. This allows fine-grained control over which types of messages are processed by a particular stream, for example, only receiving debug messages. ```cpp unsigned int severity = 0; severity |= Logger::Debugging; // Detach debug messages from your self defined stream Assimp::DefaultLogger::get()->attachStream( new myStream, severity ); ``` -------------------------------- ### Pseudo Code for Material Evaluation Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Provides a rough pseudo-code sample demonstrating how to evaluate Assimp materials within a shading pipeline, including texture stacking and contribution calculations. ```APIDOC ## Pseudo Code Listing ### Description This pseudo-code sample illustrates how to evaluate Assimp material properties in a shading pipeline, focusing on real-time graphics with shader-based rendering. It includes functions for evaluating stacked textures and computing diffuse, specular, and ambient contributions. ### Method Pseudo-code functions for rendering pipeline evaluation. ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c // Evaluate multiple textures stacked on top of each other float3 EvaluateStack(stack) { // For the 'diffuse' stack.base_color would be COLOR_DIFFUSE // and TEXTURE(aiTextureType_DIFFUSE,n) the n'th texture. float3 base = stack.base_color; for (every texture in the stack) { // assuming we have explicit & pre transformed UVs for this texture float3 color = SampleTexture(texture, uv); // scale by texture blend factor color *= texture.blend; if (texture.op == add) base += color; else if (texture.op == multiply) base *= color; else // other blend ops go here } return base; } // Compute the diffuse contribution for a pixel float3 ComputeDiffuseContribution() { if (shading == none) return float3(1,1,1); float3 intensity (0,0,0); for (all lights in range) { float fac = 1.f; if (shading == gouraud) fac = lambert-term .. else // other shading modes go here // handling of different types of lights, such as point or spot lights // ... // and finally sum the contribution of this single light ... intensity += light.diffuse_color * fac; } // ... and combine the final incoming light with the diffuse color return EvaluateStack(diffuse) * intensity; } // Compute the specular contribution for a pixel float3 ComputeSpecularContribution() { if (shading == gouraud || specular_strength == 0 || specular_exponent == 0) return float3(0,0,0); float3 intensity (0,0,0); for (all lights in range) { float fac = 1.f; if (shading == phong) fac = phong-term .. else // other specular shading modes go here // handling of different types of lights, such as point or spot lights // ... // and finally sum the specular contribution of this single light ... intensity += light.specular_color * fac; } // ... and combine the final specular light with the specular color return EvaluateStack(specular) * intensity * specular_strength; } // Compute the ambient contribution for a pixel float3 ComputeAmbientContribution() { if (shading == none) return float3(0,0,0); float3 intensity (0,0,0); // ... calculation for ambient light ... return intensity; } ``` ### Response #### Success Response - **Rendering Output** - Pseudo-code outlines the process for calculating pixel colors based on material properties and lighting. #### Response Example ```json // No direct JSON response, describes algorithmic logic. ``` ``` -------------------------------- ### Build Assimp as DLL using CMake Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/about/quickstart This snippet explains how to build the Assimp library as a Dynamic Link Library (DLL) using CMake. It indicates that the default CMake configuration process is sufficient for this purpose. No specific input parameters are required, and the output is a DLL file. ```text cmake .. make ``` -------------------------------- ### Wrap Assimp for Android using C++ Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/about/quickstart This C++ code demonstrates how to wrap the Assimp library for Android. It includes setting up an Assimp importer and an Android-specific IO system, which is crucial for file handling on Android devices. Dependencies include the Assimp library and Android NDK headers. ```cpp #include Assimp::Importer* importer = new Assimp::Importer(); Assimp::AndroidJNIIOSystem *ioSystem = new Assimp::AndroidJNIIOSystem(app->activity); if ( nullptr != ioSystem ) { importer->SetIOHandler(ioSystem); } ``` -------------------------------- ### IO-System API Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/API/API-Documentation Details the Input/Output system components of ASSIMP, including IOSystem, IOStream, IOStreamBuffer, memory-based IO, and default implementations. ```APIDOC ## IO-System API Details the Input/Output system components of ASSIMP. ### Classes - **Assimp::IOSystem**: Interface for I/O systems. - **Assimp::IOStream**: Interface for I/O streams. - **Assimp::IOStreamBuffer**: Buffer for IOStream. - **Assimp::MemoryIOStream**: In-memory IO stream. - **Assimp::DefaultIOSystem**: Default implementation of IOSystem. - **Assimp::DefaultIOStream**: Default implementation of IOStream. - **Assimp::MemoryIOSystem**: Memory-based IO system. - **Assimp::BlobIOStream**: IO stream for blob data. - **Assimp::BlobIOSystem**: IO system for blob data. ``` -------------------------------- ### UV Channel Mapping (MATKEY_UVWSRC) Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Explains how to handle UV channels when the source format does not provide explicit mapping, offering a recommended logic. ```APIDOC ## How to map UV channels to textures (MATKEY_UVWSRC) ### Description The MATKEY_UVWSRC property indicates how UV channels should be mapped to textures. This section provides a recommended logic for handling cases where the source format doesn't specify an explicit mapping. ### Method Logic-based handling using texture properties. ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ``` // Recommended logic for UV channel mapping: if (number of UV channels == 1) { assign channel 0 to all textures and break } for each texture: if (texture has uvwsrc property): assign channel specified in uvwsrc else: assign channels in ascending order for all texture stacks (e.g., diffuse1 gets channel 1, opacity0 gets channel 0) ``` ### Response #### Success Response - **UV Channel Assignment** - Textures are assigned to appropriate UV channels based on the logic. #### Response Example ```json // No direct JSON response, describes a process. ``` ``` -------------------------------- ### Notes for Text Importers Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Guidelines for creating flexible text parsers. Emphasizes tolerance in accepting input while being strict in output. Suggests converting foreign encodings to UTF-8 using Assimp::BaseImporter::ConvertToUTF8(). ```APIDOC ## Notes for Text Importers * Try to make your parser as flexible as possible. Don't rely on particular layout, whitespace/tab style, except if the file format has a strict definition, in which case you should always warn about spec violations. But the general rule of thumb is *be strict in what you write and tolerant in what you accept*. * Call **Assimp::BaseImporter::ConvertToUTF8()** before you parse anything to convert foreign encodings to UTF-8. That's not necessary for XML importers, which must use the provided XML-Parser for reading. ``` -------------------------------- ### Check for Embedded Textures in Assimp Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib This example shows how to check if a texture is embedded within the model file using Assimp's `GetEmbeddedTexture` function. If the function returns a non-null pointer, the texture is embedded and can be accessed directly from the `aiTexture` structure. Otherwise, it suggests searching for a separate texture file. ```cpp const aiScene* scene = importer.ReadFile(filePath, postProcessFlags); // ... iterate through materials and meshes ... const aiTexture* embeddedTexture = scene->GetEmbeddedTexture(texturePath); if (embeddedTexture != nullptr) { // Texture is embedded, load from aiTexture structure } else { // Texture is not embedded, search for a separate file } ``` -------------------------------- ### Logging with Assimp's DefaultLogger Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Demonstrates how to create, use, and kill the default logger instance in Assimp. This allows for logging messages at different severity levels (e.g., info). It's important to manage the logger's lifecycle by creating and killing the singleton instance. ```cpp using namespace Assimp; // Create a logger instance DefaultLogger::create("", Logger::VERBOSE); // Now I am ready for logging my stuff DefaultLogger::get()->info("this is my info-call"); // Kill it after the work is done DefaultLogger::kill(); ``` -------------------------------- ### CMake: Link Assimp Library Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/about/quickstart After adding Assimp as a subdirectory, this command links the Assimp library to your target application. This makes the Assimp functionalities available for use in your project. ```cmake TARGET_LINK_LIBRARIES(my_game assimp) ``` -------------------------------- ### Assimp Unit Test Structure (C++) Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/developer/developer This code snippet defines a unit test class for an Assimp importer. It inherits from AbstractImportExportBase and implements the importerTest method, which uses Assimp::Importer to load a test file and checks if the scene is valid. The TEST_F macro is used to define the actual test case. ```cpp #include "AbstractImportExportBase.h" #include "UnitTestPCH.h" // Add more depending includes based on your test class utMyImporter : public AbstractImportExportBase { public: bool importerTest() override { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MyFormat/Wuson.myformat", aiProcess_ValidateDataStructure); return nullptr != scene; } }; TEST_F(utMyImporter, importTest) { EXPECT_TRUE(importerTest()); } ``` -------------------------------- ### aiNode and aiMesh Structure Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Explains the relationship between aiNode and aiMesh, and how transformations are applied in a scene hierarchy. ```APIDOC ## Node Structure ### Description An aiNode represents a node in a scene hierarchy. It can reference one or more aiMesh objects and holds its own transformation matrix. ### Method N/A (Conceptual Explanation) ### Endpoint N/A ### Parameters None ### Request Example None ### Response #### Success Response (N/A) - **aiNode** (object) - Represents a node in the scene graph. - **mName** (string) - The name of the node. - **mTransformation** (Matrix4x4) - The local transformation matrix of the node. - **mNumMeshes** (integer) - The number of meshes this node refers to. - **mMeshes** (array of integers) - Indices into the aiScene::mMeshes array. - **mNumChildren** (integer) - The number of child nodes. - **mChildren** (array of aiNode pointers) - Child nodes. #### Response Example None ## aiMesh Structure ### Description An aiMesh represents a single mesh in a scene. It contains vertex data, face information, and material indices. ### Method N/A (Conceptual Explanation) ### Endpoint N/A ### Parameters None ### Request Example None ### Response #### Success Response (N/A) - **aiMesh** (object) - Represents a mesh. - **mName** (string) - The name of the mesh. - **mVertices** (array of vec3) - The vertices of the mesh. - **mNormals** (array of vec3) - The normals of the mesh. - **mTangents** (array of vec3) - The tangents of the mesh. - **mBitangents** (array of vec3) - The bitangents of the mesh. - **mTextureCoords** (array of arrays of vec2) - Texture coordinates (up to AI_MAX_NUMBER_OF_TEXTURECOORDS). - **mColors** (array of arrays of ColorRGBA) - Vertex colors (up to AI_MAX_NUMBER_OF_COLOR_SETS). - **mFaces** (array of aiFace) - The faces (triangles/polygons) of the mesh. - **mMaterialIndex** (integer) - Index into the aiScene::mMaterials array. - **mBones** (array of aiBone pointers) - Bones affecting the mesh. #### Response Example None ``` -------------------------------- ### Android CMake Options for Assimp Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/about/quickstart This snippet details CMake options for building Assimp on Android, specifically highlighting the ANDROID_ABI flag for setting the target ABI. It assumes a CMake build environment. ```text -DANDROID_ABI= ``` -------------------------------- ### Ogre Importer - Overview and Loading Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Details on the Ogre importer's capabilities, focusing on what mesh, material, and skeleton data can be loaded. It also mentions the Ogre exporter optimization for Blender. ```APIDOC ## Ogre Importer ### Description This section contains implementation notes for the OgreXML importer. The importer is currently optimized for the Blender Ogre exporter. ### What will be loaded? * **Mesh**: Faces, Positions, Normals, and all TexCoords. The Materialname will be used to load the material. * **Material**: Searches for the right material in the file. Supports materials with 1 technique and 1 pass. Loads texture name (for 1 color- and 1 normal map) and material colors (not in custom materials). Sets the material name. * **Skeleton**: Skeleton with Bone hierarchy (Position and Rotation, no Scaling support), names and transformations, animations with rotation, translation and scaling keys. ### XML-Format The Ogre loader can only handle XML mesh files. A command-line converter is available to create XML files from Binary Files. The importer attempts to load the appended material and skeleton files automatically. The skeleton file must have the same name as the mesh file (e.g., `fish.mesh.xml` and `fish.skeleton.xml`). The material file can have the same name as the mesh file (e.g., `model.mesh.xml` will try to load `model.material`). Alternatively, the material file can be specified using `Importer::SetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "materialfile.material")`. ``` -------------------------------- ### Notes for Binary Importers Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Important considerations for binary importers, including handling endianness issues and validating input data, especially offsets. ```APIDOC ## Notes for Binary Importers * Take care of endianness issues! Assimp importers mostly support big-endian platforms, which define the `AI_BUILD_BIG_ENDIAN` constant. See the next section for a list of utilities to simplify this task. * Don't trust the input data! Check all offsets! ``` -------------------------------- ### Logging API Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/API/API-Documentation Documentation for the logging facilities within ASSIMP, including the Logger, LogStream, DefaultLogger, and NullLogger classes. ```APIDOC ## Logging API Documentation for the logging facilities within ASSIMP. ### Classes - **Assimp::Logger**: Abstract base class for loggers. - **Assimp::LogStream**: Abstract base class for log streams. - **Assimp::DefaultLogger**: Default logger implementation. - **Assimp::NullLogger**: A logger that discards all messages. ``` -------------------------------- ### C++ API - Retrieving Material Properties Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Demonstrates how to retrieve material properties using the C++ API, specifically the `aiMaterial::Get()` function. ```APIDOC ## C++ API - Retrieving Material Properties Retrieving a property from a material is done using utility functions. For C++, this involves calling `aiMaterial::Get()`. ### Generic Property Retrieval ```cpp aiMaterial* mat = ..... // The generic way if(AI_SUCCESS != mat->Get(, )) { // handle epic failure here } ``` ### Retrieving Material Name To get the name of a material, you would use the `AI_MATKEY_NAME` key: ```cpp aiString name; mat->Get(AI_MATKEY_NAME, name); ``` ``` -------------------------------- ### Import/Export API Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/API/API-Documentation Information on the core classes for importing and exporting 3D model files using ASSIMP. ```APIDOC ## Import/Export API Information on the core classes for importing and exporting 3D model files. ### Classes - **Assimp::BaseImporter**: Base class for importers. - **Assimp::Importer**: Main class for importing models. - **Assimp::Exporter**: Class for exporting models. ``` -------------------------------- ### Mapping UV Channels to Textures (MATKEY_UVWSRC) Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Provides a recommended logic for flexibly handling UV channels and mapping them to textures, especially when the source format doesn't explicitly define this relationship. ```APIDOC ## Mapping UV Channels to Textures (MATKEY_UVWSRC) ### Description This section outlines a recommended approach for handling UV channels when the `MATKEY_UVWSRC` property is present or implied. This is crucial for formats that do not explicitly map textures to UV channels. ### Recommended Logic ``` If there is only one UV channel: Assign channel 0 to all textures and break. For each texture: If `UVWSRC` is defined for this texture: Assign the channel specified in `UVWSRC`. Else: Assign channels in ascending order for all texture stacks. (e.g., diffuse1 gets channel 1, opacity0 gets channel 0). ``` ### Notes Assimp may not always be aware of the perfect rule for mapping UV channels, so flexible handling is advised. ``` -------------------------------- ### C++ Setting Custom IO Handler for Assimp Importer Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Shows how to integrate a custom IO system with Assimp's Importer. After creating an instance of your custom IOSystem, you pass it to the Importer using the SetIOHandler method. This ensures that subsequent file import operations use your custom IO logic. ```cpp void DoTheImportThing( const std::string& pFile) { Assimp::Importer importer; // put my custom IO handling in place importer.SetIOHandler( new MyIOSystem()); // the import process will now use this implementation to access any file importer.ReadFile( pFile, SomeFlag | SomeOtherFlag); } ``` -------------------------------- ### Ogre Importer - Blender Export Settings Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Specific settings required when exporting from Blender to ensure compatibility with the assimp Ogre importer. ```APIDOC ## How to export Files from Blender To ensure correct loading by the assimp importer, the following options should be considered during export from Blender: * Use either "Rendering Material" or "Custom Material" (see @ref material). * Do not use "Flip Up Axies to Y". * Use "Skeleton name follow mesh". ``` -------------------------------- ### C++ API: Retrieving Material Properties Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Demonstrates how to retrieve material properties using the C++ API's `aiMaterial::Get()` method. ```APIDOC ## C++ API: Retrieving Material Properties ### Description Retrieving a property from a material is done using the `aiMaterial::Get()` method. This method is a template with explicit specializations for various data types. ### Method `aiMaterial::Get()` ### Parameters * **`key`**: The material property key (e.g., `AI_MATKEY_NAME`, `AI_MATKEY_COLOR_DIFFUSE`). * **`where-to-store`**: A pointer to a variable where the retrieved property will be stored. The type of this variable must match the expected data type of the material property. ### Request Example ```cpp aiMaterial* mat = ..... // Get material name aiString name; if(AI_SUCCESS == mat->Get(AI_MATKEY_NAME, name)) { // Use the name } // Get diffuse color aiColor3D color(0.f, 0.f, 0.f); if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE, color)) { // Use the color } // Generic way (handle potential type mismatches carefully) if(AI_SUCCESS != mat->Get(, )) { // handle epic failure here } ``` ### Response * **Success Response (AI_SUCCESS)**: The property is successfully retrieved and stored in the provided variable. * **Error Response (non-AI_SUCCESS)**: An error occurred during retrieval. ``` -------------------------------- ### Texture Stacks Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib Explains how textures are organized into independent stacks and how their results are combined in the shading equation. ```APIDOC ## Texture Stacks ### Description Describes the organization of textures into independent evaluation stacks and their contribution to the final shading. ### Organization - Textures are organized in stacks, with each stack evaluated independently. - The final color value from a texture stack is used in the shading equation. ### Example Shading Equation Component | Stack | Resulting equation | |-------------------|--------------------| | Constant base color | color | | Blend operation 0 | + | | Strength factor 0 | 0.25* | | Texture 0 | texture_0 | | Blend operation 1 | x | | Strength factor 1 | 1.0* | | Texture 1 | texture_1 | ``` -------------------------------- ### Set Material Properties in C++ Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Demonstrates how to set various material properties such as shininess, name, and diffuse texture using the aiMaterial class in C++. It utilizes the AddProperty method to associate values with predefined material keys. ```cpp aiMaterial* mat = new aiMaterial(); const float spec = 16.f; mat->AddProperty(&spec, 1, AI_MATKEY_SHININESS); //set the name of the material: NewMaterial->AddProperty(&aiString(MaterialName.c_str()), AI_MATKEY_NAME);//MaterialName is a std::string //set the first diffuse texture NewMaterial->AddProperty(&aiString(Texturename.c_str()), AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));//again, Texturename is a std::string ``` -------------------------------- ### Utilities Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/_sources/usage/use_the_lib A collection of mixed utilities for internal use by loaders, primarily for binary data handling, parsing, and scene manipulation. ```APIDOC ## Utilities Mixed stuff for internal use by loaders, mostly documented (most of them are already included by *AssimpPCH.h*): * **ByteSwapper** (*ByteSwapper.h*) - manual byte swapping stuff for binary loaders. * **StreamReader** (*StreamReader.h*) - safe, endianess-correct, binary reading. * **XmlParser** (*XmlParser.hh*) - The XML-Parser used in Asset-importer-Lib * **CommentRemover** (*RemoveComments.h*) - remove single-line and multi-line comments from a text file. * fast_atof, strtoul10, strtoul16, SkipSpaceAndLineEnd, SkipToNextToken .. large family of low-level parsing functions, mostly declared in *fast_atof.h*, *StringComparison.h* and *ParsingUtils.h* (a collection that grew historically, so don't expect perfect organization). * **ComputeNormalsWithSmoothingsGroups()** (*SmoothingGroups.h*) - Computes normal vectors from plain old smoothing groups. * **SkeletonMeshBuilder** (*SkeletonMeshBuilder.h*) - generate a dummy mesh from a given (animation) skeleton. * **StandardShapes** (*StandardShapes.h*) - generate meshes for standard solids, such as platonic primitives, cylinders or spheres. * **BatchLoader** (*BaseImporter.h*) - manage imports from external files. Useful for file formats which spread their data across multiple files. * **SceneCombiner** (*SceneCombiner.h*) - exhaustive toolset to merge multiple scenes. Useful for file formats which spread their data across multiple files. ``` -------------------------------- ### Evaluate Texture Stacks in Shading Pipeline Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Demonstrates how to evaluate multiple textures stacked on top of each other for material properties like base color. It iterates through textures in a stack, samples them using provided UVs, and applies blend operations (add, multiply) to accumulate the final color. Assumes pre-transformed UVs. ```pseudo // --------------------------------------------------------------------------------------- // Evaluate multiple textures stacked on top of each other float3 EvaluateStack(stack) { // For the 'diffuse' stack.base_color would be COLOR_DIFFUSE // and TEXTURE(aiTextureType_DIFFUSE,n) the n'th texture. float3 base = stack.base_color; for (every texture in the stack) { // assuming we have explicit & pre transformed UVs for this texture float3 color = SampleTexture(texture,uv); // scale by texture blend factor color *= texture.blend; if (texture.op == add) base += color; else if (texture.op == multiply) base *= color; else // other blend ops go here } return base; } ``` -------------------------------- ### Import Data using C Plain-C Interface Source: https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/usage/use_the_lib Illustrates importing a file using the C plain-C interface function aiImportFile. This method requires manual resource cleanup using aiReleaseImport. It takes a file path and post-processing flags, returning an aiScene pointer or NULL on failure. Error retrieval is done via aiGetErrorString. ```c #include #include #include bool DoTheImportThing( const char* pFile) { // Start the import on the given file with some example postprocessing // Usually - if speed is not the most important aspect for you - you'll t // probably to request more postprocessing than we do in this example. const struct aiScene* scene = aiImportFile( pFile, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType); // If the import failed, report it if( NULL == scene) { DoTheErrorLogging( aiGetErrorString()); return false; } // Now we can access the file's contents DoTheSceneProcessing( scene); // We're done. Release all resources associated with this import aiReleaseImport( scene); return true; } ```