Horde3D

Next-Generation Graphics Engine
It is currently 24.11.2024, 20:12

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: 29.09.2010, 21:44 
Offline

Joined: 09.09.2009, 18:58
Posts: 107
I recently found myself in need of a function that retrieved the absolute world transform of a particular node and was a bit disappointed when I found that the h3dGetNodeTransform function only retrieved the transform relative to a nodes parent. I needed to retrieve the world coordinates of a node within a scenegraph to integrate collision volumes with the nodes. So I propose that a new function be added to help with that.

Code:
// The implementation I am using uses references and nixes the scale value, but the theory is the same.
void h3dutGetNodeWorldTransform(H3DNode node, float* tx,float* ty,float* tz,float* rx,float* ry,float* rz,float*,float* sx, float* sy, float* sz)
{
    H3DNode parent;
   
    float tra_x,tra_y,tra_z;
    float rot_x,rot_y,rot_z;
    float sca_x,sca_y,sca_z;
   
    do
    {
        parent = h3dGetNodeParent(node);
        h3dGetNodeTransform(node,&tra_x,&tra_y,&tra_z,&rot_x,&rot_y,&rot_z,&sca_x,&sca_y,&sca_z);
       
        *tx+=tra_x;*ty+=tra_y;*tz+=tra_z;
        *rx+=rot_x;*ry+=rot_y;*rz+=rot_z;
        *sx+=sca_x;*sy+=sca_y;*sz+=sca_z;
       
    }while(parent!=H3DRootNode);
}


By the way, if I am doing this wrong, please let me know. That was my other reason for this post. :?


Top
 Profile  
Reply with quote  
PostPosted: 29.09.2010, 22:34 
Offline

Joined: 15.06.2008, 11:21
Posts: 166
Location: Germany
Hm. Is this really correct? Just summing up the positions and scale doesn't look good to me, can you explain why that works? Because I would have multiplied the matrices of the different transforms there and then decomposed the result into position/scale/vector. After a rotation around 180 degrees, translation suddenly goes into the opposite direction, however you are still just adding it?


Top
 Profile  
Reply with quote  
PostPosted: 29.09.2010, 22:51 
Offline

Joined: 11.09.2010, 20:21
Posts: 44
Location: Germany
This function does not work, but there is already a Horde3D function for the absolute (and relative) matrix: h3dGetNodeTransMats.


Top
 Profile  
Reply with quote  
PostPosted: 29.09.2010, 23:25 
Offline

Joined: 09.09.2009, 18:58
Posts: 107
Rauy wrote:
This function does not work, but there is already a Horde3D function for the absolute (and relative) matrix: h3dGetNodeTransMats.


Right, and this is about the solution I came up with. In the prop class I have btCollisionObjects hashed to H3DNodes for easy syncronization:

Code:
// assume the following
typedef boost::unordered_map<H3DNode, boost::shared_ptr<btCollisionObject> > NodeCollisionMap;
typedef std::pair<H3DNode, boost::shared_ptr<btCollisionObject> > CollisionMapPair;

void Prop::Update(float time)
{
    // Set the orientation of the props root node
    btQuaternion orientation((btScalar)rotX,(btScalar)rotY,(btScalar)rotZ);
    btTransform trans(orientation,btVector3(x,y,z));
    collision_object->setWorldTransform(trans);

    // explicit transforms stored by the prop object and are set when a rigid body is attached.
    h3dSetNodeTransform(node,x,y,z,rotX,rotY,rotZ,scalX,scalY,scalZ);

    BOOST_FOREACH(CollisionMapPair pair, collision_map)
    {
        float mat[4][4];
        h3dGetNodeTransMats(pair.first,NULL,mat);

        float X = mat[3][0];float Y = mat[3][1];float Z = mat[3][2];
       
        // Still need to decompose the matrix to aquire the rotation of the node.
        btQuaternion orientation((btScalar)rx,(btScalar)ry,(btScalar)rz);
        btTransform trans2(orientation,btVector3(X,Y,Z));
        pair.second->setWorldTransform(trans2);
    }
}


Top
 Profile  
Reply with quote  
PostPosted: 30.09.2010, 08:32 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
I wonder why you have to decompose the matrix to set it in bullet? Is it only to avoid scaling? Maybe you should then change the vertex positions instead of apply scaling to the modelnode, this way you have the same matrix within Horde and bullet, which may reduce errors, since the decomposition of the rotation from the matrix normally suffers from singularities. If you still want to decompose the matrix you can also have a look at the decompose function of Matrix4f. But as already mentioned, their are problems in certain rotation cases.


Top
 Profile  
Reply with quote  
PostPosted: 30.09.2010, 17:23 
Offline

Joined: 09.09.2009, 18:58
Posts: 107
Here is the code as I currently have it (untested)

Code:
void Actor::Update(float time)
{
    BOOST_FOREACH(CollisionMapPair pair, collision_map)
    {
        const float** mat;
        float* trans;
        float* rot;
        float* scal;
        h3dGetNodeTransMats(pair.first,NULL,mat);

        decompose(mat,trans,rot,scal);

        btQuaternion orientation((btScalar)rot[0],(btScalar)rot[1],(btScalar)rot[2]);
        btTransform btrans(orientation,btVector3(trans[0],trans[1],trans[2]));
        pair.second->setWorldTransform(btrans);
    }
    // if it has a core object defined
    if(core_object && asUpdate > 0)
    {
        int r;
        Stage::I()->getContext()->Prepare(asUpdate);
        Stage::I()->getContext()->SetArgFloat(0,time);
        r = Stage::I()->getContext()->Execute();
        if(r != asEXECUTION_FINISHED)
        {
            if(r == asEXECUTION_EXCEPTION)
            {
                LOG("An exception '"+string(Stage::I()->getContext()->GetExceptionString())+
                    "' occurred. Please correct the code and try again.",FATAL);
                Engine::I()->Kill();
            }
        }
    }
}


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group