Question

Je fais quelque chose comme une application de réalité augmentée, où j'ai une scène OpenGL que je veux rester aligné avec gravité, peu importe la façon dont l'appareil iOS se déplace. Je pensais que je l'avais mis en place très bien avec un CMDeviceMotion.attitude.pitch, jusqu'à ce que je découvre que penchant mess d'un iPhone avec ce numéro. J'ai donc pris un certain code de l'Garez * exemple et j'essaie maintenant d'isoler la rotation autour de l'accès vertical. La scène je dessine ne se soucie pas quelle position l'utilisateur est confronté, les chiffres sera toujours tiré à une distance déterminée du spectateur. Je pense que lorsque je figure sur le composant de rotation d'axe vertical, je peux inverser et multiplier hors de la matrice de rotation afin de garder les chiffres OpenGL encore lorsque l'utilisateur change de position.

Voici mon code:

CMDeviceMotion *d = motionManager.deviceMotion;
if (d != nil) {

    CMRotationMatrix r = d.attitude.rotationMatrix;
    transformFromCMRotationMatrix(cameraTransform, &r);


    mat4f_t projectionCameraTransform;
    multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransform);

    GLKMatrix4 rotMatrix = GLKMatrix4Make(projectionCameraTransform[0], 
                                          projectionCameraTransform[1], 
                                          projectionCameraTransform[2], 
                                          projectionCameraTransform[3], 
                                          projectionCameraTransform[4], 
                                          projectionCameraTransform[5], 
                                          projectionCameraTransform[6], 
                                          projectionCameraTransform[7], 
                                          projectionCameraTransform[8], 
                                          projectionCameraTransform[9], 
                                          projectionCameraTransform[10], 
                                          projectionCameraTransform[11], 
                                          projectionCameraTransform[12], 
                                          projectionCameraTransform[13], 
                                          projectionCameraTransform[14], 
                                          projectionCameraTransform[15]);

    }

J'utilise alors le rotMatrix comme d'habitude dans OpenGL.

Pensées, suggestions? Merci à l'avance.

* Les ensembles de code exemple Garez quelques points dans l'espace réel, fonctionne sur l'emplacement de l'utilisateur et la direction relative de ces points et les attire à l'écran de sorte que le semblent flotter au pointage horizon vers leur emplacement.

Était-ce utile?

La solution 3

J'ai pris quelques conseils de cette réponse et trouver une solution:

https: / /stackoverflow.com/questions/5328848/simulating-an-image-floating-effect-using-coremotion-devicemotion-on-the-iphone/5442962#5442962

if (d != nil) {

    GLKMatrix4 rotMatrix = GLKMatrix4MakeRotation(0, 0, 1, 0);
    float pitch = d.attitude.pitch;

    if (d.gravity.z > 0)
        pitch = -pitch;

    rotMatrix = GLKMatrix4Rotate(rotMatrix, pitch, -1, 0, 0);
    rotMatrix = GLKMatrix4Rotate(rotMatrix, d.attitude.roll, 0, -1, 0);
    rotMatrix = GLKMatrix4Rotate(rotMatrix, d.attitude.yaw, 0, 0, -1);
    rotMatrix = GLKMatrix4Multiply(rotMatrix, GLKMatrix4MakeRotation(M_PI/2, 1, 0, 0));
}

Cependant, cette détraque lorsque le téléphone est proche de la verticale. Donc, je suis toujours à la recherche.

Autres conseils

I tourner simplement l'orientation autour de l'axe Z en fonction de l'orientation de l'écran du dispositif. Ce n'est pas la plus jolie mais il semble faire exactement ce que je dois, sans aller euler et le dos (et donc, en évitant les problèmes de verrouillage gymbal)

GLKMatrix4 deviceMotionAttitudeMatrix;
if (_cmMotionmanager.deviceMotionActive) {
    CMDeviceMotion *deviceMotion = _cmMotionmanager.deviceMotion;

    // Correct for the rotation matrix not including the screen orientation:
    // TODO: Let the device notify me when the orientation changes instead of querying on each update.
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    float deviceOrientationRadians = 0.0f;
    if (orientation == UIDeviceOrientationLandscapeLeft) {
        deviceOrientationRadians = M_PI_2;
    }
    if (orientation == UIDeviceOrientationLandscapeRight) {
        deviceOrientationRadians = -M_PI_2;
    }
    if (orientation == UIDeviceOrientationPortraitUpsideDown) {
        deviceOrientationRadians = M_PI;
    }
    GLKMatrix4 baseRotation = GLKMatrix4MakeRotation(deviceOrientationRadians, 0.0f, 0.0f, 1.0f);

    CMRotationMatrix a = deviceMotion.attitude.rotationMatrix;
    deviceMotionAttitudeMatrix
        = GLKMatrix4Make(a.m11, a.m21, a.m31, 0.0f,
                         a.m12, a.m22, a.m32, 0.0f,
                         a.m13, a.m23, a.m33, 0.0f,
                         0.0f, 0.0f, 0.0f, 1.0f);
    deviceMotionAttitudeMatrix = GLKMatrix4Multiply(baseRotation, deviceMotionAttitudeMatrix);
}
else
{
    // Look straight forward (we're probably in the simulator, or a device without a gyro)
    deviceMotionAttitudeMatrix = GLKMatrix4MakeRotation(-M_PI_2, 1.0f, 0.0f, 0.0f);
}

Voici un code pour clarifier comment utiliser le attitude.rotationMatrix

// initial model view matrix
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -5.f);

// convert CMRotationMatrix to GLKMatrix4
CMRotationMatrix r = motion.attitude.rotationMatrix;
GLKMatrix4 = GLKMatrix4Make(r.m11, r.m21, r.m31, 0.0f,
                            r.m12, r.m22, r.m32, 0.0f,
                            r.m13, r.m23, r.m33, 0.0f,
                             0.0f,  0.0f,  0.0f, 1.0f);

// apply motion rotation matrix
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, _motionRotationMatrix);

// apply matrix to effect
self.effect.transform.modelviewMatrix = modelViewMatrix;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top