2013-03-14 5 views
2

1 인칭 카메라를 만들고 싶습니다. 두 가지 모드 중 하나를 선택할 수 있습니다. 특정 위치를 보면서 고정되어 있으며 (표준 "wasd"운동은 그 점을 중심으로 움직입니다), 또는 자유로운 모습을 보입니다. 움직임이 한 지점을 돌고있는 데 제약이 없으며 마우스를 사용하여 어디든지 볼 수 있습니다. (나는 자유의 여섯 자유도 카메라를 바라는 것을 원하지 않기 때문에 똑바로/아래로 똑바로 볼 수있을 정도로 단단히 고정되어있다.) 이것은 내가 현재 롤을 갖고 싶지 않다는 것을 의미한다.쿼터니온 카메라 만들기

누군가 이런 종류의 작업을 수행하는 데 필요한 기본 사항을 수행 할 수 있습니까? 저는 현재 LWJGL을 사용하고 있기 때문에 LWJGL이 제공하지 않는 몇 가지 일을하는 제 자신의 Quaternion 클래스뿐만 아니라 제공하는 Vector * 및 Matrix * 클래스에 액세스 할 수 있습니다. 또한 OpenGL의 gluLookAt (eyex, eyey, ..., upy, upz)와 정확히 일치하는 좌표가 주어진 lookAt 메서드가 있다고 가정합니다. 여기에서 행렬/행렬을 만들고 싶습니다. 또한 얻어진 매트릭스/행렬

layout(location = 0) in vec4 position; 
uniform mat4 camera; 
uniform mat4 projection; 
uniform mat4 model; 
// ... 
gl_Position = projection * camera * model * (position); 

코드의 일부를 인 버젼 쉐이더 (330)에서 사용되는가는 가정한다. 현재 작업 순서를 유지합니까? 또는 올바른 gl_Position을 얻기 위해 어떤 방식 으로든 변경해야합니까?

사원 수 코드 :

public class Quaternion { 
    public float x, y, z, w; 

    public Quaternion() { 
     this.x = 0.0f; 
     this.y = 0.0f; 
     this.z = 0.0f; 
     this.w = 1.0f; 
    } 

    public Quaternion(Vector3f v, float w) { 
     this.x = v.x; 
     this.y = v.y; 
     this.z = v.z; 
     this.w = w; 
    } 

    public Quaternion(float x, float y, float z, float w) { 
     this.x = x; 
     this.y = y; 
     this.z = z; 
     this.w = w; 
    } 

    public Quaternion(Quaternion other) { 
     this.x = other.x; 
     this.y = other.y; 
     this.z = other.z; 
     this.w = other.w; 
    } 

    public float length() { 
     return (float)Math.sqrt(x * x + y * y + z * z + w * w); 
    } 

    public Quaternion normalize() { 
     return Quaternion.normalize(new Quaternion(this)); 
    } 

    public Quaternion conjugate() { 
     return Quaternion.conjugate(new Quaternion(this)); 
    } 

    public Quaternion mult(Quaternion other) { 
     return Quaternion.mult(this, other, new Quaternion()); 
    } 

    public static Quaternion fromAxisAngle(Quaternion q, Vector3f axis, float angle) { 
     float sinAngle2 = (float)Math.sin(angle/2.0); 
     q.x = axis.x * sinAngle2; 
     q.y = axis.y * sinAngle2; 
     q.y = axis.y * sinAngle2; 
     q.w = (float)Math.cos(angle/2.0); 
     return q; 
    } 

    public static Matrix4f toMatrixUnit(Quaternion q) { 
     Matrix4f ret = new Matrix4f(); 

     ret.m00 = 1 - 2 * q.y * q.y - 2 * q.z * q.z; 
     ret.m01 = 2 * q.x * q.y - 2 * q.w * q.z; 
     ret.m02 = 2 * q.x * q.z + 2 * q.w + q.y; 
     ret.m03 = 0; 

     ret.m10 = 2 * q.x * q.y + 2 * q.w * q.z; 
     ret.m11 = 1 - 2 * q.x * q.x - 2 * q.z * q.z; 
     ret.m12 = 2 * q.y * q.z + 2 * q.w * q.x; 
     ret.m13 = 0; 

     ret.m20 = 2 * q.x * q.z - 2 * q.w * q.z; 
     ret.m21 = 2 * q.y * q.z - 2 * q.w * q.x; 
     ret.m22 = 1 - 2 * q.x * q.x - 2 * q.y * q.y; 
     ret.m23 = 0; 

     ret.m30 = 0; 
     ret.m31 = 0; 
     ret.m32 = 0; 
     ret.m33 = 1; 

     return ret; 
    } 

    public static Matrix4f toMatrix(Quaternion q) { 
     throw new UnsupportedOperationException("Use toMatrixUnit"); 
//  Matrix4f ret = new Matrix4f(); 
//  return ret; 
    } 

    public static Quaternion mult(Quaternion A, Quaternion B, Quaternion C) { 
     C.x = A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y; 
     C.y = A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x; 
     C.z = A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w; 
     C.w = A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z; 
     return C; 
    } 

    public static Quaternion normalize(Quaternion q) { 
     float len = q.length(); 
     q.x = q.x/len; 
     q.y = q.y/len; 
     q.z = q.y/len; 
     q.w = q.w/len; 
     return q; 
    } 

    public static Quaternion conjugate(Quaternion q) { 
     q.x = -q.x; 
     q.y = -q.y; 
     q.z = -q.z; 
     return q; 
    } 

답변

1

당신이 구글을 검색하면 쿼터니언 기반의 카메라를 구현하기위한 자원의 많음이있다.

당신이 C++에있는 경우, 내가 사용하는 것이 좋습니다 (다음 등을 클릭하십시오) GLM (OpenGL을 수학)에 대한 자신의 VEC/매트/퀘스트 지원 (방금 배우는 경우 산술에 버그가 있습니다.)

관련 문제