Domanda

Sto realizzando qualcosa come un'app di realtà aumentata, in cui ho una scena OpenGL che voglio rimanere allineato con la gravità, non importa come si muova il dispositivo iOS. Pensavo di averlo impostato bene con un cmdevicemotion.ttitude.pitch, fino a quando non ho scoperto che appoggiarsi a un iPhone lateralmente si mette con quel numero. Quindi ho preso un po 'di codice dal parco* e ora sto cercando di isolare la rotazione attorno all'accesso verticale. La scena che sto disegnando non importa quale intestazione dell'utente sta affrontando, le figure verranno sempre disegnate a una distanza impostata dallo spettatore. Penso che quando scopro il componente di rotazione dell'asse verticale posso invertirlo e moltiplicarlo dalla matrice di rotazione, quindi mantieni le figure OpenGL quando l'utente cambia l'intervallo.

Ecco il mio codice:

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]);

    }

Quindi uso la Rotmatrix come al solito in OpenGL.

Pensieri, suggerimenti? Grazie in anticipo.

*Il codice di esempio del parco imposta alcuni punti nello spazio reale, risolve la posizione dell'utente e la direzione relativa di quei punti e li disegna sullo schermo in modo che appaia a fluttuare all'orizzonte che puntano verso la loro posizione.

È stato utile?

Soluzione 3

Ho preso alcuni suggerimenti da questa risposta e ho trovato una soluzione:

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

Tuttavia questo tipico quando il telefono è quasi verticale. Quindi sto ancora cercando.

Altri suggerimenti

Ruoto solo l'orientamento attorno all'asse Z a seconda dell'orientamento dello schermo del dispositivo. Questo non è il più bello, ma sembra fare esattamente ciò di cui ho bisogno, senza andare a Eulero e ritorno (e quindi, evitando i problemi di blocco della palestra)

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

Ecco un po 'di codice per chiarire come usare l'atteggiamento.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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top