### Install Assimp using vcpkg Source: https://github.com/assimp/assimp-docs/blob/master/source/about/quickstart.md Install Assimp using the vcpkg dependency manager. This command clones the vcpkg repository, bootstraps it, integrates it with your system, and then installs Assimp. ```bash git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh ./vcpkg integrate install vcpkg install assimp ``` -------------------------------- ### Custom Importer Implementation Example Source: https://github.com/assimp/assimp-docs/blob/master/source/developer/developer.md A basic C++ example of a custom importer class inheriting from Assimp::BaseImporter. Implement CanRead and InternReadFile methods to parse custom file formats. ```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 } }; ``` -------------------------------- ### Assimp Profiling Report Example Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md This log output shows the detailed timing of Assimp's import and post-processing steps. Enable profiling with GLOB_MEASURE_TIME. ```default 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 ``` -------------------------------- ### C++ API: Retrieving Material Properties Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Demonstrates how to get material properties using the `aiMaterial::Get()` method in C++. It covers the generic way to retrieve properties and specific examples for material name and diffuse color. ```APIDOC ## C++ API: Retrieving Material Properties ### Description Retrieving a property from a material is done using the `aiMaterial::Get()` method. ### Method `aiMaterial::Get()` ### Parameters - **material-key**: The key identifying the material property. - **where-to-store**: A reference to a variable where the property's value will be stored. ### Request Example ```cpp aiMaterial* mat = ..... // The generic way if(AI_SUCCESS != mat->Get(,)) { // handle epic failure here } // Get material name aiString name; mat->Get(AI_MATKEY_NAME, name); // Get diffuse color aiColor3D color (0.f,0.f,0.f); mat->Get(AI_MATKEY_COLOR_DIFFUSE, color); ``` ### Response - **Success Response (AI_SUCCESS)**: The property was successfully retrieved and stored in the provided variable. - **Error Response (non-AI_SUCCESS)**: An error occurred during retrieval. ### Notes `Get()` is a template with explicit specializations for `aiColor3D`, `aiColor4D`, `aiString`, `float`, `int`, and others. Ensure the data type of the second parameter matches the expected type of the material property to avoid unexpected results. ``` -------------------------------- ### Integrate Assimp with CMake Source: https://context7.com/assimp/assimp-docs/llms.txt Demonstrates two methods for integrating Assimp into a CMake project: adding it as a subdirectory or finding an installed package. Also shows build options for static libraries and presets. ```cmake # CMakeLists.txt - Add Assimp as subdirectory cmake_minimum_required(VERSION 3.10) project(MyProject) # Option 1: Add as subdirectory add_subdirectory(assimp) target_link_libraries(my_game assimp) # Option 2: Find installed package find_package(assimp REQUIRED) target_link_libraries(my_game assimp::assimp) # Static library build # cmake -G "Ninja" -DBUILD_SHARED_LIBS=OFF CMakeLists.txt # Available presets: # - assimp_static: Static library # - assimp_double_precision: Double precision support # - assimp_with_tools: Include command line tools # - assimp_all: Everything including tests and samples ``` -------------------------------- ### Implement Custom IOStream and IOSystem in C++ Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Provide custom implementations of IOStream and IOSystem when your application requires special logic to access files. This example shows the basic structure for MyIOStream and MyIOSystem. ```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) { ... } size_t Write( const void* pvBuffer, size_t pSize, size_t pCount) { ... } aiReturn Seek( size_t pOffset, aiOrigin pOrigin) { ... } size_t Tell() const { ... } size_t FileSize() const { ... } 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 { .. } // 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 for Importer Source: https://github.com/assimp/assimp-docs/blob/master/source/developer/developer.md Example of a unit test class for an importer using Assimp's testing utilities. It verifies if a file can be successfully read and parsed into an aiScene. ```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()); } ``` -------------------------------- ### Get Material Property (C) Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Use specific aiGetMaterial functions for retrieving material properties in the C API. Check the return value for success. ```c aiMaterial* mat = ..... if(AI_SUCCESS != aiGetMaterialFloat(mat,,)) { // handle epic failure here } ``` -------------------------------- ### Get Material Property (C++) Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Use aiMaterial::Get() to retrieve generic material properties. Ensure the data type parameter matches the expected property type to avoid unexpected results. ```cpp aiMaterial* mat = ..... // The generic way if(AI_SUCCESS != mat->Get(,)) { // handle epic failure here } ``` -------------------------------- ### Manual Build from Source Source: https://context7.com/assimp/assimp-docs/llms.txt Instructions for manually building Assimp from its source code using Git and CMake. ```bash git clone https://github.com/assimp/assimp.git cd assimp cmake CMakeLists.txt cmake --build . ``` -------------------------------- ### Setting Up Logging Source: https://github.com/assimp/assimp-docs/blob/master/source/developer/developer.md Initializes the Assimp logger to capture verbose output for debugging. Call this before importing any files. ```cpp DefaultLogger::create("AssimpLog.txt", Logger::VERBOSE) ``` -------------------------------- ### Get Material Name (C) Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Retrieve the material's name using AI_MATKEY_NAME with the C API function aiGetMaterialString(). ```c aiString name; aiGetMaterialString(mat,AI_MATKEY_NAME,&name); ``` -------------------------------- ### Create and Use Default Logger Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Demonstrates how to create, use, and kill the default Assimp logger instance. Ensure to kill the logger when done to release resources. ```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(); ``` -------------------------------- ### Get Material Name (C++) Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Retrieve the material's name using AI_MATKEY_NAME with the C++ aiMaterial::Get() function. ```cpp aiString name; mat->Get(AI_MATKEY_NAME,name); ``` -------------------------------- ### Implement Custom IOSystem for Memory Assets Source: https://context7.com/assimp/assimp-docs/llms.txt Develop a custom Assimp::IOSystem to manage custom IOStreams, enabling Assimp to load models from memory. This involves registering files and providing custom IOStream instances. ```cpp // Custom IOSystem implementation class MemoryIOSystem : public Assimp::IOSystem { private: std::map> mFiles; public: void AddFile(const std::string& path, const uint8_t* data, size_t size) { mFiles[path] = {data, size}; } bool Exists(const char* pFile) const override { return mFiles.find(pFile) != mFiles.end(); } char getOsSeparator() const override { return '/'; } Assimp::IOStream* Open(const char* pFile, const char*) override { auto it = mFiles.find(pFile); if (it != mFiles.end()) { return new MemoryIOStream(it->second.first, it->second.second); } return nullptr; } void Close(Assimp::IOStream* pFile) override { delete pFile; } }; // Usage example bool LoadFromMemory(const uint8_t* modelData, size_t dataSize) { Assimp::Importer importer; MemoryIOSystem* ioSystem = new MemoryIOSystem(); ioSystem->AddFile("model.fbx", modelData, dataSize); importer.SetIOHandler(ioSystem); // Importer takes ownership const aiScene* scene = importer.ReadFile("model.fbx", aiProcess_Triangulate | aiProcess_FlipUVs); return scene != nullptr; } ``` -------------------------------- ### Get Diffuse Color (C++) Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Fetch the diffuse color of a material using AI_MATKEY_COLOR_DIFFUSE with the C++ aiMaterial::Get() function. The color variable will not be modified if the property is not set. ```cpp aiColor3D color (0.f,0.f,0.f); mat->Get(AI_MATKEY_COLOR_DIFFUSE,color); ``` -------------------------------- ### Wrap Assimp for Android Asset Access Source: https://github.com/assimp/assimp-docs/blob/master/source/about/quickstart.md This C++ code demonstrates how to initialize Assimp's Importer with the AndroidJNIIOSystem to access assets. Ensure the AndroidJNIIOSystem is correctly instantiated with the application activity. ```cpp #include Assimp::Importer* importer = new Assimp::Importer(); Assimp::AndroidJNIIOSystem *ioSystem = new Assimp::AndroidJNIIOSystem(app->activity); if ( nullptr != iosSystem ) { importer->SetIOHandler(ioSystem); } ``` -------------------------------- ### Get Diffuse Color (C) Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Fetch the diffuse color of a material using AI_MATKEY_COLOR_DIFFUSE with the C API function aiGetMaterialColor(). The color variable will not be modified if the property is not set. ```c aiColor3D color (0.f,0.f,0.f); aiGetMaterialColor(mat,AI_MATKEY_COLOR_DIFFUSE,&color); ``` -------------------------------- ### Import file using C interface Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Use the plain C interface with aiImportFile for C interactions. Remember to manually call aiReleaseImport to free resources after processing the aiScene. ```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; } ``` -------------------------------- ### Configure Assimp Logging System Source: https://context7.com/assimp/assimp-docs/llms.txt Set up Assimp's logging to capture debugging information. This involves creating a custom log stream and attaching it to the default logger with specified severity levels. ```cpp #include #include #include // Custom log stream to capture Assimp messages class CustomLogStream : public Assimp::LogStream { public: void write(const char* message) override { std::cout << "[Assimp] " << message << std::endl; } }; void SetupLogging() { // Create the default logger with verbose output Assimp::DefaultLogger::create("", Assimp::Logger::VERBOSE); // Define which severity levels to capture const unsigned int severity = Assimp::Logger::Debugging | Assimp::Logger::Info | Assimp::Logger::Warn | Assimp::Logger::Err; // Attach custom stream Assimp::DefaultLogger::get()->attachStream(new CustomLogStream(), severity); // Log custom messages Assimp::DefaultLogger::get()->info("Custom logging initialized"); } void CleanupLogging() { // Destroy the logger when done Assimp::DefaultLogger::kill(); } // Usage void ImportWithLogging(const std::string& path) { SetupLogging(); Assimp::Importer importer; const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_ValidateDataStructure); if (!scene) { Assimp::DefaultLogger::get()->error(importer.GetErrorString()); } CleanupLogging(); } ``` -------------------------------- ### Implement Custom Log Stream Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Shows how to create a custom log stream by deriving from Assimp::LogStream and overriding the write method. This allows integrating Assimp logs into your own GUI or application. ```cpp // Example stream class myStream : public LogStream { public: // Write something using your own functionality void write(const char* message) { ::printf("%s\n", message); } }; // Select the kinds of messages you want to receive on this log stream const unsigned int severity = Logger::Debugging|Logger::Info|Logger::Err|Logger::Warn; // Attaching it to the default logger Assimp::DefaultLogger::get()->attachStream( new myStream, severity ); ``` -------------------------------- ### Import file using C++ Importer class Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Use the Assimp::Importer class for C++ interactions. Create an instance, call ReadFile, and process the aiScene. Resources are managed automatically upon object destruction. ```cpp #include #include #include bool DoTheImportThing( const std::string& pFile) { // Create an instance of the Importer class Assimp::Importer importer; // And have it read the given file with some example postprocessing // Usually - if speed is not the most important aspect for you - you'll // probably to request more postprocessing than we do in this example. const aiScene* scene = importer.ReadFile( pFile, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType); // If the import failed, report it if (nullptr == scene) { DoTheErrorLogging( importer.GetErrorString()); return false; } // Now we can access the file's contents. DoTheSceneProcessing( scene); // We're done. Everything will be cleaned up by the importer destructor return true; } ``` -------------------------------- ### Generate Build Files with CMake Source: https://github.com/assimp/assimp-docs/blob/master/source/about/quickstart.md Generate project files for your default build system by running CMake in the repository folder. ```default cmake CMakeLists.txt ``` -------------------------------- ### Set Material Properties in Assimp Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Demonstrates how to add properties like shininess, name, and diffuse texture to an aiMaterial object. Ensure the aiMaterial object is properly initialized before adding properties. ```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 ``` -------------------------------- ### IO-System API Source: https://github.com/assimp/assimp-docs/blob/master/source/API/API-Documentation.md Documentation for the IO-System API, which handles file input and output operations. ```APIDOC ## IO-System API ### Description Manages file I/O operations, including reading from and writing to various sources. ### Method N/A (This is a conceptual API description) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ``` -------------------------------- ### Registering a New Importer Source: https://github.com/assimp/assimp-docs/blob/master/source/developer/developer.md This code demonstrates how to conditionally include a new importer based on build configurations. It's typically placed in ImporterRegistry.cpp. ```cpp #if (!defined assimp_BUILD_NO_FormatName_IMPORTER) ... #endif ``` -------------------------------- ### Build Static Assimp Library with Ninja Source: https://github.com/assimp/assimp-docs/blob/master/source/about/quickstart.md Configure CMake to build Assimp as a static library using the Ninja generator. This command explicitly disables shared library builds. ```default cmake CMakeLists.txt -G "Ninja" -BUILD_SHARED_LIBS=OFF ``` -------------------------------- ### Load 3D Model using C++ Importer Class Source: https://context7.com/assimp/assimp-docs/llms.txt Use the Assimp::Importer class for loading 3D assets in C++. It automatically manages resources and provides access to scene data. Ensure proper include directives for the Importer, scene structures, and post-processing flags. ```cpp #include #include #include bool LoadModel(const std::string& filePath) { // Create an instance of the Importer class Assimp::Importer importer; // Read the file with post-processing flags const aiScene* scene = importer.ReadFile(filePath, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType); // Check if import was successful if (nullptr == scene) { std::cerr << "Error: " << importer.GetErrorString() << std::endl; return false; } // Access scene data std::cout << "Loaded model with:" << std::endl; std::cout << " Meshes: " << scene->mNumMeshes << std::endl; std::cout << " Materials: " << scene->mNumMaterials << std::endl; std::cout << " Textures: " << scene->mNumTextures << std::endl; std::cout << " Animations: " << scene->mNumAnimations << std::endl; // Process meshes for (unsigned int i = 0; i < scene->mNumMeshes; i++) { aiMesh* mesh = scene->mMeshes[i]; std::cout << "Mesh " << i << ": " << mesh->mNumVertices << " vertices, " << mesh->mNumFaces << " faces" << std::endl; } // Resources are automatically cleaned up when importer goes out of scope return true; } ``` -------------------------------- ### Set Custom IO Handler for Assimp Importer in C++ Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md After implementing your custom IO system, supply an instance to the Assimp Importer object by calling SetIOHandler. The import process will then use your custom implementation to access files. ```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); } ``` -------------------------------- ### Load Model with Custom Post-Processing Flags Source: https://context7.com/assimp/assimp-docs/llms.txt Loads a 3D model using Assimp's Importer, applying a comprehensive set of post-processing flags for optimization and transformation. Includes DirectX-specific flag for left-handed coordinate systems. ```cpp #include #include #include const aiScene* LoadWithPostProcessing(const std::string& path, bool forDirectX) { Assimp::Importer importer; // Common post-processing flags unsigned int flags = aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace | aiProcess_ValidateDataStructure | aiProcess_ImproveCacheLocality | aiProcess_RemoveRedundantMaterials | aiProcess_OptimizeMeshes | aiProcess_SortByPType; // DirectX-specific conversions if (forDirectX) { flags |= aiProcess_ConvertToLeftHanded; } // Configure specific post-processing settings importer.SetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.0f); importer.SetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT, 65535); importer.SetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, 65535); importer.SetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4); // Load with post-processing const aiScene* scene = importer.ReadFile(path, flags); if (!scene) { std::cerr << "Error: " << importer.GetErrorString() << std::endl; return nullptr; } return scene; } ``` -------------------------------- ### Parse and Validate XML Data Source: https://github.com/assimp/assimp-docs/blob/master/source/developer/developer.md Include XmlParser.h, create an XMLParser instance, load data from a stream, and parse the XML. Access the root node and its children, specifically looking for a 'COLLADA' node. ```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()) { } } } ``` -------------------------------- ### C API: Retrieving Material Properties Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Explains how to retrieve material properties using the C API functions, such as `aiGetMaterialFloat`, `aiGetMaterialString`, and `aiGetMaterialColor`. ```APIDOC ## C API: Retrieving Material Properties ### Description For C, material properties are retrieved using specific `aiGetMaterial` functions. ### Method `aiGetMaterialFloat()`, `aiGetMaterialString()`, `aiGetMaterialColor()`, etc. ### Parameters - **mat**: Pointer to the `aiMaterial` object. - **material-key**: The key identifying the material property. - **where-to-store**: A pointer to a variable where the property's value will be stored. ### Request Example ```c aiMaterial* mat = ..... // Get a float property if(AI_SUCCESS != aiGetMaterialFloat(mat, , )) { // handle epic failure here } // Get material name aiString name; aiGetMaterialString(mat, AI_MATKEY_NAME, &name); // Get diffuse color aiColor3D color (0.f,0.f,0.f); aiGetMaterialColor(mat, AI_MATKEY_COLOR_DIFFUSE, &color); ``` ### Response - **Success Response (AI_SUCCESS)**: The property was successfully retrieved and stored. - **Error Response (non-AI_SUCCESS)**: An error occurred during retrieval. ``` -------------------------------- ### Load 3D Model using Plain C Function Interface Source: https://context7.com/assimp/assimp-docs/llms.txt Utilize the plain C interface (aiImportFile) for importing 3D assets, which requires manual resource management. This is suitable for C codebases or language bindings. Remember to release imported resources using aiReleaseImport. ```c #include #include #include int LoadModelC(const char* filePath) { // Import the file with post-processing const struct aiScene* scene = aiImportFile(filePath, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType); // Check for errors if (NULL == scene) { printf("Error: %s\n", aiGetErrorString()); return 0; } // Process the imported data printf("Successfully loaded: %s\n", filePath); printf(" Meshes: %d\n", scene->mNumMeshes); printf(" Materials: %d\n", scene->mNumMaterials); // Process each mesh for (unsigned int i = 0; i < scene->mNumMeshes; i++) { const struct aiMesh* mesh = scene->mMeshes[i]; printf(" Mesh %d: %d vertices\n", i, mesh->mNumVertices); } // IMPORTANT: Release resources when done aiReleaseImport(scene); return 1; } ``` -------------------------------- ### Configure Assimp for Android Build Source: https://github.com/assimp/assimp-docs/blob/master/source/about/quickstart.md Use these CMake defines when building Assimp for Android. Ensure the ANDROID_ABI is set appropriately for your target architecture. ```default -DASSIMP_ANDROID_JNIIOSYSTEM=ON -DCMAKE_TOOLCHAIN_FILE=$SOME_PATH/android.toolchain.cmake ``` -------------------------------- ### Export Scene to OBJ Format Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Demonstrates exporting an aiScene object to an OBJ file using Assimp's Exporter. This function reads a model, then exports it to a specified path and format. ```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; } ``` -------------------------------- ### Load Asset on Android using JNI Source: https://context7.com/assimp/assimp-docs/llms.txt Loads a 3D model from Android assets using Assimp's JNI IO system. Requires the Android NDK and specific CMake configuration. ```cpp #include #include #include #include const aiScene* LoadAndroidAsset(android_app* app, const std::string& assetPath) { Assimp::Importer* importer = new Assimp::Importer(); // Create Android-specific IO handler Assimp::AndroidJNIIOSystem* ioSystem = new Assimp::AndroidJNIIOSystem(app->activity); if (ioSystem != nullptr) { importer->SetIOHandler(ioSystem); } // Load from Android assets folder const aiScene* scene = importer->ReadFile(assetPath, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenNormals); return scene; } ``` ```cmake cmake -DASSIMP_ANDROID_JNIIOSYSTEM=ON \ -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=arm64-v8a \ CMakeLists.txt ``` -------------------------------- ### Implement Custom IOStream for Memory Buffers Source: https://context7.com/assimp/assimp-docs/llms.txt Create a custom Assimp::IOStream to read data directly from memory buffers. This class handles reading, seeking, and reporting file size for in-memory assets. ```cpp #include #include #include // Custom IOStream implementation class MemoryIOStream : public Assimp::IOStream { private: const uint8_t* mBuffer; size_t mSize; size_t mPos; public: MemoryIOStream(const uint8_t* buffer, size_t size) : mBuffer(buffer), mSize(size), mPos(0) {} ~MemoryIOStream() override {} size_t Read(void* pvBuffer, size_t pSize, size_t pCount) override { size_t bytesToRead = pSize * pCount; if (mPos + bytesToRead > mSize) { bytesToRead = mSize - mPos; } memcpy(pvBuffer, mBuffer + mPos, bytesToRead); mPos += bytesToRead; return bytesToRead / pSize; } size_t Write(const void*, size_t, size_t) override { return 0; } aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override { switch (pOrigin) { case aiOrigin_SET: mPos = pOffset; break; case aiOrigin_CUR: mPos += pOffset; break; case aiOrigin_END: mPos = mSize - pOffset; break; } return aiReturn_SUCCESS; } size_t Tell() const override { return mPos; } size_t FileSize() const override { return mSize; } void Flush() override {} }; ``` -------------------------------- ### Link Assimp Library in CMake Source: https://github.com/assimp/assimp-docs/blob/master/source/about/quickstart.md Link the Assimp library to your application target in CMake after adding it as a subdirectory. ```default TARGET_LINK_LIBRARIES(my_game assimp) ``` -------------------------------- ### Material Properties Reference Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Reference for Assimp material properties. ```APIDOC ## Material Properties Reference This section details various material properties that Assimp can process. ### SHININESS_STRENGTH - **Type**: float - **Default**: 1.0 - **Description**: Scales the specular color of the material. This value is kept separate from the specular color by most modelers, and so are we. ### REFRACTI - **Type**: float - **Default**: 1.0 - **Description**: Defines the Index Of Refraction for the material. This is not supported by most file formats but might be of interest for raytracing. ### TEXTURE(t,n) - **Type**: aiString - **Default**: n/a - **Description**: Defines the path of the n’th texture on the stack ‘t’, where ‘n’ is any value >= 0 and ‘t’ is one of the #aiTextureType enumerated values. A file path to an external file or an embedded texture. Use aiScene::GetEmbeddedTexture to test if it is embedded for FBX files, in other cases embedded textures start with ‘*’ followed by an index into aiScene::mTextures. See the @ref mat_tex section above. Also see @ref textures for more information about texture retrieval. ### TEXBLEND(t,n) - **Type**: float - **Default**: n/a - **Description**: Defines the strength the n’th texture on the stack ‘t’. All color components (rgb) are multiplied with this factor before any further processing is done. ### TEXOP(t,n) - **Type**: int - **Default**: n/a - **Description**: One of the #aiTextureOp enumerated values. Defines the arithmetic operation to be used to combine the n’th texture on the stack ‘t’ with the n-1’th. **TEXOP(t,0)** refers to the blend operation between the base color for this stack (e.g. **COLOR_DIFFUSE** for the diffuse stack) and the first texture. ### MAPPING(t,n) - **Type**: int - **Default**: n/a - **Description**: Defines how the input mapping coordinates for sampling the n’th texture on the stack ‘t’ are computed. Usually explicit UV coordinates are provided, but some model file formats might also be using basic shapes, such as spheres or cylinders, to project textures onto meshes. See the ‘Textures’ section below. #aiProcess_GenUVCoords can be used to let Assimp compute proper UV coordinates from projective mappings. ### UVWSRC(t,n) - **Type**: int - **Default**: n/a - **Description**: Defines the UV channel to be used as input mapping coordinates for sampling the n’th texture on the stack ‘t’. All meshes assigned to this material share the same UV channel setup. Presence of this key implies **MAPPING(t,n)** to be #aiTextureMapping_UV. See @ref uvwsrc for more details. ### MAPPINGMODE_U(t,n) - **Type**: int - **Default**: n/a - **Description**: Any of the #aiTextureMapMode enumerated values. Defines the texture wrapping mode on the x axis for sampling the n’th texture on the stack ‘t’. ‘Wrapping’ occurs whenever UVs lie outside the **0..1** range. ``` -------------------------------- ### Process Mesh Bones and Vertex Weights Source: https://context7.com/assimp/assimp-docs/llms.txt Extracts bone hierarchy, offset matrices, and vertex weights from a mesh. Verifies that vertex weights sum to approximately 1.0. Requires Assimp library. ```cpp #include struct BoneInfo { aiMatrix4x4 offsetMatrix; aiMatrix4x4 finalTransform; }; void ProcessBones(const aiMesh* mesh, const aiScene* scene) { if (!mesh->HasBones()) { std::cout << "Mesh has no bones" << std::endl; return; } std::cout << "Processing " << mesh->mNumBones << " bones" << std::endl; // Map to store bone info by name std::map boneInfoMap; // Vertex weights: [vertexIndex] -> vector of (boneIndex, weight) std::vector>> vertexWeights(mesh->mNumVertices); for (unsigned int i = 0; i < mesh->mNumBones; i++) { const aiBone* bone = mesh->mBones[i]; std::string boneName = bone->mName.C_Str(); std::cout << " Bone[" << i << "]: " << boneName << " (" << bone->mNumWeights << " weights)" << std::endl; // Store offset matrix (mesh space -> bone local space) BoneInfo info; info.offsetMatrix = bone->mOffsetMatrix; boneInfoMap[boneName] = info; // Process vertex weights for (unsigned int j = 0; j < bone->mNumWeights; j++) { const aiVertexWeight& weight = bone->mWeights[j]; unsigned int vertexId = weight.mVertexId; float boneWeight = weight.mWeight; vertexWeights[vertexId].push_back({i, boneWeight}); } // Find corresponding node in hierarchy const aiNode* boneNode = scene->mRootNode->FindNode(bone->mName); if (boneNode) { std::cout << " Found node in hierarchy" << std::endl; } } // Verify weights sum to 1.0 for each vertex for (unsigned int v = 0; v < mesh->mNumVertices; v++) { float totalWeight = 0.f; for (const auto& bw : vertexWeights[v]) { totalWeight += bw.second; } if (!vertexWeights[v].empty() && std::abs(totalWeight - 1.0f) > 0.01f) { std::cout << "Warning: Vertex " << v << " weights sum to " << totalWeight << std::endl; } } } ``` -------------------------------- ### Implement BaseImporter InternReadFile Method Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Template for the InternReadFile method in a custom Assimp importer. This method is responsible for reading the file content and populating the aiScene object. It should throw exceptions for errors. ```cpp // ------------------------------------------------------------------------------- void xxxxImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { std::unique_ptr file( pIOHandler->Open( pFile, "rb")); // Check whether we can read from the file if( file.get() == NULL) { throw DeadlyImportError( "Failed to open xxxx file ", pFile, "."); } // Your task: fill pScene // Throw a ImportErrorException with a meaningful (!) error message if // something goes wrong. } ``` -------------------------------- ### Load Model for Physics Simulation Source: https://context7.com/assimp/assimp-docs/llms.txt Loads a 3D model with post-processing flags tailored for physics simulations, such as pre-transforming vertices and optimizing meshes. ```cpp const aiScene* LoadForPhysics(Assimp::Importer& importer, const std::string& path) { return importer.ReadFile(path, aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_PreTransformVertices | aiProcess_OptimizeMeshes); } ``` -------------------------------- ### Load Model for OpenGL Source: https://context7.com/assimp/assimp-docs/llms.txt Loads a 3D model with a standard set of post-processing flags suitable for OpenGL rendering. ```cpp const aiScene* LoadForOpenGL(Assimp::Importer& importer, const std::string& path) { return importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace | aiProcess_JoinIdenticalVertices); } ``` -------------------------------- ### Implement BaseImporter GetExtensionList Method Source: https://github.com/assimp/assimp-docs/blob/master/source/usage/use_the_lib.md Template for the GetExtensionList method in a custom Assimp importer. This method populates a set with all file extensions that the importer can handle. ```cpp // ------------------------------------------------------------------------------- // Get list of file extensions handled by this loader void xxxxImporter::GetExtensionList(std::set& extensions) { extensions.insert("xxx"); } ``` -------------------------------- ### Process Skeletal Animations in Assimp Source: https://context7.com/assimp/assimp-docs/llms.txt Iterates through all animations in an Assimp scene, printing their properties. It also demonstrates how to calculate animation duration in seconds and process individual animation channels, including extracting interpolated position and rotation data at a specific time. ```cpp #include #include void ProcessAnimations(const aiScene* scene) { for (unsigned int i = 0; i < scene->mNumAnimations; i++) { const aiAnimation* anim = scene->mAnimations[i]; std::cout << "Animation: " << anim->mName.C_Str() << std::endl; std::cout << " Duration: " << anim->mDuration << " ticks" << std::endl; std::cout << " Ticks/Second: " << anim->mTicksPerSecond << std::endl; std::cout << " Channels: " << anim->mNumChannels << std::endl; // Calculate duration in seconds double ticksPerSecond = anim->mTicksPerSecond != 0 ? anim->mTicksPerSecond : 25.0; double durationInSeconds = anim->mDuration / ticksPerSecond; std::cout << " Duration (sec): " << durationInSeconds << std::endl; // Process each animation channel (affects one node) for (unsigned int j = 0; j < anim->mNumChannels; j++) { const aiNodeAnim* channel = anim->mChannels[j]; std::cout << " Channel: " << channel->mNodeName.C_Str() << std::endl; std::cout << " Position keys: " << channel->mNumPositionKeys << std::endl; std::cout << " Rotation keys: " << channel->mNumRotationKeys << std::endl; std::cout << " Scaling keys: " << channel->mNumScalingKeys << std::endl; // Example: Get interpolated transform at a specific time double timeInTicks = 0.5 * anim->mDuration; // 50% through animation // Find position key aiVector3D position(0, 0, 0); for (unsigned int k = 0; k < channel->mNumPositionKeys - 1; k++) { if (timeInTicks < channel->mPositionKeys[k + 1].mTime) { const aiVectorKey& key1 = channel->mPositionKeys[k]; const aiVectorKey& key2 = channel->mPositionKeys[k + 1]; double factor = (timeInTicks - key1.mTime) / (key2.mTime - key1.mTime); position = key1.mValue + (key2.mValue - key1.mValue) * (float)factor; break; } } // Find rotation key (quaternion interpolation) aiQuaternion rotation; for (unsigned int k = 0; k < channel->mNumRotationKeys - 1; k++) { if (timeInTicks < channel->mRotationKeys[k + 1].mTime) { const aiQuatKey& key1 = channel->mRotationKeys[k]; const aiQuatKey& key2 = channel->mRotationKeys[k + 1]; double factor = (timeInTicks - key1.mTime) / (key2.mTime - key1.mTime); aiQuaternion::Interpolate(rotation, key1.mValue, key2.mValue, (float)factor); break; } } } } } ```