Hi fysx,
When using the C-style interface provided in Horde3D.h, you have access to h3dSetNodeTransform for manually passing in nine individual floats. Instead of this, however, you can use h3dSetNodeTransMat which accepts a float pointer (which you ensure is a valid array of 16 in column-major notation). In order to only specify a transform to this relative matrix (as you say, only "rotate upper arm around X" instead of "transformation from shoulder joint + rotate upper arm around X"), you will need to add some basic functionality.
In the underlying C++ structure, each SceneNode holds a Matrix4f for its relative transform (also one for the absolute transform). By accessing this with either h3dGetNodeTransform or h3dGetNodeTransMats, you can apply your own calculations and return the result through h3dSetNodeTransMat.
If you would rather be able to pass in the transformation matrix and let Horde handle the calculation, you can add the functionality quite simply:
In the SceneNode class header (egScene.h):
Code:
void applyTransform(const Matrix4f &mat);
And in the implementation (egScene.cpp):
Code:
void SceneNode::applyTransform(const Matrix4f &mat)
{
setTransform(_relTrans * mat);
}
By calling the setTransform function, you automatically apply the _skinningDirty and _ignoreAnim 'flags', as well as any future changes to the function, therefore easier to maintain.
You can then add C-style functionality as used in the rest of the Horde interface, so there are no dependencies in your code on the internal SceneNode type (i.e. you do not need access to the class in order to use SceneNode::applyTransform).
This would be added into Horde3D.h:
Code:
DLL void h3dApplyNodeTransMat( H3DNode node, const float *mat4x4 );
And then in egMain.cpp:
Code:
DLLEXP void h3dApplyNodeTransMat( NodeHandle node, const float *mat4x4 )
{
static Matrix4f mat;
SceneNode *sn = Modules::sceneMan().resolveNodeHandle( node );
APIFUNC_VALIDATE_NODE( sn, "h3dApplyNodeTransMat", APIFUNC_RET_VOID );
if( mat4x4 == 0x0 )
{
Modules::setError( "Invalid pointer in h3dSetNodeTransMat" );
return;
}
memcpy( mat.c, mat4x4, 16 * sizeof( float ) );
sn->applyTransform( mat );
}
The only real advantage to this method is that you do not need to first get the transform of the Node before you apply your transformation. You do not need to store the transform data of each node unless you really don't like calling h3dGetNodeTransMats on each update (Note: the function requests two float** objects, but you can pass NULL for the absMat).
Hope this helps!