RotationMatrix in landscape mode? Increased Reliability on iPhone

I am creating an augmented reality application that shows buildings in places defined by some interesting objects. When you point to this point using your iPhone (in portrait mode), the OpenGL 3D model appears only in the position indicated by latitud and longitude (it is converted from these GPS coordinates to screen coordinates using rotationMatrix from CMDeviceMotion and gets the x and y values )

My problem is that I want it to work in landscape mode. I did all the work, turning the views, adapting the title depending on the current orientation of the device ... but when you point to a building in landscape mode, the model is not attached to these coordinates, but it moves around the screen. I think the problem is that rotationMatrix should change when you change the orientation of the device, but I cannot find a way to solve this problem. Any help?

- (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; } 
+4
source share
1 answer

This is a copy of my answer fooobar.com/questions/1383713 / ...

The rotation matrix does not rotate around the Z axis when the screen orientation changes. The angle properties are correct for this, but I would prefer to use only the rotation matrix. Here is the code I have for this:

 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); } 
+2
source

Source: https://habr.com/ru/post/1383710/


All Articles