Transformation Error with Parent
Posted: Thu Mar 23, 2006 5:01 am
Hi all ,
I moved this thread from bugs report forum.
First, let me explain the situation.
Suppose I create 3 scenenodes, named nodeA, nodeB and nodeC which all of them are child of root scenenode.
Then I add node to nodeA, nodeB
Parent Children
----------------------------------------
nodeA nodeA1
nodeA nodeA2
nodeA nodeA3
nodeB nodeB1
nodeB nodeB1
nodeB nodeB1
I want to setParent of nodeA1-3 and nodeB1-3 to nodeC but
position, rotation and scaling of children node MUST NOT change so I needed to recalculate each position, rotation and scaling to relative with new parent which is nodeC but position and scaling are mess up!
Here is my code for grouping
createGroupSceneNode() is creating empty scene node that doesn't do anything more than conthainer of scene node.
Any help would by greatly appreciated.
I moved this thread from bugs report forum.
First, let me explain the situation.
Suppose I create 3 scenenodes, named nodeA, nodeB and nodeC which all of them are child of root scenenode.
Then I add node to nodeA, nodeB
Parent Children
----------------------------------------
nodeA nodeA1
nodeA nodeA2
nodeA nodeA3
nodeB nodeB1
nodeB nodeB1
nodeB nodeB1
I want to setParent of nodeA1-3 and nodeB1-3 to nodeC but
position, rotation and scaling of children node MUST NOT change so I needed to recalculate each position, rotation and scaling to relative with new parent which is nodeC but position and scaling are mess up!
Here is my code for grouping
Code: Select all
// nodeList : list of node to be group
// refIndex : index of node that will be a reference position, rotation, scaling of other node in group
irr::scene::ISceneNode* CSceneNodeFactory::groupSceneNode(std::vector<irr::scene::ISceneNode*>& nodeList, irr::s32 refIndex, irr::scene::ISceneManager* smgr)
{
if (nodeList.size() == 0 || refIndex < 0 || !smgr)
{
return 0;
}
// Create a new groupSceneNode for all SceneNode in nodeList.
ISceneNode* newGroup = CSceneNodeFactory::createGroupSceneNode(0, smgr);
// Set position for the new groupSceneNode.
ISceneNode* currentNode = nodeList.at(refIndex);
newGroup->setPosition(currentNode->getPosition());
newGroup->setRotation(currentNode->getRotation());
//newGroup->setScale(currentSceneNode->getScale());
irr::core::list<ISceneNode*>::Iterator itr;
irr::core::list<ISceneNode*> newList;
irr::core::list<ISceneNode*> children;
for (u32 i = 0; i < nodeList.size(); ++i)
{
currentNode = nodeList.at(i);
if (currentNode->getChildren().getSize() > 0)
{
// has children
itr = currentNode->getChildren().begin();
for (; itr != currentNode->getChildren().end(); ++itr)
{
irr::scene::ISceneNode* node = (*itr);
vector3df newPos;
vector3df newRot;
vector3df newScl;
vector3df myScale;
vector3df parentScale;
matrix4 mat;
node->updateAbsolutePosition();
mat = node->getAbsoluteTransformation();
CLogger::print("before", mat.getTranslation());
CLogger::print("mat", getScale(mat));
newPos = (node->getPosition() + currentNode->getPosition()) - newGroup->getPosition();
newRot = (node->getRotation() + currentNode->getRotation()) - newGroup->getRotation();
myScale = node->getScale();
parentScale = currentNode->getScale();
newScl.X = myScale.X * parentScale.X;
newScl.Y = myScale.Y * parentScale.Y;
newScl.Z = myScale.Z * parentScale.Z;
node->setPosition(newPos);
node->setRotation(newRot);
//node->setScale(newScl);
newList.push_back(node);
node->updateAbsolutePosition();
mat = node->getAbsoluteTransformation();
}
deleteSceneNode(currentNode, smgr, 1);
currentNode = 0;
}
else
{
irr::scene::ISceneNode* node = currentNode;
vector3df newPos;
vector3df newRot;
vector3df newScl;
newPos = node->getPosition() - newGroup->getPosition();
newRot = node->getRotation() - newGroup->getRotation();
newScl = node->getScale();
node->setPosition(newPos);
node->setRotation(newRot);
node->setScale(newScl);
newList.push_back(node);
}
}
for (itr = newList.begin(); itr != newList.end(); ++itr)
{
(*itr)->setParent(newGroup);
}
return newGroup;
}
Code: Select all
virtual core::matrix4 getRelativeTransformation() const
{
core::matrix4 mat;
mat.setRotationDegrees(RelativeRotation);
if (RelativeScale != core::vector3df(1,1,1))
{
core::matrix4 smat;
smat.setScale(RelativeScale);
mat *= smat;
}
mat.setTranslation(RelativeTranslation);
return mat;
}