Rotating Mesh Based on Camera Position

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.
GuyOnAWallaby
Posts: 15
Joined: Sat Oct 11, 2014 6:13 am

Rotating Mesh Based on Camera Position

Post by GuyOnAWallaby »

I am trying to make it so that when I rotate my camera, my player mesh is rotated in the direction of the camera. The camera seems to rotate sometimes, but not the player mesh.

Code: Select all

 
void Player::move(int moveX, int moveZ){
 
   cam->GetIrrCamNode()->updateAbsolutePosition();
 
   core::vector3df tempVector = cam->GetIrrCamNode()->getAbsoluteTransformation().getRotationDegrees();
 
   playerMesh->setRotation(core::vector3df(0,tempVector.Y + 180 ,0));
   playerMesh->updateAbsolutePosition();
 
  /* playerMesh->setPosition(core::vector3df(getX() + moveX, getY(), getZ() + moveZ));
   X += moveX;
   Z += moveZ;*/
}
 
Any help would be appreciated.
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: Rotating Mesh Based on Camera Position

Post by Seven »

,
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Rotating Mesh Based on Camera Position

Post by CuteAlien »

Do you maybe overwrite the player rotation in another place?
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
GuyOnAWallaby
Posts: 15
Joined: Sat Oct 11, 2014 6:13 am

Re: Rotating Mesh Based on Camera Position

Post by GuyOnAWallaby »

No the only thing really happening right now is the camera and the player, there is not really any other objects or nodes and that one move function is basically the only thing in the player class. I set rotation of the mesh when I initiated the player, but that's about it. And also, you said to do cam->updateAbsoluteTransformation() before using cam->getAbsoluteTransformation(), but there is no updateAbsoluteTransformation function, only thing I could find that would be like that was onAnimate() and I tried that but nothing.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Rotating Mesh Based on Camera Position

Post by CuteAlien »

Right, it's called updateAbsolutePosition (bad name, it really updates the whole transformation).

But thinking some more about it ... something is not making sense here. We're talking about a 3rd person camera, right? So the camera is always behind the mesh - except if you rotate it away from it. Assuming you based it on my code ... the idea there is that the camera is following the node by default. You can rotate around the target with the rotate functions if you want (like you can in RPG's), but unless you do that it should already stay behind the mesh always.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
GuyOnAWallaby
Posts: 15
Joined: Sat Oct 11, 2014 6:13 am

Re: Rotating Mesh Based on Camera Position

Post by GuyOnAWallaby »

Yeah I see what you mean, but what I was trying to do was for example; if I rotated the camera so that it is looking at the front of the player, and then move forward, the player would turn around and move in the direction of the camera(which would have been behind the player). Hope that makes sense.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Rotating Mesh Based on Camera Position

Post by CuteAlien »

In that case the code above doesn't look that wrong to me. But always hard to figure out bugs without having the full code to play around with it.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
GuyOnAWallaby
Posts: 15
Joined: Sat Oct 11, 2014 6:13 am

Re: Rotating Mesh Based on Camera Position

Post by GuyOnAWallaby »

I have been messing around with this code trying to get it to work right, and it seems that when I rotate the player and move him, he always moves in the same direction. So it seems like the camera's target vector doesn't change. Unless I am doing something awfully wrong, it should work correctly ( however it's not).

Code: Select all

 
void Player::strafeLeft(){
 
    cam->GetIrrCamNode()->updateAbsolutePosition();
 
    core::vector3df tempVector = cam->GetIrrCamNode()->getAbsoluteTransformation().getRotationDegrees();
 
    tempVector.rotateXZBy(-90 , core::vector3df(X,Y,Z));
    tempVector = tempVector.normalize();
 
    playerMesh->setPosition(core::vector3df(X + (tempVector.X * 2) , Y, Z + (tempVector.Z * 2)));
    X += tempVector.X * 2;
    Z += tempVector.Z * 2;
}
 
void Player::strafeRight(){
 
    cam->GetIrrCamNode()->updateAbsolutePosition();
 
    core::vector3df tempVector = cam->GetIrrCamNode()->getAbsoluteTransformation().getRotationDegrees();
 
    tempVector.rotateXZBy(90 , core::vector3df(X,Y,Z));
    tempVector = tempVector.normalize();
 
    playerMesh->setPosition(core::vector3df(X + (tempVector.X * 2) , Y, Z + (tempVector.Z * 2)));
    X += tempVector.X * 2;
    Z += tempVector.Z * 2;
}
 
void Player::moveForward(){
 
   cam->GetIrrCamNode()->updateAbsolutePosition();
 
   core::vector3df tempVector = cam->GetIrrCamNode()->getAbsoluteTransformation().getRotationDegrees();
   tempVector = tempVector.normalize();
 
   playerMesh->setPosition(core::vector3df(X + (tempVector.X * 2) , Y, Z + (tempVector.Z * 2)));
   X += tempVector.X / 10;
   Z += tempVector.Z / 10;
}
 
void Player::moveBack(){
 
    cam->GetIrrCamNode()->updateAbsolutePosition();
 
   core::vector3df tempVector = cam->GetIrrCamNode()->getAbsoluteTransformation().getRotationDegrees();
   tempVector = tempVector.normalize();
   tempVector = tempVector.invert();
 
   playerMesh->setPosition(core::vector3df(X + (tempVector.X * 2) , Y, Z + (tempVector.Z * 2)));
   X += tempVector.X * 2;
   Z += tempVector.Z * 2;
}
 

And here is the code that handles input

Code: Select all

 if( receiver->IsKeyDown(KEY_KEY_W) )
            currentPlayer.moveForward();
        if( receiver->IsKeyDown(KEY_KEY_S) )
            currentPlayer.moveBack();
        if( receiver->IsKeyDown(KEY_KEY_A) )
            currentPlayer.strafeLeft();
        if( receiver->IsKeyDown(KEY_KEY_D) )
            currentPlayer.strafeRight();
    if ( receiver->IsKeyDown(KEY_LEFT) ){
            currentPlayer.rotate(-1);
    }
    else if ( receiver->IsKeyDown(KEY_RIGHT) ){
            currentPlayer.rotate(1);
    }
    else
        myCam.RotateHorizontal(.0);
    if ( receiver->IsKeyDown(KEY_UP) )
        myCam.RotateVertical(-.1);
    else if ( receiver->IsKeyDown(KEY_DOWN) )
        myCam.RotateVertical(.1);
    else
        myCam.RotateVertical(.0);
    if ( receiver->IsKeyDown(KEY_KEY_X) )
        myCam.ZoomIn();
    else if ( receiver->IsKeyDown(KEY_KEY_Z) )
        myCam.ZoomOut();
    myCam.Update();
 
Also, when moving forward the player will move not in the right direction, but will move until it gets to a certain spot then won't move any further. So I can this means that the camera vector never updates? By the way I ditched the original idea and just made it so that when you rotate the camera, it rotates the player as well. This post is trying to fix movement based on the cameras position vector.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Rotating Mesh Based on Camera Position

Post by CuteAlien »

You are mixing up directions and angles. getRotationDegrees returrns angles around an axis. To say you rotate an angle around some point makes no sense. You cannot rotate an angle itself, you rotate by an angle. The angle is a measurement of a rotation. I hope you get what I mean.

Doing stuff like movement and rotation is usually easier with matrices. Get the transformation matrix - give it your original direction, something like (0,0,1) (or whereever the front of your player is originally) and transform that vector by the matrix (Irrlicht matrix has functions for that already). Then you get a direction vector in the current direction of your node. Flipping it 90° can be done by ignoring y and going from (x,y,z) to (-z,y,x) or (z,y,-x).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
GuyOnAWallaby
Posts: 15
Joined: Sat Oct 11, 2014 6:13 am

Re: Rotating Mesh Based on Camera Position

Post by GuyOnAWallaby »

Alright thanks I got it working, there was some weird movement when I rotated camera, but I'll deal with that later I guess.
GuyOnAWallaby
Posts: 15
Joined: Sat Oct 11, 2014 6:13 am

Re: Rotating Mesh Based on Camera Position

Post by GuyOnAWallaby »

Alright, I am trying to fix the camera, because right now, when I rotate the camera the player does not move correctly. Here's the code.

Code: Select all

void Player::moveForward(){
 
   cam->GetIrrCamNode()->updateAbsolutePosition();
 
   int myX = getX();
   int myY = getY();
   int myZ = getZ();
   core::CMatrix4<float> tempMat = cam->GetIrrCamNode()->getAbsoluteTransformation();
   core::vector3df tempVector = core::vector3df(myX,myY,myZ);
   tempMat.transformVect(tempVector);
    tempVector.invert();
   tempVector.normalize();
 
   int tempX = tempVector.X * 2;
   int tempZ = tempVector.Z * 2;
   playerMesh->setPosition(core::vector3df(myX + tempX , myY, myZ + tempZ));
   setX(myX + tempX);
   setZ(myZ + tempZ);
}
 
void Player::moveBack(){
 
   cam->GetIrrCamNode()->updateAbsolutePosition();
 
   int myX = getX();
   int myY = getY();
   int myZ = getZ();
   core::CMatrix4<float> tempMat = cam->GetIrrCamNode()->getAbsoluteTransformation();
   core::vector3df tempVector = core::vector3df(myX,myY,myZ);
   tempMat.transformVect(tempVector);
   tempVector = tempVector.normalize();
 
   int tempX = tempVector.X * 2;
   int tempZ = tempVector.Z * 2;
   playerMesh->setPosition(core::vector3df(myX + tempX , myY, myZ + tempZ));
   setX(myX + tempX);
   setZ(myZ + tempZ);
}
 
void Player::strafeLeft(){
 
    cam->GetIrrCamNode()->updateAbsolutePosition();
    int myX = getX();
    int myY = getY();
    int myZ = getZ();
    core::CMatrix4<float> tempMat = cam->GetIrrCamNode()->getAbsoluteTransformation();
    core::vector3df tempVector = core::vector3df(myX,myY,myZ);
    tempMat.transformVect(tempVector);
 
    tempVector.rotateXZBy(-90 , core::vector3df(myX,myY,myZ));
    tempVector = tempVector.normalize();
 
    int tempX = tempVector.X * 2;
    int tempZ = tempVector.Z * 2;
    playerMesh->setPosition(core::vector3df(myX + tempX , myY, myZ + tempZ));
    setX(myX + tempX);
    setZ(myZ + tempZ);
}
 
void Player::strafeRight(){
 
    cam->GetIrrCamNode()->updateAbsolutePosition();
    int myX = getX();
    int myY = getY();
    int myZ = getZ();
    core::CMatrix4<float> tempMat = cam->GetIrrCamNode()->getAbsoluteTransformation();
    core::vector3df tempVector = core::vector3df(myX,myY,myZ);
    tempMat.transformVect(tempVector);
 
    tempVector.rotateXZBy(90 , core::vector3df(myX,myY,myZ));
    tempVector = tempVector.normalize();
 
    int tempX = tempVector.X * 2;
    int tempZ = tempVector.Z * 2;
    playerMesh->setPosition(core::vector3df(myX + tempX , myY, myZ + tempZ));
    setX(myX + tempX);
    setZ(myZ + tempZ);
}
 
 
So my questions, which I think is why the movement is all off: Shouldn't I be getting the absolute transformation of the camera's target instead of the targets location?
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Rotating Mesh Based on Camera Position

Post by mongoose7 »

Is this your problem: When the camera rotates, the player mesh should rotate around the camera so that it is in the same place relative to the camera? If this is the case, you should translate the player to the camera position , apply the camera rotation, and translate the player back to the new position. This is a bit hard to think about, so how about this. Parent the player to the camera, so the player rotates about the camera, then make player movements by adjusting his position directly.
GuyOnAWallaby
Posts: 15
Joined: Sat Oct 11, 2014 6:13 am

Re: Rotating Mesh Based on Camera Position

Post by GuyOnAWallaby »

I don't think that is my problem. Right now, when I rotate it rotates the player mesh, and the camera automatically rotates so I believe the camera is already linked to the player.

Here is the rotation code

Code: Select all

        
if ( receiver->IsKeyDown(KEY_LEFT) ){
            currentPlayer.rotate(-1);
}
else if ( receiver->IsKeyDown(KEY_RIGHT) ){
          currentPlayer.rotate(1);
}
 
 
void Player::rotate(int rot){
    rotation += rot;
   playerMesh->setRotation(core::vector3df(0,rotation,0));
}
 
This rotation might be the problem but I don't know. Just tried setting the cameras parent to the player node but it didn't help.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Rotating Mesh Based on Camera Position

Post by mongoose7 »

So, what is the behaviour you want. Try to break it down into simple steps.
GuyOnAWallaby
Posts: 15
Joined: Sat Oct 11, 2014 6:13 am

Re: Rotating Mesh Based on Camera Position

Post by GuyOnAWallaby »

Well right now it is how I want it, but the movement is weird. So pressing 'w' or 's' will move back or forwards respectively, and 'a' or 'd' will strafe the character left or right. Then rotating the camera will also rotate the character the same direction. But when I move the player after I rotate it does not move in the exact direction it should. For example, after rotating the camera and trying to move forward, sometimes it will move slightly diagonally forward, and then other times it will stop moving forward after a while.
Post Reply