Flight sim style camera.

Started by
0 comments, last by jonmiller 16 years, 2 months ago
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
Advertisement
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

This topic is closed to new replies.

Advertisement