2011-11-29 3 views
4

Я строию приложение дополненной реальности, которое показывает здания в местах, данных некоторыми интересными объектами. Когда вы указываете на эту точку с помощью своего iPhone (в портретном режиме), 3D-модель OpenGL появляется только в положении, обозначенном latitud и долготой (она преобразуется из этих координат GPS в координаты экрана с помощью rotationMatrix из CMDeviceMotion и получает значения x и y).rotationMatrix в режиме ландшафта меняется? Увеличенное reallity на iPhone

Моя проблема в том, что я хочу, чтобы она работала и в ландшафтном режиме. Я выполнил всю работу, поворачивая представления, адаптируя заголовок в зависимости от текущей ориентации устройства ... но когда вы указываете на здание в ландшафтном режиме, модель не привязана к этим координатам, но она перемещается по экрану. Я думаю, проблема в том, что rotationMatrix должен измениться, когда вы меняете ориентацию устройства, но я не могу найти способ решить эту проблему. Любая помощь?

- (void)onDisplayLink:(id)sender { 
    //Obtenemos los datos de movimiento del dispositivo 
    CMDeviceMotion *d = motionManager.deviceMotion; 

    //Si no son nulos (la localizacion esta activada y el magnetometro calibrado) 
    if (d != nil) { 
     //Obtenemos la matriz de rotacion 
     CMRotationMatrix r = d.attitude.rotationMatrix; 
     transformFromCMRotationMatrix(cameraTransform, &r); 

     //Indicamos a la vista que necesita ser renderizada de nuevo 
     [self setNeedsDisplay]; 
    } 
} 


- (void)drawRect:(CGRect)rect { 

    //vistaGPS.transform = CGAffineTransformMakeRotation([gestorOrientacion >devolverAnguloSegunOrientacion]); 

    //Si aun no tenemos puntos de interes, salimos 
    if (placesOfInterestCoordinates == nil) { 
     return; 
    } 

    //Multiplica la matriz de proyeccion y la de rotacion ¿¿¿para obtener la rotacion en >coordenadas openGL 
    mat4f_t projectionCameraTransform; 
    multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, >cameraTransform); 

    //Inicializamos el contador 
    int i = 0; 

    CLHeading *heading = locationManager.heading; 
    CLLocationDirection gradosDiferenciaNorteSinCorregir = heading.trueHeading; 

    //NSLog(@"%f , %f", gradosDiferenciaNorteSinCorregir, >gradosDiferenciaNorteSinCorregir+90); 
    CLLocationDirection gradosDiferenciaNorte = [gestorOrientacion >devolverHeadingCorregidoSegunOrientacion:gradosDiferenciaNorteSinCorregir]; 
    ////float bearing = [self getHeadingForDirectionFromCoordinate:newLocation.coordinate >toCoordinate: poi.coordenadas.coordinate]; 

    labelHeading.text = [NSString stringWithFormat:@"Heading: %f", gradosDiferenciaNorte];   


    NSArray *subvistas = [self subviews]; 

    for (PuntoInteres *poi in [puntosDeInteres objectEnumerator]) { 
     if ([subvistas containsObject:poi.vistaGL]) { 
      vec4f_t v; 

      //Multiplicamos la matriz por el vector de coordenadas del punto de interes 
      multiplyMatrixAndVector(v, projectionCameraTransform, >placesOfInterestCoordinates[i]); 

      float x = (v[0]/v[3] + 1.0f) * 0.5f; 
      float y = (v[1]/v[3] + 1.0f) * 0.5f; 

      [vistaGPS cambiarTextoLabelLatitud:x LabelLongitud:y LabelPrecision:88]; 


      //Si la coordenada Z del vector es negativa, el modelo debe verse 
      if (v[2] < 0.0f) { 
       //Centramos la vista en el punto adecuado 
       poi.vistaGL.center = CGPointMake(x*self.bounds.size.width, >self.bounds.size.height-y*self.bounds.size.height); 

       //Indicamos que deje de estar oculta 
       poi.vistaGL.hidden = NO; 

       [poi.vistaGL.modeloAPintar establecerRotacionEnX:0.0 Y:gradosDiferenciaNorte >Z:0.0]; 

       //Le decimos que comience a dibujarse 
       [poi.vistaGL startAnimation]; 
      } else { 
       //Indicamos que este oculta 
       poi.vistaGL.hidden = YES; 

       //Le decimos que deje de dibujarse 
       [poi.vistaGL stopAnimation]; 
      } 
     } 
     i++; 
    } 
} 


void transformFromCMRotationMatrix(vec4f_t mout, const CMRotationMatrix *m) { 
    mout[0] = (float)m->m11; 
    mout[1] = (float)m->m21; 
    mout[2] = (float)m->m31; 
    mout[3] = 0.0f; 

    mout[4] = (float)m->m12; 
    mout[5] = (float)m->m22; 
    mout[6] = (float)m->m32; 
    mout[7] = 0.0f; 

    mout[8] = (float)m->m13; 
    mout[9] = (float)m->m23; 
    mout[10] = (float)m->m33; 
    mout[11] = 0.0f; 

    mout[12] = 0.0f; 
    mout[13] = 0.0f; 
    mout[14] = 0.0f; 
    mout[15] = 1.0f; 
} 

ответ

2

Это копия моего ответа On stackoverflow

матрица вращения не вращается вокруг оси Z. При изменении ориентации экрана. Свойства угла для этого правильны, но я бы предпочел использовать только матрицу вращения. Вот код, который у меня есть для этого:

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