J'ai une structure de caméra qui contient les vecteurs de position, de direction et de direction. Je voudrais mettre à jour ces vecteurs basés sur le vecteur de gravité que je reçois de l'accéléromètre de l'iPhone. L'effet que je vais faire est le suivant: lorsque le haut du téléphone est incliné, la caméra regarde vers le sol. En d'autres termes, la scène/géométrie suit l'orientation du vecteur de gravité tandis que la caméra suit l'orientation du téléphone lui-même. J'ai pensé que je pourrais multiplier la matrice que j'ai construite à partir des vecteurs de la caméra par celle construite à partir du vecteur de gravité, puis sortir les nouveaux vecteurs de direction et de montée, mais je ne pense pas comprendre complètement le processus. Je n'arrive pas à le faire fonctionner. J'apprécierais grandement toute aide. Merci!Comment contrôler une caméra en openGL avec un vecteur de gravité provenant de l'accéléromètre de l'iPhone?
Répondre
Vous devez simplement mettre à jour la direction dans laquelle votre caméra regarde. Vous n'avez pas besoin de changer la matrice du monde, la méthode openGL "gluLookAt()" le fait automatiquement pour vous dans les coulisses. Si vous avez une configuration de classe de caméra, il suffit de créer une fonction pour définir le vecteur de direction de la caméra que vous aurez besoin d'obtenir calculer basé sur une valeur flottante/double (je suppose) de la boussole de l'iPhone. Lorsque la mise à jour de votre caméra est à la position lookAt(), elle doit changer la caméra pour qu'elle soit à l'emplacement correct.
Ce n'est pas très différent de ce que vous faites lorsque vous faites pivoter votre appareil photo dans un jeu basé sur FPS. La différence est que vous voulez faire pivoter la caméra le long de X-Axis au lieu de le long de l'axe Y. Jetez un coup d'œil à la manière dont une classe de caméra effectue une rotation pour déplacer la caméra vers la gauche ou la droite avec le clavier, puis modifiez-la pour qu'elle fonctionne en utilisant les valeurs de direction de votre compas.
Voici un code C++ j'ai écrit qui peut vous donner un aperçu de la façon dont votre classe appareil devrait fonctionner:
/* This reshapes the camera using the perspective projection */
void Camera::ReshapePerspectiveForPicking(void)
{
glMatrixMode(GL_PROJECTION);
// Sets the clipping volume
gluPerspective(m_FieldOfView, (float)m_width/(float)m_height, m_zNear, m_zFar);
gluLookAt( camPos.x, camPos.y, camPos.z,
camPos.x + camView.x, camPos.y + camView.y, camPos.z + camView.z,
0.0f, 1.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
}
Prenez note à la ligne ci-dessus (0.0f, 1.0f, 0,0 F). C'est le vecteur de direction UP. C'était statique pour mon jeu parce que l'appareil photo n'avait jamais besoin de baisser les yeux. Vous auriez simplement besoin de changer ce vecteur en créant un nouveau vecteur vers le haut sur l'orientation de la boussole.
La méthode ci-dessous était simplement une méthode alternative dont nous avions besoin pour parfois mettre à jour la caméra en lui passant un vecteur spécial. Vous pouvez probablement l'ignorer, je l'ai juste inclus pour que vous puissiez en tirer des leçons.
/* This updates the camera to look at the changed camera position. This uses a passed in camPosition and camView GameMath::Vector */
void Camera::Update(GameMath::Vector camPos, GameMath::Vector camView)
{
glMatrixMode(GL_PROJECTION);
gluLookAt( camPos.x, camPos.y, camPos.z,
camPos.x + camView.x, camPos.y + camView.y, camPos.z + camView.z,
0.0f, 1.0f,0.0f);
}
Voici ma méthode pour faire tourner la caméra le long de l'axe Y (Rappelez-vous souhaitez faire pivoter le long de l'axe X-) -I réécrivaient cette méthode maintenant, car il est un peu louche (je l'ai écrit il y a des années) mais c'est suffisant pour vous montrer comment cela peut être fait.
void Camera::Rotate(void)
{
if (m_rotateCamera == true)
{
// Keep the radians within 2 pi, roughly
float minimumRadiansRotate = 0.00;
float maximumRadiansRotate = 6.2831853072;
m_YRotateAngle = GameMath::Wrap(m_YRotateAngle, minimumRadiansRotate, maximumRadiansRotate);
m_YRotateAngle += m_rotateSpeed * m_rotateDirection; // Add to the camera's current angle value
camView.x = sin(m_YRotateAngle);
camView.z = -cos(m_YRotateAngle);
}
}
Il est un peu difficile de vous fournir un morceau de code spécifique pour faire ce que vous voulez faire parce que votre classe appareil photo est probablement différente de la mienne, même si cela devrait vous permettre de comprendre ce qui doit être fait. Le framework CoreLocation contient les bits de code dont vous aurez besoin pour lire les valeurs de la boussole dans le cas où vous n'avez pas encore codé cette partie.
Bonne chance.
Je pense que le sample GLGravity application d'Apple fait exactement ce que vous voulez, à moins que je ne lis votre demande mal.
Oui, c'est très similaire à ce que j'essaie d'atteindre. C'est pourquoi j'ai commencé mes recherches avec. Cependant, obtenir cet effet tout en stockant les vecteurs d'orientation pour une utilisation ultérieure est l'endroit où je trouve la difficulté. Merci! –
Je dois commencer par sayin, je suis très nouveau pour ce genre de choses, alors méfiez-vous, mais ...
i regardé le code ci-dessus et brock son explication et je pense que je suis venu avec une caméra rotative autour des axes x et y. En fait, mon appareil photo tourne autour du z aussi, mais je pense que c'est une histoire différente (je alimente simplement les valeurs filtrées des valeurs de l'accéléromètre x directement au vecteur «up» pour créer l'illusion que mes objets sont affectés par la gravité réelle ... fonctionne plutôt bien).
donc ... voici ce que je suis venu avec:
float lx = sin(DEGREES_TO_RADIANS(horzAngle));
float ly = sin(DEGREES_TO_RADIANS(vertAngle));
float lz = -cos(DEGREES_TO_RADIANS(horzAngle));
float x;
float y;
float z;
// get the default camera eye for the object
// this will center the object on the screen
[sprite.camera restore];
[sprite.camera eyeX:&x eyeY:&y eyeZ:&z];
// add distance calcs
x = x + (-1 * sprite.distance)*(lx);
z = z + (-1 * sprite.distance)*(-1);
[sprite.camera setEyeX:x eyeY:y eyeZ:z];
[sprite.camera setCenterX:x + lx centerY:y + ly centerZ:z + lz];
est d'utiliser la bibliothèque cocos2d (très facile à utiliser) ... ce encapsule les choses de la caméra afin qu'elle va finir par appeler gluLookAt
comme ceci:
gluLookAt(eyeX, eyeY, eyeZ,
centerX, centerY, centerZ,
upX, upY, upZ
);
comme je l'ai dit, je suis nouveau à cela, donc cela pourrait ne pas regarder à droite, mais il semble ... j'ai l'intention d'ajouter l'accéléromètre pour contrôler la vertAngle que vous décrivez , donc quand j'aurai le code accéléré branché, je vais essayer de me souvenir de poster ça ici.
aussi, si je manque quelque chose que quelqu'un d'autre peut ajouter de la lumière, j'aimerais l'entendre.
grâce,
john
Qu'est-ce que vous voulez vraiment est une nouvelle matrice de projection basée sur des valeurs d'accélération. Oolong fournit ce crazy math pour le faire (pas le mien).
/*
Oolong Engine for the iPhone/iPod touch
Copyright (c) 2007-2008 Wolfgang Engel http://code.google.com/p/oolongengine/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#import "Accelerometer.h"
#define FILTERINGFACTOR 0.1
@implementation Accel
- (void) SetupAccelerometer: (float) AcclerometerFrequency
{
//Configure and start accelerometer
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0/AcclerometerFrequency)];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
}
- (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)Acceleration
{
// use a basic low-pass filter to only keep the gravity in the accelerometer values
_accelerometer[0] = Acceleration.x * FILTERINGFACTOR + _accelerometer[0] * (1.0 - FILTERINGFACTOR);
_accelerometer[1] = Acceleration.y * FILTERINGFACTOR + _accelerometer[1] * (1.0 - FILTERINGFACTOR);
_accelerometer[2] = Acceleration.z * FILTERINGFACTOR + _accelerometer[2] * (1.0 - FILTERINGFACTOR);
}
- (void) GetAccelerometerMatrix:(GLfloat *) matrix
{
GLfloat length = sqrtf(_accelerometer[0] * _accelerometer[0] + _accelerometer[1] * _accelerometer[1] + _accelerometer[2] * _accelerometer[2]);
//Clear matrix to be used to rotate from the current referential to one based on the gravity vector
bzero(matrix, sizeof(matrix));
matrix[15] = 1.0f;
//matrix[3][3] = 1.0;
//Setup first matrix column as gravity vector
matrix[0] = _accelerometer[0]/length;
matrix[1] = _accelerometer[1]/length;
matrix[2] = _accelerometer[2]/length;
//Setup second matrix column as an arbitrary vector in the plane perpendicular to the gravity vector {Gx, Gy, Gz} defined by by the equation "Gx * x + Gy * y + Gz * z = 0" in which we arbitrarily set x=0 and y=1
matrix[4] = 0.0;
matrix[5] = 1.0;
matrix[6] = -_accelerometer[1]/_accelerometer[2];
length = sqrtf(matrix[4] * matrix[4] + matrix[5] * matrix[5] + matrix[6] * matrix[6]);
matrix[4] /= length;
matrix[5] /= length;
matrix[6] /= length;
//Setup third matrix column as the cross product of the first two
matrix[8] = matrix[1] * matrix[6] - matrix[2] * matrix[5];
matrix[9] = matrix[4] * matrix[2] - matrix[6] * matrix[0];
matrix[10] = matrix[0] * matrix[5] - matrix[1] * matrix[4];
}
- (void) GetAccelerometerVector:(double *) AccelValue;
{
// the vector is read-only, so make a copy of it and do not expose a pointer to it
AccelValue[0] = (double)_accelerometer[0];
AccelValue[1] = (double)_accelerometer[1];
AccelValue[2] = (double)_accelerometer[2];
}
@end
- 1. OpenGL: Aide à la transformation de caméra
- 2. Intersection sur un cercle de vecteur provenant du cercle
- 3. OpenGL - déplacer la caméra avec la souris
- 4. Xna Mise en place de la caméra
- 5. Images de caméra iPhone comme textures OpenGL ES
- 6. Comment obtenir un vecteur de caméra à partir du roulis, du tangage et du lacet?
- 7. Comment avoir un vecteur de valeur et utiliser un vecteur de pointeurs en conjonction?
- 8. Erreur de segmentation d'une caméra avec MATLAB
- 9. contrôler caméra de sécurité sans fil en utilisant le programme .NET
- 10. OpenGL: vecteur d'utilisateur multiple par matrice modelview?
- 11. Erreur de gravité dans SSIS
- 12. problème de rotation opengl
- 13. UIWebView: Comment contrôler l'affichage de la page avec un PDF?
- 14. Comment contrôler une caméra vidéo connectée à Firewire à l'aide d'un programme
- 15. Carte de développement intégrée avec caméra
- 16. C++ étendre un vecteur avec un autre vecteur
- 17. iphone cocos2d chipmunk - Centre de gravité
- 18. Comment rendre une image avec OpenGL ES?
- 19. Comment obtenir un aperçu de la caméra dans Android?
- 20. Rotation 3D en OpenGL et rotation locale
- 21. Obtention de la rotation de la caméra en radians sur les axes X, Y et Z dans OpenGL?
- 22. Quelle est la gravité de ma requête?
- 23. Quelle est la gravité de ce code?
- 24. Problème de caméra Direct3D
- 25. Construire un vecteur à partir de composants contenus dans un autre type de vecteur
- 26. POD vecteur de faible dimension en boost
- 27. Comment lire une caméra vidéo dans un programme win32 C
- 28. Quels sont les moyens de contrôler un périphérique via une adresse IP?
- 29. Comment stocker un vecteur de données de temps/valeur dans une base de données
- 30. Android: Comment créer un widget d'aperçu de caméra personnalisé?
Cela fonctionnerait pour le plus récent iPhone qui a une boussole intégrée (à moins que je comprends mal ce que vous expliquez), mais je ne travaille avec un accéléromètre donc tout ce que j'ai à un moment donné est le nouveau vecteur De plus, le nouveau vecteur ascendant n'est pas garanti perpendiculaire à l'axe des x de la caméra, alors comment déterminer la nouvelle direction de la caméra? –