bboguni Posted November 21, 2022 Share Posted November 21, 2022 (edited) Hello First of all, thank you for providing such a great sample. //Importing Models Directly to Memory https://developer.unigine.com/en/docs/2.13/code/usage/custom_import_processor/index?rlang=cpp I have a question. Through the Importing Models Directly to Memory method, an accurate mesh shape could be imported. But the part about animation import is not at all I didn't know... Is there no separate guide document?? I am attaching a simple sample project that I am currently testing. FBXAnimation.zip Edited November 22, 2022 by bboguni Link to comment
danvern Posted November 22, 2022 Share Posted November 22, 2022 Hello! This is an updated MemoryProcessor: class MemoryProcessor : public Unigine::ImportProcessor { protected: // method to be called on mesh processing virtual bool onProcessMesh(MeshPtr &mesh, ImportMesh *import_mesh) override { UGUID guid; guid.generate(); import_mesh->filepath = guid.getString(); meshes.append(import_mesh->filepath, mesh); return true; } // method to be called on mesh animation processing bool onProcessAnimation(MeshPtr& animation, ImportMesh* import_mesh, ImportAnimation* import_animation) override { UGUID guid; guid.generate(); meshes_animations.append(import_mesh, animation); return true; } bool onProcessAnimation(MeshPtr& animation, ImportAnimation* import_animation) { UGUID guid; guid.generate(); return true; } // method to be called on texture processing bool onProcessTexture(ImportTexture *import_texture) { import_texture->filepath = import_texture->original_filepath; return true; } // method to be called on material processing bool onProcessMaterial(MaterialPtr &material, ImportMaterial *import_material) { UGUID guid; guid.generate(); materials.append(import_material->name, material); return true; } // method performing nodeto be called on mesh processing void convert_node(NodePtr &node, ImportNode *import_node) { using namespace Unigine::Math; // checking node's type and performing the corresponding import operations if (import_node->camera != nullptr) { // importing a camera PlayerPtr player; getImporter()->importCamera(this, player, import_node->camera); node = player; node->setWorldTransform(Mat4(import_node->transform)); } else if (import_node->light != nullptr) { // importing a camera LightPtr light; getImporter()->importLight(this, light, import_node->light); node = light; node->setWorldTransform(Mat4(import_node->transform)); } else if (import_node->mesh != nullptr) { // importing a mesh ImportMesh* import_mesh = import_node->mesh; if (import_mesh->has_animations) { float fps = getImporter()->getParameterFloat("fps"); ObjectMeshSkinnedPtr SkinObject = ObjectMeshSkinned::create(meshes[import_mesh->filepath]); auto it = meshes_animations.find(import_mesh); if (it != meshes_animations.end()) { int animation_id = SkinObject->addAnimation(it->data); SkinObject->setNumLayers(1); SkinObject->setAnimation(0, animation_id); } SkinObject->setSpeed(fps); //SkinObject->setWorldTransform(Mat4(import_node->transform)); // for (const ImportGeometry& geometry : import_mesh->geometries) { for (const ImportSurface& surface : geometry.surfaces) { int surface_index = surface.target_surface; if (surface_index == -1) { Log::error("Can't find surface \"%s\".\n", surface.name.get()); continue; } if (surface.material == nullptr) continue; SkinObject->setMaterial(materials[surface.material->name], surface_index); } } node = SkinObject; //for test SkinObject->setLoop(true); SkinObject->play(); } else { ObjectMeshStaticPtr object = ObjectMeshStatic::create(meshes[import_mesh->filepath]); object->setWorldTransform(Mat4(import_node->transform)); for (const ImportGeometry& geometry : import_mesh->geometries) { for (const ImportSurface& surface : geometry.surfaces) { int surface_index = surface.target_surface; if (surface_index == -1) { Log::error("Can't find surface \"%s\".\n", surface.name.get()); continue; } if (surface.material == nullptr) continue; object->setMaterial(materials[surface.material->name], surface_index); } } node = object; } } else { // or importing a dummy node node = NodeDummy::create(); node->setWorldTransform(Mat4(import_node->transform)); } node->setName(import_node->name); // recursively processing all node's children and adding them to the hierarchy in the world for (ImportNode *import_child : import_node->children) { NodePtr child; convert_node(child, import_child); node->addWorldChild(child); } } // method to be called on node processing virtual bool onProcessNode(NodePtr &node, ImportNode *import_node) { convert_node(node, import_node); return true; } private: // HashMaps to be used for imported meshes and materials HashMap<String, MeshPtr> meshes; HashMap<ImportMesh *, MeshPtr> meshes_animations; HashMap<String, Unigine::MaterialPtr> materials; }; it is also necessary to update the code in import methods: MemoryProcessor memory_processor; ImportScene* scene = importer->getScene(); for (ImportMesh* meshToImport : scene->getMeshes()) { MeshPtr m = Mesh::create(); importer->importMesh(&memory_processor, m, meshToImport); if (m->getNumBones()) { for (ImportAnimation* animation : scene->getAnimations()) { MeshPtr animation_mesh = Mesh::create(); //mesh for animation importer->importAnimation(&memory_processor, animation_mesh, meshToImport, animation); } } } 2 Link to comment
bboguni Posted November 22, 2022 Author Share Posted November 22, 2022 Thank you very much. danvern Confirmed that it works perfectly. Thank you for your kind reply. 1 Link to comment
Recommended Posts