UNIGINE's Import System allows you to import models and scenes in various external formats (FBX, DAE, OBJ, etc.). Although the basic set of file formats supported by UNIGINE out-of-the-box includes the most commonly used ones, in some cases you may need to import models or scenes in some specific file format. Fortunately the Import System can be extended to support any custom file format.
Implement your own custom importer as a plugin.
Create your own import pre-processor.
Use your custom importer to bring a scene stored in a custom file format to UNIGINE.
So, in this example we are going create a custom importer for a custom file format. Let it be an xml-based format in which we declare our scene as a hierarchy of nodes that have a transformation and can have a mesh, light or camera attribute. Let our file format have a .myext exstension. An example of a scene in our custom format containing all available elements is given below.
At the end of this example we're going to have this model imported to UNIGINE's world and saved in UNIGINE's native file formats in the specified folder. But before we get started, a little bit of theory (as key points).
UNIGINE's API offers us a set of classes for implementing customized model import.
A custom importer should be inherited from the Importer class.
A custom import processor should be inherited from the ImportProcessor class.
Enough words! Let's get to business! The code below is supplemented with comments explaining the basic aspects of the process.
As you know each importer should be implemented as a plugin. So we're going to create a C++ plugin.
As for plugin implementation, it's also simple. Include UnigineImport.h for basic import functionality and our importer's header file (MyImporter.h).
To learn more about creating a C++ plugin please refer to this article.
First we should define some intermediate data structures to which all parameters of imported scene elements are to be extracted. And we should declare a common template for UserData to be able to assign data to the import structures.
Extract data from the input file, put it to the corresponding import structures (ImportMesh, ImportLight, etc.) and add them to the import scene.
Use pre-processor(s) to prepare scene metadata when necessary (e.g. merge all static meshes into a single one, optimize vertex cache, etc.). In our example we're going to strip off light color information if the corresponding option (make_lights_white) is set.
Save generated UNIGINE objects to *.node and *.mesh files. This part is performad by the DefaultProcessor, so we do nothing here.
These default values can be changed in your application when using the importer via the Importer::setParameter*() methods.
First, let us create a new project named MyProject, that will use our library. Let it be a simple project using UnigineScript only (the idea for C++ is the same).
Put our plugin library module (a *.dll, *.so or *.dylib file) to our project's bin directory.
Make sure your project's binary and plugin library have the same bitness and version.
The same can be done in the project's system logic via Engine::addPlugin() on the C++ side or via Engine.addPlugin() on the C# side of the project.
Use the plugin in our project. Let's add some lines of code to the init() method of the world script (MyProject.cpp file) to demonstrate the idea.
my_importer.init("my_scene.myext", ~0);				// initializing the importer with default import flags IMPROT_LIGHTS, IMPORT_MESHES, IMPORT_CAMERAS, etc.
Now when we launch our project with MyImporter plugin loaded and MyProject world opened the scene will imported to the world and corresponding files are saved to MyProject/data/output_folder/ folder.