Ok i do have those in my code Pitch Yaw Roll and so forth, i also have those linked to some keys like w-moves forward and s-backwards now q and e control the yaw left and right and t and g control the pitch up and down. When you use the kybrd to do this it works rotates around in a full 360 deg circle i have no problem with that but when i use the mouse to move you cant turn completely around and then the camera is not horizontally correct its like the roll is changing it.
Here is my camera.cpp i bet some of the coding is wrong...
[Source]#include "camera.h"Camera::Camera(){ _cameraType = AIRCRAFT; _pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f); _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f); _up = D3DXVECTOR3(0.0f, 1.0f, 0.0f); _look = D3DXVECTOR3(0.0f, 0.0f, 1.0f);}Camera::Camera(CameraType cameraType){ _cameraType = cameraType; _pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f); _right = D3DXVECTOR3(1.0f, 0.0f, 0.0f); _up = D3DXVECTOR3(0.0f, 1.0f, 0.0f); _look = D3DXVECTOR3(0.0f, 0.0f, 1.0f);}Camera::~Camera(){}void Camera::getPosition(D3DXVECTOR3* pos){ *pos = _pos;}void Camera::setPosition(D3DXVECTOR3* pos){ _pos = *pos;}void Camera::getRight(D3DXVECTOR3* right){ *right = _right;}void Camera::getUp(D3DXVECTOR3* up){ *up = _up;}void Camera::getLook(D3DXVECTOR3* look){ *look = _look;}void Camera::walk(float units){ // move only on xz plane for land object if( _cameraType == LANDOBJECT ) _pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units; if( _cameraType == AIRCRAFT ) _pos += _look * units;}void Camera::strafe(float units){ // move only on xz plane for land object if( _cameraType == LANDOBJECT ) _pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units; if( _cameraType == AIRCRAFT ) _pos += _right * units;}void Camera::fly(float units){ // move only on y-axis for land object if( _cameraType == LANDOBJECT ) _pos.y += units; if( _cameraType == AIRCRAFT ) _pos += _up * units;}void Camera::pitch(float angle){ D3DXMATRIX T; D3DXMatrixRotationAxis(&T, &_right, angle); // rotate _up and _look around _right vector D3DXVec3TransformCoord(&_up,&_up, &T); D3DXVec3TransformCoord(&_look,&_look, &T);}void Camera::yaw(float angle){ D3DXMATRIX T; // rotate around world y (0, 1, 0) always for land object if( _cameraType == LANDOBJECT ) D3DXMatrixRotationY(&T, angle); // rotate around own up vector for aircraft if( _cameraType == AIRCRAFT ) D3DXMatrixRotationAxis(&T, &_up, angle); // rotate _right and _look around _up or y-axis D3DXVec3TransformCoord(&_right,&_right, &T); D3DXVec3TransformCoord(&_look,&_look, &T);}void Camera::roll(float angle){ // only roll for aircraft type if( _cameraType == AIRCRAFT ) { D3DXMATRIX T; D3DXMatrixRotationAxis(&T, &_look, angle); // rotate _up and _right around _look vector D3DXVec3TransformCoord(&_right,&_right, &T); D3DXVec3TransformCoord(&_up,&_up, &T); }}void Camera::getViewMatrix(D3DXMATRIX* V){ // Keep camera's axes orthogonal to eachother D3DXVec3Normalize(&_look, &_look); D3DXVec3Cross(&_up, &_look, &_right); D3DXVec3Normalize(&_up, &_up); D3DXVec3Cross(&_right, &_up, &_look); D3DXVec3Normalize(&_right, &_right); // Build the view matrix: float x = -D3DXVec3Dot(&_right, &_pos); float y = -D3DXVec3Dot(&_up, &_pos); float z = -D3DXVec3Dot(&_look, &_pos); (*V)(0,0) = _right.x;(*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f; (*V)(1,0) = _right.y;(*V)(1, 1) = _up.y;(*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f; (*V)(2,0) = _right.z;(*V)(2, 1) = _up.z;(*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f; (*V)(3,0) = x;(*V)(3, 1) = y; (*V)(3, 2) = z; (*V)(3, 3) = 1.0f; }void Camera::setCameraType(CameraType cameraType){ _cameraType = cameraType;}[/Source]
[/source]
[Source]void Camera::RotateCamera(float AngleDir, float xSpeed, float ySpeed, float zSpeed){ float xNewLookDirection = 0, yNewLookDirection = 0, zNewLookDirection = 0; float xLookDirection = 0, yLookDirection = 0, zLookDirection = 0; float CosineAngle = 0, SineAngle = 0; // First we will need to calculate the cos and sine of our angle. I creaetd two macros to // do this in the CCamera.h header file called GET_COS and GET_SINE. To use the macros // we just send in the variable we ant to store the results and the angle we need to // calculate. GET_COS(CosineAngle, AngleDir); GET_SINE(SineAngle, AngleDir); // Next get the look direction (where we are looking) just like in the move camera function. xLookDirection = _look.x - _pos.x; yLookDirection = _look.y - _pos.y; zLookDirection = _look.z - _pos.z; // Normalize the direction. float dp = 1 /(float)sqrt(xLookDirection * xLookDirection + yLookDirection * yLookDirection + zLookDirection * zLookDirection); xLookDirection *= dp; yLookDirection *= dp; zLookDirection *= dp; // Calculate the new X position. xNewLookDirection = (CosineAngle + (1 - CosineAngle) * xSpeed) * xLookDirection; xNewLookDirection += ((1 - CosineAngle) * xSpeed * ySpeed - zSpeed * SineAngle)* yLookDirection; xNewLookDirection += ((1 - CosineAngle) * xSpeed * zSpeed + ySpeed * SineAngle) * zLookDirection; // Calculate the new Y position. yNewLookDirection = ((1 - CosineAngle) * xSpeed * ySpeed + zSpeed * SineAngle) * xLookDirection; yNewLookDirection += (CosineAngle + (1 - CosineAngle) * ySpeed) * yLookDirection; yNewLookDirection += ((1 - CosineAngle) * ySpeed * zSpeed - xSpeed * SineAngle) * zLookDirection; // Calculate the new Z position. zNewLookDirection = ((1 - CosineAngle) * xSpeed * zSpeed - ySpeed * SineAngle) * xLookDirection; zNewLookDirection += ((1 - CosineAngle) * ySpeed * zSpeed + xSpeed * SineAngle) * yLookDirection; zNewLookDirection += (CosineAngle + (1 - CosineAngle) * zSpeed) * zLookDirection; // Last we add the new rotations to the old view to correctly rotate the camera. _up.x = _pos.x + xNewLookDirection; _up.y = _pos.y + yNewLookDirection; _up.z = _pos.z + zNewLookDirection; [/Source]
[/source]
[Source]void Camera::RotateByMouse(int mousePosX, int mousePosY, int midX, int midY){ float yDirection = 0.0f; // Direction angle. float xDirection = 0.0f; // Direction angle. float yRotation = 0.0f; // Rotation angle. // If the mouseX and mouseY are at the middle of the screen then we can't rotate the view. if((mousePosX == midX) && (mousePosY == midY)) return; // Next we get the direction of each axis. We divide by 1000 to get a smaller value back. yDirection = (float)((midX - mousePosX)) / 1000.0f; //yRotation = (float)((midY - mousePosY)) / 500.0f; //xDirection = (float)((midY - mousePosY)) / 1000.0f; // We use curentRotX to help use keep the camera from rotating too far in either direction. _look.x -= yDirection; //_look.y -= xDirection;/* // Stop the camera from going to high... if(_look.x > 1.0f) { _look.x = 1.0f; return; } // Stop the camera from going to low... if(_look.x < -1.0f) { _look.x = -1.0f; return; */ // Next we get the axis which is a perpendicular vector of the view direction and up values. // We use the cross product of that to get the axis then we normalize it. float xAxis = 0, yAxis = 0, zAxis = 0; float xDir = 0, yDir = 0, zDir = 0; // Get the Direction of the view. xDir = _pos.x - _look.x; yDir = _pos.y - _look.y; zDir = _pos.z - _look.z; // Get the cross product of the direction and the up. xAxis = (yDir * _up.z) - (zDir * _up.y); yAxis = (zDir * _up.x) - (xDir * _up.z); zAxis = (xDir * _up.y) - (yDir * _up.x); // Normalize it. float len = 1 /(float)sqrt(xAxis * xAxis + yAxis * yAxis + zAxis * zAxis); xAxis *= len; yAxis *= len; zAxis *= len; // Rotate the camera. //RotateCamera(-xDirection, xAxis, yAxis, zAxis); RotateCamera(-yDirection, 0, 0, 0);}[/Source]
[/source]