Rotate around a point 3D
Rotate around a point 3D
Hi all,
Hmm i know i've probably asked a similar question regarding rotation before but this one has me stumped.
I've been wondering if it is possible to rotate a billboardscene node around a point (another billboard as the center), from its original position to another position in 3D.
Here is a pic
Basically it is a protein in 3D, what i wanted to do was pick an 'atom' shall we say A, as the point of rotation and then pick a position in 3D space point X and rotate atom B so as to be placed on point X .
Now i set it up so every atom of the protein is a child of the atom that is being rotate around (A). One way i though of doing it was to pick the point in 3D, scale back or up to the correct distance between atom A and atom B and then work out the angles needed to move point B for each axis to position X.
It sounded complicated so i'd though i'd ask if there was a better way
Regards Wolfe
Hmm i know i've probably asked a similar question regarding rotation before but this one has me stumped.
I've been wondering if it is possible to rotate a billboardscene node around a point (another billboard as the center), from its original position to another position in 3D.
Here is a pic
Basically it is a protein in 3D, what i wanted to do was pick an 'atom' shall we say A, as the point of rotation and then pick a position in 3D space point X and rotate atom B so as to be placed on point X .
Now i set it up so every atom of the protein is a child of the atom that is being rotate around (A). One way i though of doing it was to pick the point in 3D, scale back or up to the correct distance between atom A and atom B and then work out the angles needed to move point B for each axis to position X.
It sounded complicated so i'd though i'd ask if there was a better way
Regards Wolfe
If A is parent to B, and A rotates , then B should also rotate.
If A rotates around the Y axes (or the axis pointing up) then B also rotates around that axis.
If all childs to A should not been rotates, then you can release / attach the parent - child relation as needed.
Can you not simply rotate the parent?
If A rotates around the Y axes (or the axis pointing up) then B also rotates around that axis.
If all childs to A should not been rotates, then you can release / attach the parent - child relation as needed.
Can you not simply rotate the parent?
You can use matrix for rotation. Something like this should work:
Note that rotations are set in Euler angles.
[EDIT:] it should be nodeB->setPosition(nodeA->getPosition() + relPos); not nodeB->setPosition(nodeB->getPosition() + relPos); ...corrected.
Code: Select all
vector3df relPos = nodeB->getPosition() - nodeA->getPosition();
core::matrix4 matrix;
matrix.setRotationDegrees(core::vector3df rotation);
matrix.rotateVect(relPos);
nodeB->setPosition(nodeA->getPosition() + relPos);
[EDIT:] it should be nodeB->setPosition(nodeA->getPosition() + relPos); not nodeB->setPosition(nodeB->getPosition() + relPos); ...corrected.
Last edited by arras on Thu Feb 28, 2008 9:54 am, edited 1 time in total.
If you want the whole molecule to rotate, I think you should be able to use a empty/dummy scene node.
- get delta vector from parent absolute position to X
- add delta vector to parent node translation, thus moving the parent node to X
- remove delta vector from child translation. this moves the child back to the same absolute position.
- rotate the parent as necessary
Yep thats what i want to do, the tricky part is knowing what rotation is required in order to move atom B to point X.Can you not simply rotate the parent?
What i don't see is where exactly do you use position X's vector3D in the above equation?You can use matrix for rotation. Something like this should work:
Code:
vector3df relPos = nodeB->getPosition() - nodeA->getPosition();
core::matrix4 matrix;
matrix.setRotationDegrees(core::vector3df rotation);
matrix.rotateVect(relPos);
nodeB->setPosition(nodeA->getPosition() + relPos);
Note that rotations are set in Euler angles.
Surely having every other atom as a child of the parent means the whole molecule will rotate relative to the parent.If you want the whole molecule to rotate, I think you should be able to use a empty/dummy scene node.
Regards Wolfe
If you want to rotate B around A then X is not just any point you can choose by its position. It's distance from A must be equal distance of B from A. It must lay on the same circle as B with center in A. Therefore you must define X by angle of rotation. That is vector3df rotation. Or did I miss something?What i don't see is where exactly do you use position X's vector3D in the above equation?
The problem is i don't necessarily want to rotate atom B around A.
What i want to do is rotate atom A 'SO THAT' atom B is moved onto the chosen vector3d, which would be scaled back to the correct distance as i mentioned previously.
Because every other atom is a child of atom A, it is atom A i want to rotate thus in essence also moving every other atom
Regards Wolfe
What i want to do is rotate atom A 'SO THAT' atom B is moved onto the chosen vector3d, which would be scaled back to the correct distance as i mentioned previously.
Because every other atom is a child of atom A, it is atom A i want to rotate thus in essence also moving every other atom
Regards Wolfe
Nice task. Ugly, but might work:
Start rotating A, keep track of the x position of the target atom until it reaches to wanted x position using getposition() on the target atom mesh, then stop rotating the parent ( A ).
So far for one angle, if you want to rotate the whole thing so the picked atom will face the camera, you can use a simmilair system.
Ofcourse there are math equations to solve this, but this method might give you the correct result.
Start rotating A, keep track of the x position of the target atom until it reaches to wanted x position using getposition() on the target atom mesh, then stop rotating the parent ( A ).
So far for one angle, if you want to rotate the whole thing so the picked atom will face the camera, you can use a simmilair system.
Ofcourse there are math equations to solve this, but this method might give you the correct result.
If atoms of the molecule are fixed position, you can simply treat the molecule as one group.
But...
If the atoms are going to fold to simulate something else, now that's a different story.
Are you going to simulate molecular bonding? Like proteins and amino acids?
And will these molecules also fold? That's going to be complicated.
Wow, that's super incredible.
I'd like to see a screenshot of your progress, please.
Well, you could look into the cord physics pattern to simulate connections from a joint. Like dangling cords, to be exact. With a slight change of how they are attracted or repelled.
But...
If the atoms are going to fold to simulate something else, now that's a different story.
Are you going to simulate molecular bonding? Like proteins and amino acids?
And will these molecules also fold? That's going to be complicated.
Wow, that's super incredible.
I'd like to see a screenshot of your progress, please.
Well, you could look into the cord physics pattern to simulate connections from a joint. Like dangling cords, to be exact. With a slight change of how they are attracted or repelled.
Sadly not as complicated as that Dlangdev, it's just for a simplier protein alignment algorithm, based on an estimation distribution algorithm.
Though what you've said has peaked my interest.
The previous method i've looked into using is rather abstract. All you need is two rotations in order to move an object to a position in 3D space, given it is in the circumference/ distance between the two atoms.
Regards Wolfe
Though what you've said has peaked my interest.
The previous method i've looked into using is rather abstract. All you need is two rotations in order to move an object to a position in 3D space, given it is in the circumference/ distance between the two atoms.
Regards Wolfe
Well after hashing around a bit i need someone with more knowledge to help me on some things
One, relation between parent and child:
before setting either lets say we have node A with position 1,1,1 and node B position 5,5,5
If you were to set node A to be a child of node B then does it retain it's orignal position and simply change it to be relative to the parent so it will read 1,1,1 but really be 4,4,4? in absolute position sense.
If this is true above, when does it exactly become fact, i've been told that absolute positions are updated every frame so any change inbetween one isn't applied yet.
I've been fiddling with updateabsoluteposition() but this doesn't seem to be having the effect i would expect.
If i create a node, then create a parent node. Set the parent nodes position to that of the first node, make it a parent of the first node and then move the parent node to another position, even if i call updateabsoluteposition() several times the first node always shows the same absolute position which is the same as its relative position.
Surly you would expect both nodes to be either placed in the same position or for the first node to be slightly displaced becuase it is relative to the parent now, however it seems its position is only finally set correctly when the next frame is invoked.
Is this how it should be .
Parent child relationships are hard
Regards Wolfe
One, relation between parent and child:
before setting either lets say we have node A with position 1,1,1 and node B position 5,5,5
If you were to set node A to be a child of node B then does it retain it's orignal position and simply change it to be relative to the parent so it will read 1,1,1 but really be 4,4,4? in absolute position sense.
If this is true above, when does it exactly become fact, i've been told that absolute positions are updated every frame so any change inbetween one isn't applied yet.
I've been fiddling with updateabsoluteposition() but this doesn't seem to be having the effect i would expect.
If i create a node, then create a parent node. Set the parent nodes position to that of the first node, make it a parent of the first node and then move the parent node to another position, even if i call updateabsoluteposition() several times the first node always shows the same absolute position which is the same as its relative position.
Surly you would expect both nodes to be either placed in the same position or for the first node to be slightly displaced becuase it is relative to the parent now, however it seems its position is only finally set correctly when the next frame is invoked.
Is this how it should be .
Parent child relationships are hard
Regards Wolfe
The relative position of the node will not be updated when the object is reparented. If we assume that A and B are parented to the root scene node, then their relative positions are their absolute positions. If you set A to be a child of B, A will be offset from the absolute position of B by its own relative position. So the new absolute position of A will be (5, 5, 5) + (1, 1, 1), the relative position will remain (1, 1, 1).cdrwolfe wrote:before setting either lets say we have node A with position 1,1,1 and node B position 5,5,5
If you were to set node A to be a child of node B then does it retain it's orignal position and simply change it to be relative to the parent so it will read 1,1,1 but really be 4,4,4? in absolute position sense.
If you want to reparent a node without affecting its absolute position, you need to calculate the new position, and then apply it. I belive that the following code would do the trick. Of course if you want the node to be oriented and scaled correctly, you can use the absolute transformations to do something similar...
Code: Select all
// ensure position is up to date
A->updateAbsolutePosition();
// get the current world position of A
core::vector3df pos = A->getAbsolutePosition();
// transform that position into B's coordinate system
B->getAbsoluteTransformation().inverseTranslateVect(pos);
// set A as a child of B
A->setParent (B);
// move A into B's coordinate system
A->setPosition (pos);
// update the absolute transformation of A
A->updateAbsolutePosition ();
The absolute positions are updated automatically inside the smgr->drawAll(). If you want to update the absolute position explicitly, you can do it with updateAbsolutePosition().If this is true above, when does it exactly become fact, i've been told that absolute positions are updated every frame so any change inbetween one isn't applied yet.
It does work, you just have to update the absolute positions of all of the nodes up to the root.I've been fiddling with updateabsoluteposition() but this doesn't seem to be having the effect i would expect.
Yes, like I said, you need to update the absolute positions of all nodes involved. By default the AbsoluteTransformation of each scene node is the identity matrix. If you call updateAbsolutePosition(), the relative position, rotation and scale are applied to the AbsoluteTransformation matrix in addition to the AbsoluteTransformation of the parent scene node. But if the parent matrix hasn't been updated, then the child position won't include the parent position, rotation and scale.If i create a node, then create a parent node. Set the parent nodes position to that of the first node, make it a parent of the first node and then move the parent node to another position, even if i call updateabsoluteposition() several times the first node always shows the same absolute position which is the same as its relative position.
The following function can update the position of a node and its ancestors, thus getting it the most up to date AbsoluteTransformation.
Code: Select all
void ISceneNode_updateAbsolutePosition (scene::ISceneNode* node)
{
scene::ISceneNode* parent = node->getParent ();
if (parent)
ISceneNode_updateAbsolutePosition (parent);
node->updateAbsolutePosition ();
}
If you specify the position as a parameter to the add*SceneNode function, the AbsoluteTransformation will be updated before the add*SceneNode call returns. If you do this for all scene nodes, then all objects will be placed at the correct positions.Surly you would expect both nodes to be either placed in the same position or for the first node to be slightly displaced becuase it is relative to the parent now, however it seems its position is only finally set correctly when the next frame is invoked.
If you have a full scene graph that you want to update, the following code will do just that...
Code: Select all
void ISceneNode_updateAll (scene::ISceneNode* node)
{
node->updateAbsolutePosition();
core::list<scene::ISceneNode*>::ConstIterator beg = node->getChildren ().begin();
core::list<scene::ISceneNode*>::ConstIterator end = node->getChildren ().end ();
for (/**/; beg != end; ++beg)
ISceneNode_updateAll (*beg);
}
void ISceneManager_updateAll (scene::ISceneManager* smgr)
{
ISceneNode_updateAll (smgr->getRootSceneNode ());
}
Thanks Vitek,vitek wrote:If you want the whole molecule to rotate, I think you should be able to use a empty/dummy scene node.
Travis
- get delta vector from parent absolute position to X
- add delta vector to parent node translation, thus moving the parent node to X
- remove delta vector from child translation. this moves the child back to the same absolute position.
- rotate the parent as necessary
I'd though i'd also have a go at using your technique for the overall rotation.
At the moment mine is a long winded attempt based upon an older one i did for ship rotation. Essentially working out the angles for both the X axis and Y axis and then applying them to the parent i.e parent.rotation = new vector (rotX, rotY, parent.rotation.Z).
For your method, i assume i hope that by delta vector you mean the distance between the two nodes, i.e X.position - parent.position which i assume is the unit vector?
You mentioned adding the delta vector to the parent node translation thus moving the parent to position X.
Silly question but can't you set the parents position to that simply of X.
i.e parent.position = X.position? or use absolutepositions if you have to.
My problem has always been how to get the angle to rotate by and then how to apply it to the parent in order to rotate the whole molecule and have the child Node B rotated to position X (naturally assuming correct distance).
Also one quick question regarding parent/child, i'am at work so i can't check but is it possible to set a node who already has a parent back to having the root scene node as a parent.
I had originally just simply reset the node to have as it's parent 'Itself'but later noticed that its position is shifted by its relative position bahh .
Thanks for the help anyway i'll give it a go tonight
Regards Wolfe