[SOLVED] Problem with node orientation over a spheric world

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Xico
Posts: 30
Joined: Sun Jun 05, 2005 5:08 pm
Location: Buenos Aires, Argentina
Contact:

[SOLVED] Problem with node orientation over a spheric world

Post by Xico »

Hi, I'm making a little game, in wich the player walk over a little planet.
I use a function to build a rotation matrix to have the player sceneNode oriented according to the center of the planet. But... have a problem I can't solve. Here a image to describe it:

Image

The rotation matrix allways have the Z axis (the front of the node) facing the target. But in this case I need the downside of the node facing the target.
A rusty solution can be rotate in 3dmax the player model, and use his Y as Z, but is a ugly solution....

here the function:

Code: Select all

// the initial up direction of the node
vector3df up(0,1,0);
// the up direction during gameplay
vector3df curup(up);

void pointTarget(ISceneNode& node, ISceneNode& target)
{     
   vector3df targetdir=target.getPosition()-node.getPosition();   
   
   // build the rotation matrix
   vector3df z(targetdir);
   z.normalize();
   vector3df x( curup.crossProduct(z));
   x.normalize();
   vector3df y( z.crossProduct(x));
   y.normalize();
   
   core::matrix4 transform; 
     
   transform(0,0) = x.X;
   transform(0,1) = y.X;
   transform(0,2) = z.X;
   transform(0,3) = 0;
   
   transform(1,0) = x.Y;
   transform(1,1) = y.Y;
   transform(1,2) = z.Y;
   transform(1,3) = 0;
   
   transform(2,0) = x.Z;
   transform(2,1) = y.Z;
   transform(2,2) = z.Z;
   transform(2,3) = 0;
   
   transform(3,0) = 0;
   transform(3,1) = 0;
   transform(3,2) = 0;
   transform(3,3) = 1.0f;   
      
   vector3df rot=transform.getRotationDegrees();
   transform.transformVect(up,curup);
   curup.normalize();
   node.setRotation(rot);
} 
I've tryed a lot modifyng the order of the axis vectors, his crossproducts, etc... but I allways fail. Also tryed the buildCameraLookAtMatrixLH function without success.
Any help is very welcome. Thanks in advance.
Last edited by Xico on Mon Jul 11, 2005 5:56 pm, edited 2 times in total.
Thulsa Doom
Posts: 63
Joined: Thu Aug 05, 2004 9:40 am
Location: Germany

Post by Thulsa Doom »

Hi Xico,

One principle thing concerning geometry.
As Irrlicht uses LHS-Coord as default (the orientation of the CoordSystem in the image displays this), one has to be careful with the crossproduct.

In a RHS-CoordSystem the crossproduct writes:
Z = X x Y

But in a LHS-Coord the crossproduct changes sign:
Z = - X x Y = Y x X

Another point is the rotation.
Have u tried to rotate the node after loading it to the scene?
Why doesn't this work?
omaremad

Post by omaremad »

use a fly circle animator with the same radius as the planet
Xico
Posts: 30
Joined: Sun Jun 05, 2005 5:08 pm
Location: Buenos Aires, Argentina
Contact:

SOLVED

Post by Xico »

Thanks Thulsa for your advices. That help me to figure out how works the coord system.
I've managed to have it working now.

Code: Select all

// the initial forward direction of the node
vector3df fwd(0,0,1);
// the forward direction during gameplay
vector3df curfwd(fwd);


void pointTarget(ISceneNode& node, ISceneNode& target)
{     
   vector3df targetdir=target.getPosition()-node.getPosition();   
   
   // build the rotation matrix   
   targetdir.normalize();
   
   vector3df x(curfwd.crossProduct(targetdir));
   x.normalize();
   
   vector3df z( targetdir.crossProduct(x));
   z.normalize();
   vector3df y( z.crossProduct(x));
   y.normalize(); 
   
   
   core::matrix4 transform; 
     
   transform(0,0) = x.X;
   transform(0,1) = y.X;
   transform(0,2) = z.X;
   transform(0,3) = 0;
   
   transform(1,0) = x.Y;
   transform(1,1) = y.Y;
   transform(1,2) = z.Y;
   transform(1,3) = 0;
   
   transform(2,0) = x.Z;
   transform(2,1) = y.Z;
   transform(2,2) = z.Z;
   transform(2,3) = 0;
   
   transform(3,0) = 0;
   transform(3,1) = 0;
   transform(3,2) = 0;
   transform(3,3) = 1.0f;   
      
   vector3df rot=transform.getRotationDegrees();
   transform.transformVect(fwd,curfwd);
   curfwd.normalize();
   node.setRotation(rot);
} 
Here the image with the example working properly:
Image

I don't know too much about vectors, so this has been a trial and error thing. Anyway, hope it helps others with the same problem.

best
Xico
IainC
Posts: 27
Joined: Tue Feb 24, 2004 5:55 pm
Location: Aberystwyth, UK
Contact:

Post by IainC »

Wow - reminds me of a idea I had ages ago for an RTS set on a tiny little planet, but I gave up because movement on the surface beat me.

I had a nice perlin-based class for generating the planets, let me know if you'd like it and you can try and make a custom scene node out of it.

Image

Binary demo can be found here. There's no LOD though :(
www.coldcity.com|ninjastyle
Post Reply