Horde3D http://horde3d.org/forums/ |
|
bind pose relative joint rotations http://horde3d.org/forums/viewtopic.php?f=2&t=1605 |
Page 1 of 1 |
Author: | fysx [ 11.12.2011, 02:19 ] |
Post subject: | bind pose relative joint rotations |
Hi there, I am currently trying to do some simple procedural animation for a custom model. From reading the documentation it seems to me, that the general approach would be to find the scene graph node of the joint and then perform the desired transformation on it using "h3dSetNodeTransform". When I do that, I can only specify the full transformation relative to the parent joint. However I would like to perform a motion relative to the bind pose (i.e. only "rotate upper arm around X" instead of "transformation from shoulder joint + rotate upper arm around X"). One possible solution would be to store the bind pose transformation from the shoulder joint, however that feels like bloating book-keeping as for each joint the parent transformation has to be stored. Is there any other way? Thanks in advance, Martin |
Author: | Tindros [ 29.12.2011, 11:28 ] |
Post subject: | Re: bind pose relative joint rotations |
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! |
Page 1 of 1 | All times are UTC + 1 hour |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |