Player movement relative to the camera's rotation

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
Hsyenoh05
Posts: 5
Joined: Tue Oct 18, 2022 12:29 pm

Player movement relative to the camera's rotation

Post by Hsyenoh05 »

I added a scene node for the Player and made him move whenever I pressed any of the WASD keys, and it works, except when I move the Player's camera, I tried doing some math-related stuff in order for it to work, But I couldn't get any closer to the solution, I'd appreciate your feedback on this :)
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Player movement relative to the camera's rotation

Post by CuteAlien »

If you are lucky ISceneNodeAnimatorCameraFPS already does what you want.

Otherwise the easiest way is to work with matrices. For this case you can think of them basically as coordinate systems.
Start by defining one direction as "forward" - like 0,0,1 for example (if you have a model - use the direction where the nose is). Think of this as your base "step" the player can take. It's the one you add to your position each frame. Multiply it by some value and you get faster/slower (and often you multiply it by time to have fps-independent movement).

Now figure out the coordinate system (matrix) where forward is the same direction as your camera.
Luckily Irrlicht already can calculate those for you - every ISceneNode (including the ICameraSceneNode) has two functions, getRelativeTransformation and getAbsoluteTransformation, which return those matrices.
For cameras you have to set bindTargetAndRotation(true) to make this work.
Use getRelativeTransformation (slightly easier to use, absolute transformation is only needed if you have parent/child relations between scenenodes). Then transform your "forward" vector to point forward in that coordinate system. matrix4::rotateVect will do that (it also would scale, but you don't need that for cameras). Add the result to your coordinates and you'll move forward in the camera coordinate system.

Quick example, super untested, just giving the idea:

Code: Select all

camera->bindTargetAndRotation(true); // only call this once.

// That stuff is called every frame
irr::core::vector3df step(0,0,1);
camera->render(); // force camera to update it's matrices in Irrlicht 1.8 - Irrlicht trunk has updateMatrices() for that
irr::core::matrix4 camMatrix = camera->getRelativeTransformation();
camMatrix.rotateVect(step);

youPlayerNode->setPosition( youPlayerNode->getPosition() + step * timePerFrame );
As always there's several other ways to approach this. For example you can put that code into an animator. Then you don't need the camera->render() as cameras are updated before nodes (if you forget this you simply get last frame of camera - which can also be fine sometimes).

Or another solution is to make your node a child of the camerascenenode. Then as long as bindTargetAndRotation(true) is set moving is automatically in the camera coordinate system. Thought the nice part about working with matrices yourself is that it works the same for every other node, not just those from cameras (so you can for example follow behind someone etc).

I often prefer moving the player instead of the camera. And let the camera follow.
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
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Player movement relative to the camera's rotation

Post by Mel »

We could use a Third Person Camera animator :)
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Post Reply