[HELP!!!] Moving nodes to targeted positions + rotations

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
jorgerosa
Competition winner
Posts: 117
Joined: Wed Jun 30, 2010 8:44 am
Location: Portugal
Contact:

[HELP!!!] Moving nodes to targeted positions + rotations

Post by jorgerosa »

Code: Select all

// Header:
#include <irrlicht.h>
using namespace irr;
 
// Initialize some vars:
bool PLAY_THIS_ANIMATION = true;
scene::ISceneNode* myNode[100];
 
 
 
/// PART 1/2 - The main animation function:
ISceneNode* moveThisNode(ISceneNode* node, vector3df FinalPos, vector3df FinalRot, f32 speed, f32 frameDeltaTime){
 
vector3df NowPos = node->getPosition(); // Get current node position
vector3df NowRot = node->getRotation(); // Get current node rotation
 
// core::vector3df ip = NowPos.getInterpolated(FinalPos, 0.001f); // Position distance (With a tolerance of 0.001f) (Old code line)
// core::vector3df ir = NowRot.getInterpolated(FinalRot, 0.001f); // Rotation distance (With a tolerance of 0.001f) (Old code line)
 
f32 tolerance = 0.001f;
bool onPosition = (core::equals(NowPos.X, FinalPos.X, tolerance) && core::equals(NowPos.Y, FinalPos.Y, tolerance) && core::equals(NowPos.Z, FinalPos.Z, tolerance));
bool onRotation = (core::equals(NowRot.X, FinalRot.X, tolerance) && core::equals(NowRot.Y, FinalRot.Y, tolerance) && core::equals(NowRot.Z, FinalRot.Z, tolerance));
 
// if(ip != FinalPos){ // Not yet on targeted position, so continue doing... (Old code line)
if(!onPosition){       // Not yet on targeted position, so continue doing...
if(NowPos.X<FinalPos.X){ NowPos.X += speed * frameDeltaTime; } else if(NowPos.X>FinalPos.X){ NowPos.X -= speed * frameDeltaTime; }; // X Axis 
if(NowPos.Y<FinalPos.Y){ NowPos.Y += speed * frameDeltaTime; } else if(NowPos.Y>FinalPos.Y){ NowPos.Y -= speed * frameDeltaTime; }; // Y Axis
if(NowPos.Z<FinalPos.Z){ NowPos.Z += speed * frameDeltaTime; } else if(NowPos.Z>FinalPos.Z){ NowPos.Z -= speed * frameDeltaTime; }; // Z Axis
// Aplly the new position step to the node:
node->setPosition(vector3df(NowPos));
};
 
// if(ir != FinalRot){ // Not yet on targeted rotation, so continue doing... (Old code line)
if(!onRotation){       // Not yet on targeted rotation, so continue doing... 
if(NowRot.X<FinalRot.X){ NowRot.X += speed * frameDeltaTime; } else if(NowRot.X>FinalRot.X){ NowRot.X -= speed * frameDeltaTime; }; // X Axis
if(NowRot.Y<FinalRot.Y){ NowRot.Y += speed * frameDeltaTime; } else if(NowRot.Y>FinalRot.Y){ NowRot.Y -= speed * frameDeltaTime; }; // Y Axis
if(NowRot.Z<FinalRot.Z){ NowRot.Z += speed * frameDeltaTime; } else if(NowRot.Z>FinalRot.Z){ NowRot.Z -= speed * frameDeltaTime; }; // Z Axis
// Aplly the new rotation step to the node:
node->setRotation(vector3df(NowRot));
};
 
// Targeted position and rotation achieved, so do...
// if(ip == FinalPos && ir == FinalRot){ cout << "Node is on targeted position and rotation!" << endl; }; // (Old code line)
if(onPosition && onRotation){ cout << "Node is on targeted position and rotation!" << endl; };
 
};
 
 
 
// Usual irrlicht stuf:
int main(int argc, char** argv){
 
// ... 
// myNode[0] = smgr->addMeshSceneNode(smgr->getMesh("model0.obj"));
// myNode[1] = smgr->addMeshSceneNode(smgr->getMesh("model1.obj"));
// myNode[2] = smgr->addMeshSceneNode(smgr->getMesh("model2.obj"));
// ... 
 
// Initialize for frame delta time:
u32 time_then = device->getTimer()->getTime();
 
while(device->run()){
 
            // Get frame delta time:
            const u32 time_now = device->getTimer()->getTime();
            const f32 frameDeltaTime = (f32)(time_now-time_then)/1000.f; // Time in seconds: /1000.f
            time_then = time_now;
 
            /// PART 2/2 - Animating some nodes:
            if(PLAY_THIS_ANIMATION){
            for(int i=0; i<10; ++i){
            // Function usage: Node, Final Position, Final Rotation, Speed, FrameDeltaTime
            moveThisNode(myNode[i], vector3df(10.0,19.0,10.0), vector3df(0.0,90.0,0.0), 2.0, frameDeltaTime);
            };
            }; 
 
};
};
 
(I commented a lot and aligned the above code, so I hope it could be easily readable as possible.)

NOTE: I created the above function, since "createFollowSplineAnimator()" never triggers "hasFinished()" to "true".
AND "createRotationAnimator()" creates a constant/continuous rotation. (So, never triggers "hasFinished()" to "true" too, of course).
Both animators can be added to the same node, they work just fine, but I can´t get the result that I intend to: Nodes that targets the final positions + final rotations and trigger something at the the end.
( Irrlicht animators reference: http://irrlicht.sourceforge.net/docu/cl ... nager.html )


So... This "universal" function intends to move and rotate nodes to a defined targeted position and rotation.
:arrow: Is this the right way to do this?
:arrow: If, yes... Can someone help to improve this function? Maybe "convert" all this to an animator (or edit the existing ones) to achive similar result? Any new ideas? Any "how-to" examples? etc, etc, etc...

The goal is:
A) Node far from target: More speed and more rotation steps
B) Node near the target: Less speed and less rotation steps
C) Return something as node hits the targeted position and rotation
D) Maybe (just maybe... I dont know) with a minimum speed and rotation factor: 1
(or any other value, just to avoid never reach target, and to avoid long time waiting, doesnt really need to be a perfect smooth animation, but a solid one (in my scratches here sometimes gets an endless loop, or never hits the target, funny rotations, lots of other issues... Well... you can imagine....).

.
Last edited by jorgerosa on Tue May 08, 2012 5:42 pm, edited 13 times in total.
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: [HELP!!!] Moving nodes to targeted positions + rotations

Post by smso »

There may be some gotchas in

Code: Select all

if(ip != FinalPos){ // Not yet on targeted position, so continue doing...
if(ir != FinalRot){ // Not yet on targeted rotation, so continue doing...
if(ip == FinalPos && ir == FinalRot)
 
The operators != and == of the class irr::core::vector3d<T> are expressed internally as:

Code: Select all

bool equals(const vector3d<T>& other, const T tolerance = (T)ROUNDING_ERROR_f32 ) const
It might be helpful if you use the "equals()" function and increase the tolerance.


You may also compared the elapsed time and the time taken to complete the action.

Regards
smso
jorgerosa
Competition winner
Posts: 117
Joined: Wed Jun 30, 2010 8:44 am
Location: Portugal
Contact:

Re: [HELP!!!] Moving nodes to targeted positions + rotations

Post by jorgerosa »

smso wrote:There may be some gotchas ...
Thanks for the tips. Code changes were applied in the first post. :)
Post Reply