Loading multiple character files using various DAE objects

Hello!

I have written an COLLADA .dae importer, which uses integration classes to convert the data into a realtime-friendly format. Afterwards the converted data is transferred to classes of our engine, but that part is not my problem.

Everything works fine, when the first character file is loaded using DAE::load(). I do not delete the DAE object after conversion because I want to cache data for a faster reimport of an already loaded file.
Before I load a second file a new DAE object is created using “new DAE”. Its database object is truly set to NULL but anyway calling DAE::load() with the new object leads to double conversion. For the first file only one mesh and one skin are created for example but in the second execution there are two of each kind. Normally daeIntegrationObject::fromCOLLADA() is called via a short list of intermediate functions but for the second file each first version of an objects is converted via a long list of resolve functions. Subsequently the second ones are converted normally, again. So I think the first versions are the ones from the first file even though they have been loaded using another DAE object. First of all that fact leads to a higher conversion time but this only an unlovely side effect.
The real problem is that both skin objects only link to the first version of the source mesh and only the first skin is linked to both skeleton nodes. I have to say that the files are identically except for the animation content, so the names and IDs are identically, too. That is surely the problem to resolve the right object. But at all I do not want that both files are used for resolving.

Is it possible load COLLADA files independently from each other in the same process? Only using different DAE objects does not seem to work.

One DAE object can have multiple files loaded at once. In fact, this is how you’re supposed to do it in general. This way you can get cross-document references resolved automatically.

DAE dae;
dae.load("file1.dae");
dae.load("file2.dae");

Now the database will be filled with elements from both documents. When doing database queries, pass in a document URI to restrict the results to elements from a single document:

daeElement* el = 0;
dae.getDatabase()->getElement(&el, 0, "my-element", 0, "file1.dae");

In theory (and if I’m understanding you correctly) what you’re doing with multiple DAEs should also work, but there’s a lot of shared state (yuck) with the DAEs and there are issues. I just fixed a crash due to multiple DAEs a couple weeks ago, but it seems there are still problems.

Thank you for your response.

I knew that one DAE object can load multiple files, but I do not know what will happen, if there are different objects with equal names in diverse files. So I decided to use various DAE objects. Unfortunately that does not work well.
Now I got the time to test multiple files with one DAE object and it really works in the current case. But what happens, if there are two different meshes with the same name and ID for example? Will only be the first one referenced? Or are all objects correctly loaded into a kind of file namespace?

Will only be the first one referenced? Or are all objects correctly loaded into a kind of file namespace?
The latter, sort of. the DAE object has a database which has a list of documents. Each document contains a reference to the root of the xml tree for that document. In general these trees are completely independent. If you have many documents with an element whose ID is “my-element”, that’s perfectly fine, there will be no conflict.

The only place a conflict is introduced is when using the database to do lookups for elements matching a specific ID or type. This is done with the daeDatabase::getElement method. Let’s say that I want to find the element whose ID is “my-element”. It’s not required that you specify a particular document, so you can write code like this:

daeElement* elt = 0;
dae.getDatabase()->getElement(&elt, 0, "my-element");

If you only have one document open in the DAE object, this works perfectly. But if you have two (or more) documents open and each one contains an element whose ID is “my-element”, the preceding code will return a matching element, but you don’t know which one. Instead, specify the URI of the document you want to search in:

daeElement* elt = 0;
dae.getDatabase()->getElement(&elt, 0, "my-element", NULL, "file1.dae");

See the daeDatabase::getElement documentation for more info.

So I decided to use various DAE objects. Unfortunately that does not work well.
Yes, what you’re trying to do is perfectly valid, but unfortunately there are problems. The DAE objects share some global state, and it could require a significant reworking of the code to split everything up so that multiple simultaneous DAE objects work fine. My humble apologies for that. A bug is already reported here. Until that’s fixed, loading multiple documents into one DAE object should be a good workaround.

Steve