Scenegraph rotation problem [SOLVED]

Started by
4 comments, last by mobeen 16 years, 12 months ago
Hi all, I am doing a simplistic scenegraph implementation. I have a scenenode class containing a transformation matrix (transform) to store the object's orientation. In render, I set the world transform to the current node's transform*its parent's transform. This works as long as the node is parented to an unrotated parent. If I parent a scene node to a parent which is rotated, the results are weird. http://www.geocities.com/mobeen211/image2.PNG However, if i parent it to an unrotated but translated parent it works ok. http://www.geocities.com/mobeen211/image1.PNG My question is how can this issue be solved? Should I create two matrices one for local and other for the world transform of the node? Regards, Mobeen [Edited by - mobeen on April 24, 2007 4:31:01 AM]
Proud to be a PAKISTANI.
Advertisement
Sorry for the trouble guys. Like so many of my previous issues as soon as I discuss it with anyone i get the answer. I have it sorted now. I was missing a single line to undo parent rotation now its working ok.
Proud to be a PAKISTANI.
Quote:Original post by mobeen
Sorry for the trouble guys. Like so many of my previous issues as soon as I discuss it with anyone i get the answer. I have it sorted now. I was missing a single line to undo parent rotation now its working ok.

It'll be helpful if you can show us the solution, in case others have your problem or something similar to it.

Beginner in Game Development?  Read here. And read here.

 

Quote:I was missing a single line to undo parent rotation now its working ok.
Sounds a bit wierd to have to explicitly undo parent rotation, unless the child nodes for some reason don't inherit a parent's rotation (???). If your scene node has a node->parent transform then you should just recursively concatentate the node->parent * parent_node->parent_parent etc, resulting in node->world (or at least node->hierarchy_root which is normally world space). At some point a parent will have no parent in which case either copy the transform or concatenate with identity.
Alpha_ProgDes said:

It'll be helpful if you can show us the solution, in case others have your problem or something similar to it.

Well this is how i have my scene node render setup. This is in managed directx and c#.
In my scenegraph i have setup the root node with a meshindex of -1 and have meshindices stored in each SceneNode. A singleton Meshloader loads all the meshes and stores them in containers. Every scenennode has a bbox which is updated based on the current transform.

void Render(Device dev)
{
if(meshIndex!=-1)
{
Matrix comb = transform*parent.transform;
if(dev.Transform.World != comb)
{
dev.Transform.World = comb;
bbox.Update(comb);
MeshLoader.instance.renderMesh(dev, meshIndex);
}
}

if(children.Count==0)
return;

//recurse on children
foreach(SceneNode s in children)
s.Render(dev);
}

Now I have a scenenode lister to graphically show a treeview of my scenegraph. If u want a node to be parented to another node, simply drag it on the parent.
This is what i do in the drag drop code. I have forced user to only rotate in the y axis only.

void DragDropNode(string parentName, string childName)
{
SceneNode parent = GetNodeByName(parentName);
SceneNode childName = GetNodeByName(childName);

if(parent == null || child == null)
return;

Vector3 offset = new Vector3(child.Transform.M41 - parent.Transform.M41,
child.Transform.M42 - parent.Transform.M42,
child.Transform.M43 - parent.Transform.M43);

float offsetRot = child.RotationAmount - parent.RotationAmount;
child.parent = parent;
child.Transform = Matrix.Translate(offset.X, offset.Y, offset.Z)* Matrix.RotationYawPitchRoll(offsetRot,0,0);
}

Rompa said:

Sounds a bit wierd to have to explicitly undo parent rotation, unless the child nodes for some reason don't inherit a parent's rotation (???). If your scene node has a node->parent transform then you should just recursively concatentate the node->parent * parent_node->parent_parent etc, resulting in node->world (or at least node->hierarchy_root which is normally world space). At some point a parent will have no parent in which case either copy the transform or concatenate with identity.

Yeah i m recursively setting the node's transform but if if the node is parented to a rotated parent, weird transformations occur.
Proud to be a PAKISTANI.
Ok guys,
I managed to find the solution. The problem was that on each render I was concatenating the childnodes transform to its parent. This was working ok if the parent was unrotated. But then if you have a rotated parent node, you have to multiply the child's transform by the inverse of the parent's rotation matrix. So my new drag drop code is as follows.
void DragDropNode(string parentName, string childName){   SceneNode parent = GetNodeByName(parentName);   SceneNode childName = GetNodeByName(childName);   if(parent == null || child == null)       return;   Vector3 offset = new Vector3(child.Transform.M41 - parent.Transform.M41,                                child.Transform.M42 - parent.Transform.M42,                                child.Transform.M43 - parent.Transform.M43);   //Get the parent's transform   Matrix invRot = parent.transform;   //Remove any translation values   invRot.M41 = 0;   invRot.M42 = 0;   invRot.M43 = 0;   //Invert rotation only   invRot.Invert();   //Attach the new parent   child.parent = parent;   //Set the new transform   //Note that i only allow rotation in the y axiz   child.Transform = Matrix.RotationYawPitchRoll(rotationValue,0,0) *Matrix.Translate(offset.X, offset.Y, offset.Z)*invMat ;}

Now it works spot on.
Proud to be a PAKISTANI.

This topic is closed to new replies.

Advertisement