2014-10-07 3 views
0

GLUT 및 OpenGL을 사용하여 FPS 스타일 카메라를 만들려고합니다. 나는이 특별한 튜토리얼 http://www.gamedev.net/page/resources/_/technical/math-and-physics/a-simple-quaternion-based-camera-r1997을 따라 갔다. 내가 벡터 곱은 빼고해야 기능을 정상화 만든Quaternion FPS 카메라

void RotateCamera(double Angle, double x, double y, double z) 
{ 
    //quaternions in the form of w,x,y,z 
    quaternion temp(cos(Angle/2), x*sin(Angle/2), y * sin(Angle/2),z * sin(Angle/2)); 
    quaternion quat_view(0, view.x, view.y, view.z); 
    quaternion result = operator*(operator*(temp, quat_view), temp.conjugate()); 
    view = result.vector(); 
} 


void SetViewByMouse(int MouseX, int MouseY) 
{ 

    // the middle of the screen in the x direction 
    int MiddleX = G308_WIN_WIDTH/2; 

    // the middle of the screen in the y direction 
    int MiddleY = G308_WIN_HEIGHT/2; 

    // vector that describes mouseposition - center 
    G308_Point mouse_direction; 
    mouse_direction.x = 0.0f; 
    mouse_direction.y = 0.0f; 
    mouse_direction.z = 0.0f; 

    // static variable to store the rotation about the x-axis, since 
    // we want to limit how far up or down we can look. 
    // We don't need to cap the rotation about the y-axis as we 
    // want to be able to turn around 360 degrees 
    static double CurrentRotationX = 0.0; 

    // The maximum angle we can look up or down, in radians 
    double maxAngle = 1; 


    // if the mouse hasn't moved, return without doing 
    // anything to our view 
    if((MouseX == MiddleX) && (MouseY == MiddleY)) 
    return; 

    // otherwise move the mouse back to the middle of the screen 
    glutWarpPointer(MiddleX, MiddleY); 

    // get the distance and direction the mouse moved in x (in 
    // pixels). We can't use the actual number of pixels in radians, 
    // as only six pixels would cause a full 360 degree rotation. 
    // So we use a mousesensitivity variable that can be changed to 
    // vary how many radians we want to turn in the x-direction for 
    // a given mouse movement distance 

    // We have to remember that positive rotation is counter-clockwise. 
    // Moving the mouse down is a negative rotation about the x axis 
    // Moving the mouse right is a negative rotation about the y axis 
    mouse_direction.x = float((MiddleX - MouseX)/mouse_sensitivity); 
    mouse_direction.y = float((MiddleY - MouseY)/mouse_sensitivity); 

    CurrentRotationX += mouse_direction.y; 

    // We don't want to rotate up more than one radian, so we cap it. 
    if(CurrentRotationX > 1) 
    { 
    CurrentRotationX = 1; 
    return; 
    } 
    // We don't want to rotate down more than one radian, so we cap it. 
    if(CurrentRotationX < -1) 
    { 
    CurrentRotationX = -1; 
    return; 
    } 
    else 
    { 
    // get the axis to rotate around the x-axis. 
    G308_Point Axis = crossProduct(subtract(view,position), up); 
    // To be able to use the quaternion conjugate, the axis to 
    // rotate around must be normalized. 
    Axis = normalise(Axis); 

    // Rotate around the y axis 
    RotateCamera(mouse_direction.y, Axis.x, Axis.y, Axis.z); 
    // Rotate around the x axis 
    RotateCamera(mouse_direction.x, 0, 1, 0); 
    } 

    glutPostRedisplay(); 
} 

: 저자의 코드에 대한 몇 가지 작은 변화와

(나는 약간 다르게 기능을 처리하는 다른 사원 수 클래스가) 여기 내 코드입니다 잘 작동합니다.

프로그램을 실행시 문제

, 그것은 예상대로 장면을 표시하지만 마우스를 이동할 때, 그냥 바로 검은 간다. 미안하지만 그다지 도움이된다면 마우스 감도를 0.1로 설정했습니다. 이 당신이 찾고 있지만 내 프로젝트

그것은 내가 그것을 사용하고 프로젝트의 맥락에서 작동 중 하나에서 몇 가지 조각을 보여주지하지만 일부 오류가 기었다가있을 수 있습니다 무엇 인 경우

+0

을 추출 할 때에 꽤 특히 FPS, 당신은 그것을 해결하기 위해 시도하고있는 무슨 문제 것은보기 벡터를 수행하고, 최대 벡터 수없는, 사원 수 카메라의 시점을 이해 적이 없어요 두 개의 교차 곱으로 행렬을 구성 할 수 있습니까? (그런 것이 없기 때문에 "짐벌 잠금"이라고 말하지 말아라. 쿼터니언은 문제를 해결하지 못한다.) – Damon

+0

때로는 사람들이 쿼터니언을 광고 할 때 깜짝 놀랐습니다. 축 각도가 실제로 반짝이는데 ... –

+0

데이먼, 개인적으로 저는 프로그램의 다른 모든 회전이 그런 식으로 표현 될 때 추론하기가 더 쉽기 때문에 개인적으로 사용합니다. – lijat

답변

0

확실하지 않음 나는 조각

// a function to build a quaternion from axis angle 
inline Quat rotationAroundAxis(double r,Vec3 a){ 
    a=normalize(a); 
    a*=sin(r/2); 
    return Quat(a(0),a(1),a(2),cos(r/2)); 
} 

// read the mouse movement, the important part is to get int dx,dy,dz somehow 
int mx,my,mz; 
glfwGetMousePos(&mx,&my); 
mz=glfwGetMouseWheel(); 
int dmx=mx-oldMx; 
int dmy=my-oldMy; 
int dmz=mz-oldMz; 
oldMx=mx; 
oldMy=my; 
oldMz=mz; 

// get the current rotation 
Quat r=cameraTransform()->getRotation(); 
//create a vector that encodes these 
float sr=time_since_last_frame*100.0f;//sensitivity constant 
Vec3 rv(-dmy*0.001*sr,-dmx*0.001*sr,dmz*0.1); 
//rotate around the axis formed by the vector -rv with 
//the magnitude of the vectors normal norm(rv) 
Quat rot=normalize(rotationAroundAxis(norm(rv),-rv)*r); 
//save the new rotation and update rotation matrix 
cameraTransform()->setRotation(rot); 

inline Matrix4x4 Transform::setRotation(Quat r){ 
    rotationQuat=r;//save rotation so we can get it later 
    //convert to a rotation matrix and store it 
    double x=r.i,y=r.j,z=r.k,w=r.r; 
    rotation=matrix(1-2*y*y-2*z*z,2*x*y-2*z*w,2*x*z+2*y*w,0, 
        2*x*y+2*z*w,1-2*x*x-2*z*z,2*y*z-2*x*w,0, 
        2*x*z-2*y*w,2*y*z+2*x*w,1-2*x*x-2*y*y,0, 
        0,0,0,1); 
} 

// the rotation is later used to compute the transform of the camera to 
//its position in the scene 
transform=scale*rotation*translate; 

// invert it 
worldToEye=transform.inverse(); 

//setup rendering 
glMatrixMode(GL_MODELVIEW); 
glPushMatrix(); 
glLoadIdentity(); 
glMultMatrixf((float*)&worldToEye); 


// DRAW all objects here 
관련 문제