سؤال

I'm new to GLM and trying to write a fps-style camera class

should I need to recalculate the up vector when I move the mouse?

however everything look strange after i change the up vector

Still, my program looks buggy when i maintain the up vector

file: fpscamera.cpp

void FPSCamera::rotateScreen(float dx, float dy){
auto oldDirection=getTarget()-getPosition();

setTarget(getPosition()+rotate(oldDirection, -dx*5, getUp()));
auto oldHoro=rotate(cross(oldDirection,getUp()), -dx*5, getUp());
setTarget(getPosition()+rotate(getTarget()-getPosition(),dy*5, oldHoro));

    ////////////////HERE////////////////////////
//setUp(normalize(cross(oldHoro,getTarget()-getPosition())));
}

You can download the source code and binary here

https://docs.google.com/file/d/0B9givuJvSet8ekRReWtRM29ldzg/edit?usp=sharing

mingw-built64 g++4.8(C++11) glfw3 GLM(MathHelper Library) required

g++ -std=c++0x -Wall main.cpp mesh.cpp fpscamera.cpp -lglfw3 -lopengl32 -lglu32 -lgdi32

move toward the target... W

turn Left/Right.... Q/E

move left/Right.... A/D

====================2013/8/6 edit I edit my camera class and add yaw pitch roll function

void Camera::roll(float among){
    if(isChange) resetCacheAxis();
    upVec=glm::rotate(upVec, among, cacheY);
    isChange=true;
}

void Camera::pitch(float among){
    if(isChange) resetCacheAxis();
    targetVec=posVec+glm::rotate(targetVec-posVec, among, cacheX);
    upVec=glm::normalize(glm::cross(cacheX, targetVec-posVec));
    isChange=true;
}
void Camera::yaw(float among){
    if(isChange) resetCacheAxis();
    targetVec=posVec+glm::rotate(targetVec-posVec, among, cacheZ);
    isChange=true;
}

void Camera::resetCacheAxis(){
    cacheY=glm::normalize(targetVec-posVec);
    cacheZ=glm::normalize(upVec);
    cacheX=glm::cross(cacheY, cacheZ);
}

and I implement mouse camera control with yaw and pitch

void FPSCamera::rotateScreen(float dx, float dy){
    yaw(-dx);
    pitch(dy);
}

the problem is still there....

Initial

after moving the mouse along a circle path several times.....

final

هل كانت مفيدة؟

المحلول

The camera should rotate about 2 axis. The up vector and the strafe vector. Rotating about the up vector gives the side to side "look", while rotating about the strafe vector gives the up and down "look".

When you perform the rotation, you need to not only transform the direction, but also the up vector and strafe vector. You don't seem to be doing that here. At least 2 vectors must be changed after a transformation as all 3 vectors must be orthogonal to each other.

Take a look at the following as pseudocode:

public static void MouseLook(float x, float y)
{
     Matrix xRot = Matrix.CreateFromAxisAngle(Vector3.Up, x * rotationSpeed);
     Matrix yRot = Matrix.CreateFromAxisAngle(Vector3.Right, y * rotationSpeed);

     viewMatrix = viewMatrix * yRot * xRot;

     // Orthogonalize the matrix
     OrthoNormalize();
 }

 private static void OrthoNormalize()
 {
     Vector3 zAxis = viewMatrix.Forward;
     zAxis.Normalize();

     Vector3 xAxis = Vector3.Cross(Vector3.Up,zAxis); 
     xAxis.Normalize();



     Vector3 yAxis = Vector3.Cross(xAxis,zAxis);  
     yAxis.Normalize();

     viewMatrix.Forward = zAxis;
     viewMatrix.Up = yAxis;
     viewMatrix.Right = xAxis;
}

Check out the following question as it has the answer to what you're looking for: Camera Rotation

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top