How can I rotate an ISceneNode around a given axis?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
mybiandou
Posts: 32
Joined: Thu Sep 10, 2009 6:20 am

How can I rotate an ISceneNode around a given axis?

Post by mybiandou »

I want to rotate an ISceneNode around my given axis,
for example, the axis is defined by the reference point vector3df(xo,yo,zo) and the direction vector3df(ax,ay,az) under global coordinates

The ISceneNode is defined by the following

ISceneNode *node=smgr0>addEmptySceneNode();
node->addChild(...) //add a lot of sub models
....


How can I realize this kind of rotation?

Thank you in advance.
FuzzYspo0N
Posts: 914
Joined: Fri Aug 03, 2007 12:43 pm
Location: South Africa
Contact:

Post by FuzzYspo0N »

You can use something like :

Code: Select all

core::matrix4 curPos = node->getAbsoluteTransformation();

curPos.rotateBy( core::vector3df() );

The functions inside the core::matrix4 class are really easy to use for rotation, check the docs for a full list of features.
mybiandou
Posts: 32
Joined: Thu Sep 10, 2009 6:20 am

Post by mybiandou »

But the given axis is defined via one reference point and the direction,
for example , an axis starts from xa,ya,za, and its direction is vx,vy,vz

How do you use the reference point information?
FuzzYspo0N wrote:You can use something like :

Code: Select all

core::matrix4 curPos = node->getAbsoluteTransformation();

curPos.rotateBy( core::vector3df() );

The functions inside the core::matrix4 class are really easy to use for rotation, check the docs for a full list of features.
Bear_130278
Posts: 237
Joined: Mon Jan 16, 2006 1:18 pm
Location: Odessa,Russian Federation

Post by Bear_130278 »

But vector3d is a vector indeed 8))) With a point in space and a direction.
Do you like VODKA???
Image
Image
mybiandou
Posts: 32
Joined: Thu Sep 10, 2009 6:20 am

Post by mybiandou »

But,. sorry, I read the reference of vector3d once more, I only can find 3 members of class vector3d named X Y Z
http://irrlicht.sourceforge.net/docu/cl ... tor3d.html

If it is a point-based vector, it should have six members but not three like the free vector(only has direction but hasn't reference point)


Bear_130278 wrote:But vector3d is a vector indeed 8))) With a point in space and a direction.
[/url]
Bear_130278
Posts: 237
Joined: Mon Jan 16, 2006 1:18 pm
Location: Odessa,Russian Federation

Post by Bear_130278 »

vector3d< T >::getLength ( )
How about this?
How can you get a length if you do not have direction?? :)


Hmmm maybe you are right 8)))
T getLength() const { return (T) sqrt((f64)(X*X + Y*Y + Z*Z)); }
Do you like VODKA???
Image
Image
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

Take a look at the API for Quaternions;
http://irrlicht.sourceforge.net/docu/cl ... rnion.html

they can be constructed from a vector and an angle (i.e. rotate around a given vector) then calculate a vector3df which can be used to set the rotation of a scene node. They don't have any method (that I've found) to set the other 2 axes of rotation however.
mybiandou
Posts: 32
Joined: Thu Sep 10, 2009 6:20 am

Post by mybiandou »

The quaternion is a combination by the rotation direction and the rotation angle. Also, it has no reference point information.

If the reference point of the direction vector can not be provided, maybe the default reference point is (0,0,0).

Thank you all very much.

DavidJE13 wrote:Take a look at the API for Quaternions;
http://irrlicht.sourceforge.net/docu/cl ... rnion.html

they can be constructed from a vector and an angle (i.e. rotate around a given vector) then calculate a vector3df which can be used to set the rotation of a scene node. They don't have any method (that I've found) to set the other 2 axes of rotation however.
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

the default reference point is 0,0,0 of the node being rotated, effectively (not 0,0,0 of the world). If you want to move it around some other reference, you'll need to create a vector which points from the reference to your object, then apply the rotation to that vector and set the node's position to referencePoint + rotatedVector, as well as setting the node's rotation. This is because rotations in Irrlicht have no translation component.
mybiandou
Posts: 32
Joined: Thu Sep 10, 2009 6:20 am

