2011-01-06 5 views
2

J'ai écrit une classe de caméra à la première personne pour android.Première personne Rotation de caméra en 3D

La classe est très simple, l'objet de la caméra a ses trois axes X, Y et Z

et il y a des fonctions pour créer la matrice modelview (c.-à-calculateModelViewMatrix()), faire pivoter la caméra le long de sa X et Y axe et Traduire la caméra le long de son axe Z.

Je pense que ma calibrage ModelViewMatrix est correcte et je peux aussi traduire la caméra le long de l'axe Z.

La rotation le long de l'axe des x semble fonctionner, mais le long de l'axe Y, cela donne des résultats étranges. Un autre problème avec la rotation semble être qu'au lieu de faire tourner la caméra, mon modèle 3D commence à tourner à la place le long de son axe.

J'ai écrit une autre implémentation basée sur le point de vue et en utilisant la fonction GLU.gluLookAt() de l'OpenGL ES pour obtenir la matrice ModelView mais qui semble souffrir exactement des mêmes problèmes.

EDIT

d'abord merci pour votre réponse.

J'ai effectivement fait une deuxième implémentation de la classe Camera, cette fois en utilisant les fonctions de rotation fournies dans la classe android.opengl.Matrix comme vous l'avez dit. J'ai fourni le code ci-dessous, ce qui est beaucoup plus simple. À ma grande surprise, les résultats sont «exactement» les mêmes. À mon grand étonnement, les résultats sont exactement les mêmes. Cela signifie que mes fonctions de rotation et les fonctions de rotation d'Android produisent les mêmes résultats. J'ai fait un test simple et regardé mes données. Je viens de faire pivoter le point LookAt de 1-dgree à la fois autour de l'axe Y et j'ai regardé les coordonnées. Il semble que mon point LookAt soit en retard par rapport à l'angle de rotation exact, par ex. à 20 degrés il a seulement roatated 10 à 12 degrés. Et après 45 degrés il commence à s'inverser

Répondre

2

Il existe une classe android.opengl.Matrix qui est une collection de méthodes statiques qui font tout ce dont vous avez besoin sur un float [16] que vous passez. Je vous recommande fortement d'utiliser ces fonctions au lieu de rouler les vôtres. Vous voudrez probablement soit setLookAtM avec le point de référence calculé à partir de vos angles de caméra (en utilisant sin, cos comme vous le faites dans votre code - je suppose que vous savez comment faire.)

- éditer en réponse à de nouvelles réponse -

(vous devriez probablement avoir modifié votre question initiale, en passant - votre réponse comme une autre question me confondre un peu)

Ok, voici donc une façon de le faire. Ceci n'est pas compilé et n'a pas été testé. J'ai décidé de construire la matrice manuellement à la place; peut-être que cela donnera un peu plus d'informations sur ce qui se passe ...

class TomCamera { 
    // These are our inputs - eye position, and the orientation of the camera. 
    public float mEyeX, mEyeY, mEyeZ; // position 
    public float mYaw, mPitch, mRoll; // euler angles. 

    // this is the outputted matrix to pass to OpenGL. 
    public float mCameraMatrix[] = new float [16]; 

    // convert inputs to outputs. 
    public void createMatrix() { 
     // create a camera matrix (YXZ order is pretty standard) 
     // you may want to negate some of these constant 1s to match expectations. 
     Matrix.setRotateM(mCameraMatrix, 0, mYaw, 0, 1, 0); 
     Matrix.rotateM(mCameraMatrix, 0, mPitch, 1, 0, 0); 
     Matrix.rotateM(mCameraMatrix, 0, mRoll, 0, 0, 1); 
     Matrix.translateM(mCameraMatrix, 0, -mEyeX, -mEyeY, -mEyeZ); 
    } 
}