Hi there, I'm trying to use Blender with the 3D engine Horde3D and I would really like to be able to import skinned animations from Blender to Horde via collada. A description of the problem can be found here: [
www.nextgen-engine.net]
The Horde "colladaConv" importer program isn't very generally written and only works with collada files exported from max or maya (using the FCollada library) with the "bake matrices" option enabled. So although some of the fault lies with "colladaConv" I think the collada blender plugin is not far from being compatible with Horde.
I started to look into how to modify the collada plugin but I soon gave up due to the complexity of the plugin and my limited understanding of collada and blender.
(Sidenote: As much as I like Python, the lack of type declarations actually makes it harder to dig into a large foreign code base imo.)
So this is what I came up with:
line 1217 in collada.py should be changed from:
AppendTextChild(node,i[0],val)
to:
SetAttribute(AppendTextChild(node,i[0],val), DaeSyntax.SID, "transform")
For example, this will change exported nodes from:
<node layer="L2" sid="Root" type="JOINT" id="Root" name="Root">
<matrix>
-1.0 0.0 0.0 -0.00047
...
to:
<node layer="L2" sid="Root" type="JOINT" id="Root" name="Root">
<matrix sid="transform">
-1.0 0.0 0.0 -0.00047
...
This will make "bake matrices" work just like FCollada and allow them to be compatible with Horde.
Then comes the hard part:
All bone animation IPO:s should not merely be exported as they are, they should be merged into one animation channel which uses matrices and targets the <node-name>/transform. For example, a two frame animation which animates a "LeftUpLeg-node" node:
<animation id="LeftUpLeg-node-transform">
<source id="LeftUpLeg-node-transform_LeftUpLeg-node_transform-input">
<float_array id="LeftUpLeg-node-transform_LeftUpLeg-node_transform-input-array" count="2">0 0.04</float_array>
<technique_common>
<accessor source="#LeftUpLeg-node-transform_LeftUpLeg-node_transform-input-array" count="2" stride="1">
<param name="TIME" type="float"/>
</accessor>
</technique_common>
<technique profile="MAYA">
<pre_infinity>CONSTANT</pre_infinity>
<post_infinity>CONSTANT</post_infinity>
</technique>
</source>
<source id="LeftUpLeg-node-transform_LeftUpLeg-node_transform-output">
<float_array id="LeftUpLeg-node-transform_LeftUpLeg-node_transform-output-array" count="32">-0.786355 0.617776 0.000000 -5.83286 -0.617776 -0.786355 0.000000 -0.923933 0.000000 0 1 -11.6415 0 0 0 1 -0.45474 0.890625 0.000000 -5.83286 -0.890625 -0.45474 0.000000 -0.923933 0.000000 0 1 -11.6415 0 0 0 1</float_array>
<technique_common>
<accessor source="#LeftUpLeg-node-transform_LeftUpLeg-node_transform-output-array" count="2" stride="16">
<param name="TRANSFORM" type="float4x4"/>
</accessor>
</technique_common>
</source>
<source id="LeftUpLeg-node-transform_LeftUpLeg-node_transform-interpolations">
<Name_array id="LeftUpLeg-node-transform_LeftUpLeg-node_transform-interpolations-array" count="2">LINEAR LINEAR</Name_array>
<technique_common>
<accessor source="#LeftUpLeg-node-transform_LeftUpLeg-node_transform-interpolations-array" count="2" stride="1">
<param name="INTERPOLATION" type="Name"/>
</accessor>
</technique_common>
</source>
<sampler id="LeftUpLeg-node-transform_LeftUpLeg-node_transform-sampler">
<input semantic="INPUT" source="#LeftUpLeg-node-transform_LeftUpLeg-node_transform-input"/>
<input semantic="OUTPUT" source="#LeftUpLeg-node-transform_LeftUpLeg-node_transform-output"/>
<input semantic="INTERPOLATION" source="#LeftUpLeg-node-transform_LeftUpLeg-node_transform-interpolations"/>
</sampler>
<channel source="#LeftUpLeg-node-transform_LeftUpLeg-node_transform-sampler" target="LeftUpLeg-node/transform"/>
</animation>
The above output is from 3ds max; of course, the collada blender plugin doesn't have to output just like this, I think the important part is the <channel ... target = "LeftUpLeg-node/transform"/> tag and the float array of 4x4 bone node transforms.
I was thinking of modifying translator.py/Animation.SaveToDae so that it goes through all the generated IPO-curves if "bake matrices" is on and generates matrices for them, multiplies the matrices together and puts them in a new curve which has as many key frames as the "union of the other curves' key frames" if you understand what I mean. But I figured that I wasn't the right person to do it since I don't really understand the code.
Also, there is one more problem: the "Warning: Mesh Businessman_002 is directly attached to a joint; use skin instead!" warning. I think this is the same thing as another thing I noticed: I exported an animated mesh from blender without "bake matrices" and imported this .dae into 3ds max. The mesh imported alright, the bones and the animation of the bones too. But: the mesh wasn't joined to the bones anymore (no skinning) and the mesh was misplaced (by the inverse of the root bone position I think). I don't know how to fix this problem, but it might be solved just by removing the link between the skinned mesh and the root bone when exporting to collada maybe?
Anyhow, I might be way off with my proposed solutions since I only have a very shallow understanding of the exporter and collada in general. Perhaps they can be of some help at least. Thanks for the great work with the collada plugin, hopefully these problems can be fixed!