ios uikit opengl-es-2.0 augmented-reality vuforia

ios - ¿Cómo debo traducir un modelo de OpenGLES a un CATransform3D?



uikit opengl-es-2.0 (1)

Mi objetivo es superponer una vista de UIKit estándar (por el momento, solo estoy creando un UILabel pero eventualmente tendré contenido personalizado) sobre una forma detectada mediante el rastreo de imágenes y el Vuforia AR SDK. Tengo algo que funciona, pero con un término "fudge" que no puedo explicar. Me gustaría entender dónde está mi error, por lo que puedo justificar la existencia de esta corrección o usar un algoritmo diferente que se sepa que es válido.

Mi proyecto se basa en el proyecto de ejemplo ImageTargets en el SDK de Vuforia. Donde su EAGLView itera sobre los resultados para representar las teteras OpenGL, he reemplazado esto con una llamada a mi clase TrackableObjectController ++ TrackableObjectController . Para cada resultado rastreable, hace esto:

- (void)augmentedRealityView:(EAGLView *)view foundTrackableResult:(const QCAR::TrackableResult *)trackableResult { // find out where the target is in Core Animation space const QCAR::ImageTarget* imageTarget = static_cast<const QCAR::ImageTarget*>(&(trackableResult->getTrackable())); TrackableObject *trackable = [self trackableForName: TrackableName(imageTarget)]; trackable.tracked = YES; QCAR::Vec2F size = imageTarget->getSize(); QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(trackableResult->getPose()); CGFloat ScreenScale = [[UIScreen mainScreen] scale]; float xscl = qUtils.viewport.sizeX/ScreenScale/2; float yscl = qUtils.viewport.sizeY/ScreenScale/2; QCAR::Matrix44F projectedTransform = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; QCAR::Matrix44F qcarTransform = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; /* this sizeFudge constant is here to put the label in the correct place in this demo; I had thought that * the problem was related to the units used (I defined the length of the target in mm in the Target Manager; * the fact that I''ve got to multiply by ten here could be indicative of the app interpreting length in cm). * That turned out not to be the case, when I changed the reported length of the target it stopped drawing the * label at the correct size. Currently, therefore, the app and the target database are both using mm, but * there''s the following empirically-divised fudge factor to get the app to position the correctly-sized view * in the correct position relative to the detected object. */ const double sizeFudge = 10.0; ShaderUtils::translatePoseMatrix(sizeFudge * size.data[0] / 2, sizeFudge * size.data[1] / 2, 0, projectedTransform.data); ShaderUtils::scalePoseMatrix(xscl, -yscl, 1.0, projectedTransform.data); // flip along y axis ShaderUtils::multiplyMatrix(projectedTransform.data, qUtils.projectionMatrix.data, qcarTransform.data); ShaderUtils::multiplyMatrix(qcarTransform.data, modelViewMatrix.data, qcarTransform.data); CATransform3D transform = *((CATransform3D*)qcarTransform.data); // both are array[16] of float transform = CATransform3DScale(transform,1,-1,0); //needs flipping to draw trackable.transform = transform; }

Luego hay otro código, llamado en el hilo principal, que mira mis instancias de TrackableObject , aplica el CATransform3D computado a la capa de la vista de superposición y establece la vista de superposición como una subvista de EAGLView .

Mi problema es que, como se ha sizeFudge en el ejemplo de código, con este factor sizeFudge . Aparte de este factor, el código que tengo hace lo mismo que esta respuesta ; Pero eso es poner mi punto de vista en el lugar equivocado.

Empíricamente, encuentro que si no sizeFudge término sizeFudge , mi vista superpuesta sigue bien la orientación y la traducción del objeto rastreado, pero está desplazada hacia abajo y hacia la derecha en la pantalla del iPad. Esto es una diferencia de traducción, por lo que tiene sentido. que cambia el termino utilizado para. Primero pensé que el problema era el tamaño del objeto como se especifica en Target Manager de Vuforia. Esto resulta no ser el caso; si creo un objetivo diez veces el tamaño, entonces la vista de superposición se dibuja en el mismo lugar incorrecto pero diez veces más pequeño (ya que el AR supone que el objeto que está rastreando está más lejos, supongo).

Es solo traducir la pose aquí que me lleva a donde quiero estar, pero esto no es satisfactorio ya que no tiene ningún sentido para mí. ¿Alguien puede explicar la forma correcta de traducir las coordenadas de OpenGL provistas por Vuforia a un CATransform3D que no se basa en números mágicos?

** Algunos datos más **

El problema es más complicado de lo que pensaba cuando escribí esta pregunta. La ubicación de la etiqueta en realidad parece depender de la distancia desde el iPad al objeto rastreado, aunque no de forma lineal. También hay un aparente error sistemático.

Aquí hay un gráfico construido al mover el iPad a una cierta distancia del objetivo (ubicado sobre el cuadrado negro) y marcarlo con un bolígrafo donde apareció el centro de la vista. Los puntos arriba y a la izquierda de la casilla tienen el fudge de traducción como se describe arriba, los puntos abajo y a la derecha tienen sizeFudge==0 . Es de esperar que la relación entre la distancia y el desplazamiento que se muestra aquí indiquen a alguien con más conocimientos de gráficos en 3D que yo en cuál es el problema con la transformación.


Es probable que tenga que ver con la configuración de sus vistas en primer lugar. Una desviación extraña podría deberse a que el ancho y la altura son al revés o cualquier otro valor incorrecto posible, como el uso de una relación de pantalla de iPhone en un iPad.

¿Es tu aplicación el paisaje? Si es así, entonces dale una oportunidad en el retrato. En el pasado, me he dado cuenta de que las aplicaciones siempre se inician con las dimensiones de la pantalla vertical (aunque no lo he confirmado), por lo que si la configuración de la vista se produce antes de que la pantalla sea la "forma correcta", obtendrá una discrepancia.

También puedes intentar calcular exactamente cuánto está mal. En lugar de multiplicar size.data como hack: agregue otra traducción y modifique los números hasta que sea correcto. Esos números pueden darte una mejor idea de lo que está sucediendo. * 10 es probablemente pura casualidad y no significa mucho.