1
\$\begingroup\$

I have a simple camera class working in directx 11 allowing moving forward and rotating left and right. I'm trying to implement strafing into it but having some problems.

The strafing works when there's no camera rotation, so when the camera starts at 0, 0, 0. But after rotating the camera in either direction it seems to strafe at an angle or inverted or just some odd stuff.

Here is a video uploaded to Dropbox showing this behavior. https://dl.dropboxusercontent.com/u/2873587/IncorrectStrafing.mp4

And here is my camera class. I have a hunch that it's related to the calculation for camera position. I tried various different calculations in strafe and they all seem to follow the same pattern and same behavior. Also the m_camera_rotation represents the Y rotation, as pitching isn't implemented yet.

#include "camera.h"


camera::camera(float x, float y, float z, float initial_rotation) {
m_x = x;
m_y = y;
m_z = z;
m_camera_rotation = initial_rotation;

updateDXZ();
}


camera::~camera(void)
{
}

void camera::updateDXZ() {
m_dx = sin(m_camera_rotation * (XM_PI/180.0));
m_dz = cos(m_camera_rotation * (XM_PI/180.0));
}

void camera::Rotate(float amount) {
m_camera_rotation += amount;

updateDXZ();
}

void camera::Forward(float step) {
m_x += step * m_dx;
m_z += step * m_dz;
}

void camera::strafe(float amount) {
float yaw = (XM_PI/180.0) * m_camera_rotation;

m_x += cosf( yaw ) * amount;
m_z += sinf( yaw ) * amount;
}

XMMATRIX camera::getViewMatrix() {
updatePosition();

return XMMatrixLookAtLH(m_position, m_lookat, m_up);
}

void camera::updatePosition() {
m_position = XMVectorSet(m_x, m_y, m_z, 0.0);
m_lookat = XMVectorSet(m_x + m_dx, m_y, m_z + m_dz, 0.0);
m_up = XMVectorSet(0.0, 1.0, 0.0, 0.0);
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

What I do in my camera class is that I always store the forward and up vector and then use cross product in every update to calculate the right vector. In other words you need at least to store/calculate your right vector in order to be able to correctly determine the direction that you should strafe in. In your case you can do the following:

forward = normalize(m_lookat - m_position);
right   = cross( forward, m_up );

And the you use right for moving the camera:

m_position += (right * moveOffset ); // make sure right is normalized, moveOffset is a scalar not a vector.
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thank you so so much, this did the trick. I wasn't storing the right or forward positions and now it makes perfect sense that I'd need them to get the cross product for 90 degrees. I've updated my class and it works 100%. Many thanks. \$\endgroup\$ Commented Oct 21, 2013 at 10:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .