To rotate / revolve node in world space & in local space

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

To rotate / revolve node in world space & in local space

Post by smso »

To rotate / revolve node in world space & in local space
Last updated: 5th Jan, 1013


/*** 5 rotateNode and revolveNode functions ***/

Code: Select all

 
void rotateNodeInWorldSpace(scene::ISceneNode* node, f32 degs, const core::vector3df& axis)
{
    core::quaternion q;
    q.fromAngleAxis(degs*core::DEGTORAD, axis);
    core::matrix4 m1 = q.getMatrix();
 
    node->updateAbsolutePosition();
    core::matrix4 m2 = node->getAbsoluteTransformation();
    
    core::matrix4 m = m1*m2;
    node->setRotation(m.getRotationDegrees());
    
}

Code: Select all

 
void rotateNodeInLocalSpace(scene::ISceneNode* node, f32 degs, const core::vector3df& axis)
{
    node->updateAbsolutePosition();
    core::matrix4 m2 = node->getAbsoluteTransformation();
    core::vector3df a = axis;
    m2.rotateVect(a);
    a.normalize();
 
    core::quaternion q;
    q.fromAngleAxis(degs*core::DEGTORAD, a);
    core::matrix4 m1 = q.getMatrix();
 
    core::matrix4 m = m1*m2;
    node->setRotation(m.getRotationDegrees());
    
}

Code: Select all

 
//both axis and pivot are in world space
void revolveNodeInWorldSpace(scene::ISceneNode* node, f32 degs, const core::vector3df& axis, const core::vector3df& pivot)
{
    node->updateAbsolutePosition();
    core::vector3df p1 = node->getAbsolutePosition();
    core::vector3df p2 = getClosestPointOnLine(axis, pivot, p1);
    core::vector3df vect = p1 - p2;
    
    core::quaternion q;
    q.fromAngleAxis(degs*core::DEGTORAD, axis);
    q.getMatrix().rotateVect(vect);
    
    node->setPosition(p2 + vect);
}

Code: Select all

 
//both axis and pivot are in local space
void revolveNodeInLocalSpace(scene::ISceneNode* node, f32 degs, const core::vector3df& axis, const core::vector3df& pivot)
{
    moveNodeInLocalSpace(node, pivot);
    rotateNodeInLocalSpace(node, degs, axis);
    moveNodeInLocalSpace(node, -pivot);
}

Code: Select all

 
//axis is in local space and pivot in world space
void revolveNodeAboutLocalAxis(scene::ISceneNode* node, f32 degs, const core::vector3df& axis, const core::vector3df& pivot)
{
    node->updateAbsolutePosition();
    core::matrix4 m = node->getAbsoluteTransformation();
    core::vector3df a = axis;
    m.rotateVect(a);
    a.normalize();
 
    core::vector3df p1 = node->getAbsolutePosition();
    core::vector3df p2 = getClosestPointOnLine(a, pivot, p1);
    core::vector3df vect = p1 - p2;
 
    core::quaternion q;
    q.fromAngleAxis(degs*core::DEGTORAD, a);
    q.getMatrix().rotateVect(vect);
    
 
    node->setPosition(p2 + vect);
    
}

/*** helper functions ****/

Code: Select all

 
void moveNodeInLocalSpace(scene::ISceneNode* node, const core::vector3df& distVect)
{
    node->updateAbsolutePosition();
    core::matrix4 m = node->getAbsoluteTransformation();
    core::vector3df d = distVect;
    m.rotateVect(d);
        
    core::vector3df pos = node->getAbsolutePosition() + d;
    node->setPosition(pos);
}

Code: Select all

 
void moveNodeInLocalSpace(scene::ISceneNode* node, const core::vector3df& dir, f32 dist)
{
    node->updateAbsolutePosition();
    core::matrix4 m = node->getAbsoluteTransformation();
    core::vector3df d = dir;
    m.rotateVect(d);
    d.normalize();
    
    core::vector3df pos = node->getAbsolutePosition() + d * dist;
    node->setPosition(pos);
}

Code: Select all

 
// the line is defined by axis direction passing through the pivot
// 3rd argument "point" is the external point
core::vector3df getClosestPointOnLine
(
    const core::vector3df& axis,
    const core::vector3df& pivot,
    const core::vector3df& point
)
{
    core::vector3df c = point - pivot;
    f32 t = axis.dotProduct(c);
    return pivot + axis*t;
}



Regards,
smso
Last edited by smso on Sat Jan 05, 2013 1:30 pm, edited 6 times in total.
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Re: To rotate node in world space and in local space

Post by christianclavet »

Thanks smso!

So by finding the current orientation vector of a node, I could input this in "axis" and enter an offset without suffering gimbal lock? I think I really could put this to use. I will have something to study!
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: To rotate node in world space and in local space

Post by smso »

Added 2 "revolveNode" functions with pivot:

Code: Select all

revolveNodeInWorldSpace()
and

Code: Select all

revolveNodeAboutLocalAxis()
See first post.


Regards,
smso
Last edited by smso on Sat Jan 05, 2013 1:31 pm, edited 3 times in total.
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: To rotate node in world space and in local space

Post by smso »

christianclavet wrote: So by finding the current orientation vector of a node, I could input this in "axis" and enter an offset without suffering gimbal lock?
@christianclavet
It's better for discussion if you could provide a picture to show what you want to achieve.

Regards,
smso
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Re: To rotate node in world space and in local space

Post by christianclavet »

Ha, it's simple and I think I will be able to do it with your provided code. Will use it to rotate a node with the mouse without having problems with gimbal lock.

I'll take a node oriented at a specific position (let's say 45,36,67 degree),
input will be mouse movement offset. (so very small increments). From there, try to find the directional vector and find the offset value.
Once I have those value, I only have to use it with your code and will have the resulting "final" position.

Thanks for the others functions!
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: To rotate / revolve node in world space & in local space

Post by smso »

Added one more revolveNode function and some helper functions.
See first post.


Regards,
smso
chronologicaldot
Competition winner
Posts: 685
Joined: Mon Sep 10, 2012 8:51 am

Re: To rotate / revolve node in world space & in local space

Post by chronologicaldot »

Sweet. Thanks, smso!
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: To rotate / revolve node in world space & in local space

Post by hendu »

Seems some of these do what my patch here does:
http://irrlicht.sourceforge.net/forum/v ... =7&t=45846
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: To rotate / revolve node in world space & in local space

Post by smso »

hendu wrote:Seems some of these do what my patch here does:
http://irrlicht.sourceforge.net/forum/v ... =7&t=45846
Thanks for the patching work. I must admit that some functions written by me is not as concise as yours but I did so mainly for learning purposes.

By the way, the patch reminds me of the setRotationCenter() function of class core::matrix4, which I nearly forgot:)

Regards,
smso
Post Reply