Frage

Ich mache so etwas wie eine erweiterte Reality -App, in der ich eine OpenGL -Szene habe, die ich mit der Schwerkraft in Einklang stehen möchte, egal wie sich das iOS -Gerät bewegt. Ich dachte, ich hätte es mit einer cmDevicemotion.attitude.pitch einwandfrei eingestellt, bis ich feststellte, dass ein iPhone mit dieser Nummer eingestellt wurde. Also habe ich einen Code aus dem Park* Beispiel genommen und jetzt versuche ich, die Rotation um den vertikalen Zugang zu isolieren. Die Szene, die ich zeichne, ist es egal, welche Überschrift der Benutzer gegenübersteht. Die Figuren werden immer eine festgelegte Entfernung zum Betrachter gezogen. Ich denke, wenn ich die vertikale Achse -Rotationskomponente herausfinne, kann ich sie umkehren und aus der Rotationsmatrix multiplizieren. Halten Sie also die OpenGL -Zahlen noch, wenn der Benutzer die Überschrift ändert.

Hier ist mein 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]);

    }

Ich benutze dann die Rotmatrix wie gewohnt in OpenGL.

Gedanken, Vorschläge? Danke im Voraus.

*Der Park -Beispielcode legt ein paar Punkte im realen Raum ein, arbeitet den Standort des Benutzers und die relative Richtung dieser Punkte aus und zeichnet sie auf dem Bildschirm, sodass die am Horizont auf ihren Standort verweist.

War es hilfreich?

Lösung 3

Ich habe einige Hinweise auf diese Antwort genommen und eine Lösung gefunden:

https://stackoverflow.com/questions/5328848/simulations-an-image-floating-effect-using-coremotion-tevicemotion-on-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));
}

Dieses Wagen, wenn das Telefon in der Nähe von vertikal ist. Also schaue ich immer noch.

Andere Tipps

Ich drahe nur die Ausrichtung um die Z -Achse abhängig von der Ausrichtung des Gerätsbildschirms. Dies ist nicht der schönste, aber es scheint genau das zu tun, was ich brauche, ohne nach Euler und zurück zu gehen (und damit die Probleme der Gymbal -Schleuse zu vermeiden)

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

Hier ist ein Code, um zu klären, wie die Einstellung verwendet wird.

// 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;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top