Post by mybiandou »

Thank you for your explanation.
To clarify the question more clearly, take the following drawing as an example.
The origin of the world coordinates is at O point (xog,yog,zog)
The object A is mounted to scene node root with local coordinates(xl,yl,zl)

So when I rotate the scene node O' by a free vector(no reference point given), all the mesh nodes and scene nodes related to it will rotate rounding by the origin of the O'.

If I want to rotate the scene node O' and its children objects rounding by the given reference point C ,

How can I do it?

Code: Select all

ISceneNode *root;
ISceneNode *child;
root=smgr->addEmptySceneNode(0,-1);  //add an empty scene node to world coord
root->setPoisition(xog,yog,zog);

//add a child cube scene node with size lengthxwidthxheight at (xl,yl,zl) under local coordinate
child=smgr->addCubeSceneNode(1.0f,root,-1,vector3df(xl,yl,zl),vector3df(0,0,0),vector3df(length,width,height));	

//then I want to rotate the scene node root and its child together around vector (vxg,vyg,vzg) written under world coordinate and the reference point (xcg,ycg,zcg) also written under world coords
//how can I do it?

The following is my subroutine for rotate a rigid body by time
But I can not specify the rotating reference point.

Code: Select all

void CRBODY::onDeltaTime(float dtime)
{
	float x,y,z;
	irr::core::vector3df oldrot;

	//rotate it by angle speed around given axis
	irr::core::vector3df myaxis;
	float myangle;
	irr::core::vector3df myrotation;
	irr::core::quaternion q;

	myaxis.X=this->ax;
	myaxis.Y=this->ay;
	myaxis.Z=this->az;
	myaxis.normalize();

	myangle=this->rot_speed*dtime;
	
	q.fromAngleAxis(myangle, myaxis);
	q.toEuler(myrotation);	

	oldrot=root->getRotation();
	myrotation+=oldrot;
	root->setRotation(myrotation);
}
Image


DavidJE13 wrote:the default reference point is 0,0,0 of the node being rotated, effectively (not 0,0,0 of the world). If you want to move it around some other reference, you'll need to create a vector which points from the reference to your object, then apply the rotation to that vector and set the node's position to referencePoint + rotatedVector, as well as setting the node's rotation. This is because rotations in Irrlicht have no translation component.
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

I wouldn't recommend rotating the root node, but if you do, then ensure you *only* rotate the root - it will rotate every other node itself.

Code for rotating a node "sn" by angle vector "ang" and reference point "cen":

Code: Select all

sn->updateAbsolutePosition( );
CMatrix4<f32> mtrans = sn->getParent( )->getAbsoluteTransformation( );
CMatrix4<f32> mitrans;
mtrans->getInverse( &mitrans );
vector3d<f32> offset = sn->getAbsolutePosition( ) - cen;
vector3d<f32> angle = sn->getRotation( );
CMatrix4<f32> mangle = CMatrix4<f32>( )->setRotationDegrees( angle );
CMatrix4<f32> mang = CMatrix4<f32>( )->setRotationDegrees( ang );
mang->rotateVect( &offset );
offset += cen;
mitrans->transformVect( &offset );
sn->setPosition( offset );
sn->setRotation( (mang * mangle)->getRotationDegrees( ) );
should work in all cases, but I haven't actually tested the code. If you're only interested in rotating the root node, most of that isn't needed;

Code: Select all

sn->updateAbsolutePosition( );
vector3d<f32> offset = sn->getAbsolutePosition( ) - cen;
vector3d<f32> angle = sn->getRotation( );
CMatrix4<f32> mangle = CMatrix4<f32>( )->setRotationDegrees( angle );
CMatrix4<f32> mang = CMatrix4<f32>( )->setRotationDegrees( ang );
mang->rotateVect( &offset );
sn->setPosition( offset + cen );
sn->setRotation( (mang * mangle)->getRotationDegrees( ) );
Post Reply