2013-02-18 11 views
16

Il mio obiettivo è sovrapporre una visualizzazione UIKit standard (per il momento sto creando solo uno UILabel ma alla fine avrò un contenuto personalizzato) su una forma rilevata utilizzando il tracciamento delle immagini e l'SDK Vuforia AR. Ho qualcosa che funziona, ma con un termine "fudge" che non posso giustificare. Mi piacerebbe capire dove è il mio errore, quindi posso giustificare l'esistenza di questa correzione o utilizzare un algoritmo diverso che è noto per essere valido.Come dovrei tradurre un modelView OpenGLES in un CATransform3D?

Il mio progetto si basa sul progetto di esempio ImageTargets nell'SDK di Vuforia. Laddove il loro esegue iterazioni sui risultati per il rendering delle teorie OpenGL, l'ho sostituito con una chiamata alla classe ObjC++ TrackableObjectController. Per ogni risultato tracciabile, lo fa:

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

V'è poi un altro codice, chiamato sul thread principale, che guarda i miei TrackableObject casi, vale la calcolata CATransform3D al livello della vista sovrapposizione e imposta la vista sovrapposizione come una sottoview dello .

Il mio problema è, come il commento nel codice di esempio ha dato via, con questo fattore sizeFudge. Oltre a questo fattore, il codice che ho fa la stessa cosa as this answer; ma questo sta mettendo la mia opinione nel posto sbagliato.

Empiricamente trovo che se non includere il termine sizeFudge, allora la mia vista sovrapposizione segue l'orientamento e la conversione dell'oggetto monitorato bene, ma è compensato verso il basso e verso destra sul iPad schermo-si tratta di una differenza di conversione, quindi ha senso cambiare il termine usato per. Per prima cosa ho pensato che il problema fosse la dimensione dell'oggetto come specificato in Target Manager di Vuforia. Questo risulta non essere il caso; se creo un bersaglio dieci volte la dimensione, la vista di sovrapposizione viene disegnata nello stesso posto errato ma dieci volte più piccola (poiché l'AR presuppone che l'oggetto del suo tracciamento sia più lontano, suppongo).

Trasloca qui solo la posa che mi porta dove voglio essere, ma questo non è soddisfacente in quanto non ha alcun senso per me. Qualcuno può spiegare il modo corretto di tradurre le coordinate OpenGL fornite da Vuforia in un CATransform3D che non si basa su numeri magici?

** Alcuni altri dati **

il problema è più complicato di quanto ho pensato quando ho scritto questa domanda. La posizione dell'etichetta sembra effettivamente dipendere dalla distanza dall'iPad all'oggetto tracciato, sebbene non in modo lineare. C'è anche un evidente errore sistematico.

Ecco una tabella costruita spostando l'iPad a una certa distanza dall'obiettivo (situato sopra il quadrato nero) e contrassegnando con una penna dove è apparso il centro della vista. I punti sopra e alla sinistra del quadrato hanno il fudge di traduzione come descritto sopra, i punti in basso e a destra hanno sizeFudge==0. Speriamo che la relazione tra distanza e offset mostrata qui induca qualcuno con più conoscenza della grafica 3D di me a capire qual è il problema con la trasformazione.

Chart as described in the previous paragraph.

+1

Qual è il sistema di coordinate utilizzato per la loro vista OpenGL ES? Normalmente, le scene OpenGL ES sono impostate con coordinate che vanno da -1 a 1, piuttosto che da 0 a [larghezza] o [altezza] delle coordinate UIKit. Potevo vedere la necessità di una traduzione per renderlo conto. Se stessero usando un sistema di coordinate compreso tra -10 e 10, ciò potrebbe spiegare il fattore fudge della traduzione. –

+0

Grazie per l'intuizione @BradLarson. Non sono sicuro di come troverei questo sistema di coordinate; Al momento non riesco a vedere dove il progetto imposta un trancio o un'altra proiezione della telecamera. Ho anche la sensazione che questo non sia correlato, perché il sistema di coordinate di _view's_ sarebbe bidimensionale nel piano della vista, non è vero? –

+1

Sembra che questi ragazzi potrebbero avere la risposta per te o almeno alcuni suggerimenti utili: http://stackoverflow.com/questions/6045502/how-to-get-catransform3d-from-projection-and-modelview-matricesModelView-matrices – cb88

risposta

1

E 'probabilmente a che fare con la messa a punto dei vostri punti di vista, in primo luogo. Uno strano offset potrebbe essere causato dal fatto che la larghezza e l'altezza sono il modo sbagliato o altri eventuali valori errati come l'utilizzo di un rapporto schermo iPhone su un iPad.

La tua app è panoramica? Se è così, provalo in ritratto.In passato ho notato che le app sembrano sempre lanciare con le dimensioni dello schermo verticale (non l'ho ancora confermato), quindi se l'impostazione della visualizzazione avviene prima che lo schermo sia il "giusto modo" intorno a te, otterrai una discrepanza.

Si potrebbe anche provare a calcolare esattamente quanto è fuori. Invece di moltiplicare size.data come un hack: aggiungi un'altra traduzione e modifica i numeri finché non è corretta. Questi numeri potrebbero darti un'idea migliore di ciò che sta accadendo. * 10 è probabilmente solo passera pura e non significa molto.

+0

Sembra un percorso promettente per scendere, grazie. Ho visto altri problemi nell'app a causa dell'orientamento verticale/orizzontale, quindi esaminerò l'argomento. –

+0

Mi sembra che ci sia sicuramente un errore _different_ off-by-some in diversi orientamenti, che potrebbe essere un indizio. Non è il tutto, poiché tutto appare in (un diverso) posto sbagliato anche nell'orientamento verticale. Ho trovato che l'importo fuori varia con la distanza dal bersaglio, quindi sembra un problema generale con la trasformazione della matrice. –