Flight sim style camera.
I am trying to make a ship simulator and am running into a few problems when trying to hard attach my camera to the bridge of the ship. I have looked up some basic camera information in a few books that I have and also online. I have come to the conclusion that there must be multiple ways of doing this and I need the way that is not explained. The difference that I'm running into is when calculating rotations for yaw, pitch, and roll these texts have given me a way to manipulate the matrix based on these values, but only when detecting input from a device such as mouse, keyboard, or XBox controller. My situation is a bit different in that I have a steering wheel set up as my input. I'm getting the position of the wheel and passing that into a complex physics function which in turn calculates the actual yaw, pitch, and roll values for my ship. Then I use those values to create a rotation matrix via the D3DXMatrixRotationYawPitchRoll() function. So now I have the rotation matrix of the ship and the position is calculated elsewhere. I take this information and set the camera's LookAt, Up, and Right vectors to match the ship, then use this equation to calculate the camera's position according to the rotation matrix :
camera_position = (ship_position + (ship_right * camera_offset.x) + (ship_up * camera_offset.y) + (ship_at * camera_offset.z));
When I recalculate the view matrix like this :
//Keep camera's axes orthogonal to each other and of unit length.
D3DXVec3Normalize(&direction_vector, &direction_vector);
D3DXVec3Cross(&up_vector, &direction_vector, &right_vector);
D3DXVec3Normalize(&up_vector, &up_vector);
D3DXVec3Cross(&right_vector, &up_vector, &direction_vector);
D3DXVec3Normalize(&right_vector, &right_vector);
x = -D3DXVec3Dot(&position_vector, &right_vector);
y = -D3DXVec3Dot(&position_vector, &up_vector);
z = -D3DXVec3Dot(&position_vector, &direction_vector);
//Build the matrix
camera_view(0,0) = right_vector.x;
camera_view(1,0) = right_vector.y;
camera_view(2,0) = right_vector.z;
camera_view(3,0) = position_vector.x;
camera_view(0,1) = up_vector.x;
camera_view(1,1) = up_vector.y;
camera_view(2,1) = up_vector.z;
camera_view(3,1) = position_vector.y;
camera_view(0,2) = direction_vector.x;
camera_view(1,2) = direction_vector.y;
camera_view(2,2) = direction_vector.z;
camera_view(3,2) = position_vector.z;
camera_view(0,3) = 0.0f;
camera_view(1,3) = 0.0f;
camera_view(2,3) = 0.0f;
camera_view(3,3) = 1.0f;
//Set the world matrix to the camera
render_dev_ref->GetD3DDevice()->SetTransform(D3DTS_VIEW, &camera_view);
I get crazy information for the position coming out from the dot products, which essentially ends up with my camera pitching, rolling, and yawing properly, but it strafes on the x constantly. After a certain point the camera will then reach its max and warp to the other end, meet up with the ship, and then keep going. I've tried everything I can think of and now I'm wondering if this is a problem where I should be using quaternions. I don't know much but I read up a little about them saying that they alleviate running into a gimbal lock. Is that what I'm getting here? Can anyone help me? I'm very confused and I hope that my long winded post is an adequate description of my situation.
Thanks for any tips in advance! :)
-Jon
I finally got it working to specification. Apparently calling the D3DXMatrixYawPitchRoll function and then sticking the updated position into the matrix isn't good enough. I had to create a separate matrix for each of the yaw, pitch, roll, and position. Then multiply each one together into a Complete matrix. What the will give you is a hard attach camera causing the world to rotate and roll/pitch with the entity. However, i needed the world to stay flat while the entity rolled, so I had to redo the way I built the view matrix.
D3DXVECTOR3 WorldUp(0.0f, 1.0f, 0.0f);
D3DXVECTOR3 AtPos;
AtPos = position_vector + (direction_vector * 0.5f);
// Since this function takes in points for position and direction, we need
// to scale the direction vector a bit so we are looking in the correct direction.
D3DXMatrixLookAtLH(&camera_view, &position_vector, &AtPos, &WorldUp);
Instead of recalculating the matrix like I was before, all I needed to do was call D3DXMatrixLookAtLH. This does everything for you except for the fact that instead of vectors, it takes in a position point and a look at point. Therefore when we call this function, we have to scale our at vector (direction_vector) a bit so that we end up looking at that point and in the correct direction.
Hope this helps anyone. It's a bit specific, but there it is.
Jon
D3DXVECTOR3 WorldUp(0.0f, 1.0f, 0.0f);
D3DXVECTOR3 AtPos;
AtPos = position_vector + (direction_vector * 0.5f);
// Since this function takes in points for position and direction, we need
// to scale the direction vector a bit so we are looking in the correct direction.
D3DXMatrixLookAtLH(&camera_view, &position_vector, &AtPos, &WorldUp);
Instead of recalculating the matrix like I was before, all I needed to do was call D3DXMatrixLookAtLH. This does everything for you except for the fact that instead of vectors, it takes in a position point and a look at point. Therefore when we call this function, we have to scale our at vector (direction_vector) a bit so that we end up looking at that point and in the correct direction.
Hope this helps anyone. It's a bit specific, but there it is.
Jon
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement