2013-03-14 2 views
2

J'aimerais pouvoir créer une caméra à la première personne, qui peut être dans l'un des deux modes. Soit il est fixe en regardant un endroit spécifique (et le mouvement standard "wasd" se déplace autour de ce point), soit il a un aspect libre, où le mouvement n'est pas contraint à tourner autour d'un point et la souris peut être utilisée n'importe où. (serré pour ne pouvoir regarder que vers le haut/le bas, car je ne veux pas d'une caméra à six degrés de liberté à la Descent) Cela signifie que je ne veux pas avoir de roll. Est-ce que quelqu'un peut me guider à travers les bases nécessaires pour mettre en œuvre ce genre de chose? J'utilise actuellement LWJGL, j'ai donc accès aux classes Vector * et Matrix *, ainsi qu'à ma propre classe Quaternion qui fait des choses que LWJGL ne fait pas. Supposons aussi que j'ai une méthode, lookAt, qui reçoit des coordonnées exactement comme gluLookAt d'OpenGL (eyex, eyey, ..., upy, upz), et c'est là que je voulais construire la matrice/matrices. Supposons également la matrice résultante/matrices vont être utilisées dans une version 330 shaders oùCréer un appareil photo Quaternion

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

est une partie du code. Est-ce que je garde l'ordre actuel des opérations, ou dois-je le modifier de quelque façon que ce soit pour obtenir la bonne position de gl_Position?

Code Quaternion:

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; 
    } 

Répondre

1

Il y a beaucoup de ressources pour la mise en œuvre appareil photo en fonction quaternions si vous recherchez Google.

Si vous êtes en C++, je recommande d'utiliser GLM (OpenGL Mathématiques) pour leur VEC/tapis/quat support (si vous apprenez juste, il vaut mieux avoir des bugs dans votre arithmétique.)

Questions connexes