Trying to create a FPS-style camera so I can "move around" a loaded model

I have a VS 2022 solution here:

ScottTunstall/Monogame3DRotatingCamera: A camera revolving around a textured cube. (github.com)

It’s based on the tutorial here:
Monogame Tutorial: Beginning 3D Programming – GameFromScratch.com

It works fine.

What I’d like to do is change this so:

  1. I can move around the loaded 3D Model using WSAD keys and mouse to “look up/down”, like in an FPS.
  2. I would then like to add more models to the “world”, that I could “drive” amongst, kind of like the video game Battlezone.

I have looked for camera and model code here, but had no success. I thought about rotating the camera on its own axis, and the “look at” target using CreateFromAxisAngle() but didn’t have any lucky with that.

I’m not a math expert and did not study 3D programming at Uni, but if you tell me what code I need to add, I will try add it myself.

Note: this is only for personal research purposes. I am not creating a game.
When I crack this, I will upload to Github so others can use it to learn.

If you want a camera that orbits around some target, something like this should work:

Vector3 camDir = Matrix.CreateFromYawPitchRoll(yaw, pitch, 0).Forward;
Vector3 camPos = camTarget - camDir * camDistance;
Matrix viewMatrix = Matrix.CreateLookAt(camPos, camTarget, Vector3.Up);

Hi Markus, thanks for replying.

I’m looking for a free-moving camera that lets me roam around the 3D models I have positioned in 3D space using WSAD.

My current line of thinking is to move forward is easy. I just subtract the camera position vector3 from the camera target Vector3, then normalize the vector and add the result to the camera position.

What I don’t know for sure yet is how to rotate the camera clockwise or anticlockwise. I’m thinking I could create a matrix from the current camera position, then multiply that by Matrix.CreateRotationY(angle) and store result back to camera position vector3. I’d repeat the calculation for the camera target.

Would this work?

That’s what he solved for you with those three lines of code. Just change Yaw and Pitch when you want to rotate and that’s it.

The code I showed you will orbit at some distance around a target, but you can easily adjust it to look around only. Instead of moving the camera back, you move the target forward, so the middle line becomes:

Vector3 camTarget = camPos + camDir;

Right, I was wondering if there would be a way without storing angles (yaw, pitch) in variables but if this is the best way then so be it. I’ll give it a try.

Thanks and happy new year!

Scott

There is other ways. You could store the camera matrix and incrementally rotate it every frame.
But why would you? As long as storing angles works for what you need, it should be the simpler solution.

I have updated the code to use CreateYawPitchRoll.

Result is here: ScottTunstall/Monogame3DRotatingCamera: A camera revolving around a textured cube. (github.com)

New code is as follows:

_camAngle = 0f;
_camPosition = new Vector3(0f, 0f, -5);
_camTarget = _camPosition + Matrix.CreateFromYawPitchRoll(_camAngle, 0, 0).Forward * 10;
_viewMatrix = Matrix.CreateLookAt(_camPosition, _camTarget, Vector3.Up);

I can now move amongst the cubes as desired. Thanks for your help.

One thing I find weird is that incrementing the _camAngle (radians) makes the view rotate anticlockwise, instead of clockwise which I expected. Is this to do with OpenGL’s “handed-ness” ?