2013-02-18 15 views
16

Moim celem jest nałożenie standardowego widoku UIKit (na razie tworzę tylko UILabel, ale w końcu będę mieć niestandardową zawartość) nad wykrytym kształtem za pomocą śledzenia obrazu i zestawu SD pakietu Vuforia AR. Mam coś, co działa, ale z terminem "krówki", którego nie mogę wyjaśnić. Chciałbym zrozumieć, gdzie jest mój błąd, więc mogę albo uzasadnić istnienie tej poprawki, albo użyć innego algorytmu, który jest znany jako ważny.Jak powinienem przetłumaczyć model OpenGLES do CATransform3D?

Mój projekt jest oparty na przykładowym projekcie ImageTargets w pakiecie SDK Vuforia. Gdzie ich EAGLView iteruje nad wynikami do renderowania czajników OpenGL, zastąpiłem to wywołaniem mojej klasy ObjC++ TrackableObjectController. Dla każdego wyniku trackable, robi to:

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

Nie ma wtedy inny kod, zwany w głównym wątku, który patrzy na moich TrackableObject przypadkach stosuje komputerowej CATransform3D do warstwy widoku nakładki i ustawia widok nakładki jako Wywiad z EAGLView.

Mój problem polega na tym, że komentarz w próbce kodu został rozdany, z tym czynnikiem sizeFudge. Oprócz tego czynnika, kod, który mam, robi to samo: as this answer; ale to umieszcza mój pogląd w niewłaściwym miejscu.

Empirycznie stwierdzam, że jeśli nie uwzględnię terminu sizeFudge, to mój widok nakładki śledzi orientację i tłumaczenie dobrze śledzonego obiektu, ale jest przesunięty w dół i w prawo na ekranie iPada - jest to różnica w tłumaczeniu, więc ma sens zmiana terminu. Najpierw pomyślałem, że problemem jest rozmiar obiektu określony w Menedżerze docelowym Vuforii. Okazuje się, że tak nie jest; jeśli utworzę 10-krotny cel, to widok nakładki zostanie narysowany w tym samym, niepoprawnym miejscu, ale dziesięciokrotnie mniejszy (jak przypuszcza AR, zakładając, że śledzenie obiektu jest bardziej oddalone).

To jest tylko tłumaczenie pozie, która doprowadza mnie tam, gdzie chcę być, ale jest to niezadowalające, ponieważ nie ma dla mnie żadnego sensu. Czy ktokolwiek może wyjaśnić poprawny sposób tłumaczenia ze współrzędnych OpenGL dostarczonych przez Vuforia na CATransform3D, który nie polega na magicznych liczbach?

** Niektóre więcej danych **

Problem jest bardziej skomplikowany niż myślałem, kiedy pisałem to pytanie. Wydaje się, że lokalizacja etykiety zależy od odległości iPada od śledzonego obiektu, ale nie liniowo. Istnieje również oczywisty błąd systematyczny.

Oto wykres skonstruowany przez przeniesienie iPada do pewnej odległości od celu (znajdującego się nad czarnym kwadratem) i oznaczenie piórem, w którym pojawiło się centrum widoku. Punkty powyżej i na lewo od kwadratu mają krotność translacji, jak opisano powyżej, punkty poniżej i na prawo mają sizeFudge==0. Mam nadzieję, że pokazany tu stosunek odległości do przesunięcia wskazuje, że ktoś, kto ma większą wiedzę o grafice 3D niż ja, ma problem z transformacją.

Chart as described in the previous paragraph.

+1

Jaki jest układ współrzędnych używany do ich widoku OpenGL ES? Zwykle sceny OpenGL ES są konfigurowane ze współrzędnymi, które idą od -1 do 1, a nie od 0 do [szerokości] lub [wysokości] współrzędnych UIKit. Widzę, że potrzebuję tłumaczenia, aby to uwzględnić. Jeśli używali układu współrzędnych w zakresie od -10 do 10, może to wyjaśniać współczynnik krówki tłumaczenia. –

+0

Dzięki za wgląd @BradLarson. Nie jestem pewien, w jaki sposób znajdę ten układ współrzędnych; Nie mogę obecnie zobaczyć, w którym miejscu projektu ustawiono kształt stożka ściętego lub inną projekcję z kamery. Mam również wrażenie, że nie ma to związku, ponieważ układ współrzędnych _widoku_ byłby dwuwymiarowy w płaszczyźnie widoku, czyż nie? –

+1

Wygląda na to, że ci faceci mogą znaleźć dla ciebie odpowiedź lub przynajmniej pomocne wskazówki: http://stackoverflow.com/questions/6045502/how-to-get-catransform3d-from-projection-and-modelview-matricesModelView-matrices – cb88

Odpowiedz

1

To chyba zrobić z konfiguracją swoich poglądów w pierwszej kolejności. Dziwne przesunięcie może być spowodowane niewłaściwą szerokością i wysokością lub dowolnymi innymi niepoprawnymi wartościami, takimi jak użycie współczynnika ekranu iPhone'a na iPadzie.

Czy krajobraz Twojej aplikacji jest odpowiedni? Jeśli tak, to daj mu portret.Zauważyłem w przeszłości, że aplikacje zawsze wydają się uruchamiać z wymiarami ekranu pionowego (nie potwierdziłem tego), więc jeśli twoja konfiguracja widoku nastąpi, zanim ekran będzie "właściwą drogą", dostaniesz niedopasowanie.

Możesz również spróbować dokładnie określić, na ile to działa. Zamiast pomnażania size.data jako hack: dodaj kolejne tłumaczenie i dostosuj numery, aż będą poprawne. Te liczby mogą dać ci lepszy wgląd w to, co się dzieje. * 10 to prawdopodobnie tylko fuks i nie znaczy nic wielkiego.

+0

To brzmi jak obiecująca droga do zejścia, dzięki. Widziałem inne problemy w aplikacji ze względu na orientację pionową/poziomą, więc przyjrzę się temu. –

+0

Wydaje mi się, że istnieje zdecydowanie inny błąd w różnych orientacjach, co może być wskazówką. To nie wszystko, ponieważ wszystko pojawia się również w innym (niewłaściwym) miejscu w orientacji portretowej. Zauważyłem, że kwota wyłączona różni się w zależności od odległości od celu, więc wygląda na ogólny problem z transformacją macierzy. –

Powiązane problemy