About the unit meter

Ok, problem is as follows i have a bunch of collada files, referenced form a master file and possibly form the sub files themselves. I’m using the collada dom to recurse the application (i have no choice on the matter its a testbed for suitability of collada dom)

Now each file defines its own scaling,

My problem is that theres no nice way in the dom to point me to the value. So i have to resolve the document form uri and get the asset element back up form the domCOLLADA object with getAsset and so on.

However if theres a more natural way then I´m all ears, because quite frankly it feels most of the time that the dom isn’t doing me any favors. (in fact i would probably have been ready ages ago had i not bothered to use it, but thats not in my hands)

And sax style parsing is out of the question, as i do have to do this in a certain order otherwise everything craps up totally. (the target system is somewhat limited)

PS: my current alternate strategy is to try to resolve scale every time i encounter a instance that jumps over a url and push the scale in a hash then retrieve it for each and every object based on that.

Hi, welcome to Collada!

If I understand your problem, you’d like an easy way to get the <unit> element from a document given an element in the document. It shouldn’t be too hard to write a function to do that using the DOM:

// Returns the document's <unit> element given an element in the document
domAsset::domUnit* getDocumentUnitInfo(daeElement* elt) {
	if (!elt || !elt->getDocument() || !elt->getDocument()->getDomRoot())
		return NULL;

	domCOLLADA* root = daeSafeCast<domCOLLADA>(elt->getDocument()->getDomRoot());
	if (!root->getAsset() || !root->getAsset()->getUnit())
		return NULL;

	return root->getAsset()->getUnit();

You have to be a bit careful, because a document doesn’t have to have a <unit> element (in which case the spec defines appropriate default values), so the above function might return NULL. The function could be modified to always return a valid value of course.

Anyway, let me know if this helps solve your problem or not.


Yes i know how to retrieve the element, thanks for the code anyway. :wink: But its a bit top heavy to do this with my scenes as they are huge (they are not meant to be used for games but rather they represent entire factories down to the nut and bolt, so the scenes may end up having 10-20 mil polys just in bolts and rivets). So memory is a bit of an potenttial issue here.

Anyway seems like the original authors have ignored the unit issue (and up type). But id rather not, just for sake of completeness.

So memory is a bit of an potenttial issue here.
I’m not sure what you mean. The code I posted doesn’t use any additional memory. Good luck with the project though.

No, but caching the data does. And the importer is slow as it is and i must find way to speed it up, See continuously going up and down the tree is slowing me down quite considerably already. I mean i already have 20 minute imports which are WAY too slow 1/4 of thet would be acceptrable.

Now would be fine if i would just convert the data to native data permanently but thats not what the client uses it for i suspect. SO the data will be 90% of time in translation.

According to the spec asset tags can pop up in any number of places, so it isn’t just enough to get the asset tag of the root.

Although it would be slower, the most sure-fire way of getting the correct units is checking if any parents contain an asset child, for example:

    float GetUnitScale(daeElement* pelt) {
        while(pelt != NULL) {
            daeElement *pchild = pelt->getChild("asset");
            if( pchild != NULL && pchild->typeID() == domAsset::ID() ) {
                domAsset* passet = (domAsset*)pchild;
                if( passet->getUnit() != NULL )
                    return passet->getUnit()->getMeter();

            pelt = pelt->getParentElement();
        return 1;

If the collada file is being recursed in hierarchical order, then the asset tags can be correctly tracked and there would be no need for this. However, considering the enormous reference and instance elements, going through the file in hierarchical order could be extremely difficult.

Perhaps a two-pass algorithm would work best. The first-pass would traverse the collada graph in hierarchical order, find all the places where the unit scale is changed and would set the user data of every element to point to the correct scale. The second pass would go through the collada file in logical order (ie starting at the <scene> or <library_*> elements) and build up the scene.