2016-05-29 14 views
2

Ich habe diese App, die nur in der Landschaft funktioniert.Konvertieren einer SCNVector3-Position in eine CGPoint SCNView-Koordinate?

Ich habe ein Objekt auf Scenekit. Das Objekt ist an einer bestimmten Position, angegeben durch:

SCNNode * buttonRef = [scene.rootNode childNodeWithName:@"buttonRef" recursively:YES]; 
SCNVector3 buttonRefPosition = [buttonRef position]; 

Jetzt brauche ich, dass SCNVector3-mainView 2D-Koordinaten zu konvertieren, wo

mainView = (SCNView *)self.view; 

Die Szene orthogonale Kamera verwendet, so dass keine Perspektive. Die Kamera ist die Standardkamera. Keine Drehung, keine Übersetzung. Die orthographische Skalierung der Kamera ist 5.4.

Wie konvertiere ich das?

Ich habe andere Antworten auf SO über die umgekehrte Frage gefunden, die von CGPoint zu SCNVector3 konvertiert, aber klingt nicht offensichtlich für mich, wie man das Gegenteil tut, von SCNVector3 zu CGPoint.

Wenn die SCNView eine Unterklasse von UIView ist, dann ist (0,0) der obere linke Punkt und im Fall der iPhone 6-Landschaft ist (667, 375) der untere rechte Punkt.

Dieser Knopf von mir ist fast ganz rechts und in der Mitte der Höhe. In Bezug auf die UIKit würde ich sagen, dass diese Taste ist (600, 187), aber wenn ich dies tun: (?)

SCNNode * buttonRef = [scene.rootNode childNodeWithName:@"buttonRef" recursively:YES]; 
SCNVector3 buttonRefPosition = [buttonRef position]; 

SCNVector3 projectedPoint = [mainView projectPoint: buttonRefPosition]; 

ich Project gleich (7,8, 375, 0)

und Wenn ich eine 10x10-Ansicht zu der Koordinate (7.8, 375) mit UIKit hinzufüge, bekomme ich eine Ansicht unten links !!

Wie gesagt, die App funktioniert nur im Querformat, aber diese Koordinatensysteme sind alle durcheinander.

+0

Ist die 'buttonRef' Knotengeometrie ein SceneKit Objekt (' SCNSphere', 'SCNBox ', etc) oder etwas, das in einem 3D-Modellierungswerkzeug erstellt und als Datei geladen wurde le? Alle SceneKit-Objekte haben einen Ursprung bei 0,0,0 (damit meine ich, dass das Zentrum einer Kugel bei 0,0,0 liegt), es kann sein, dass das Modell, das Sie verwenden, Geometrie hat, die nicht um 0 zentriert ist. Eine schnelle Möglichkeit zum Überprüfen besteht darin, eine kleine "SCNSphere" als untergeordnetes Element des buttonRef-Knotens hinzuzufügen und zu bestätigen, dass sie an der Stelle angezeigt wird, an der Sie den Ursprung Ihrer Geometrie vermuten. FWIW 'projectPoint' gibt erwartete 2D-Koordinaten in meiner App zurück. – lock

+0

Ihr Kommentar macht Sinn. Um zu testen, dass ich das getan habe, [scnView projectPoint: SCNVector3Zero]; 'oder mit anderen Worten, ich projiziere 0,0,0. Die Projektion gibt mir (0, 375, 0). Wie kann man 0,0,0 auf Scenekit - das ist in meinem Fall ist was genau in der Mitte der Kamera zu sehen ist (0,375,0) oder tatsächlich (0,375) auf UIKit? ... das ist ein Punkt auf der rechten Seite? – SpaceDog

+0

Guter Test, ich fügte hinzu, dass in mein Projekt, sogar auf eine orthographische Projektion umgeschaltet und immer noch einen 2D-Punkt in der Mitte meiner Sicht. Ist es möglich, dass Ihr SCNView viel größer als die Bildschirmgröße ist? Was bedeutet das Ausgeben der Rahmen/Grenzen Ihres SCNView (in didLayoutView)? Wenn Ihre Ansicht doppelt so groß ist wie der Bildschirm und die linke Hälfte nicht sichtbar ist, würde das die Zahlen erklären, die Sie erhalten. – lock

Antwort

2

Das Konvertieren von Modellraumpunkten zu Bildschirmraumpunkten wird als Projizieren bezeichnet (weil es die Projektionstransformation der Kamera anwendet, um von einem 3D-Raum in einen 2D-Raum zu mappen). Der Renderer (über die GPU) tut es viele, viele Male pro Frame, um die Punkte in Ihrer Szene auf den Bildschirm zu bekommen.

Es gibt auch eine bequeme Methode, um, wenn Sie müssen es selbst tun: projectPoint:

+0

Ich habe weitere Informationen hinzugefügt. – SpaceDog

+0

Was ist das Gegenteil davon? Vom Bildschirm in das szenebasierte (ich denke) Kameraprojekt. Soll ich dafür eine andere Frage starten? – Confused

+0

Oder schauen Sie sich den Link an. Das gleiche Protokoll, das "Projekt" hat, könnte auch etwas haben, das wie ein Gegenteil klingt ... – rickster

0

Ganz alte Frage, aber leider @ricksters Antwort war keine wirkliche Hilfe für mich, als Project: Ansicht Koordinaten vermasselt hält Liefern in meinem Fall auch (das selbe Problem wie @SpaceDog beschrieben)!

Allerdings fand ich, dass in mein Fall das Problem war, dass ich eine Transformation auf meinen Wurzelknoten angewendet hatte (drehte die Welt auf den Kopf ;-)). Dies führt offensichtlich zu den falschen Ergebnissen von Project: ...

Da ich nicht die Transformation entfernen konnte, musste ich meine Eingabe an Project anzupassen: entsprechend.

SCNVector3 viewStartPosition = ...; // Some place in the scene 
SCNVector3 viewStartPositionRel = SCNVector3FromSCNVector4(SCNMatrix4MultV(self.scene.rootNode.worldTransform, SCNVector4FromSCNVector3(viewStartPosition))); 
// Vector from UISceneView 0/0 top/left to start point 
SCNVector3 viewStartPositionInViewCoords = [self.sceneView projectPoint:viewStartPositionRel]; 

Leider liefert Apple keine Matrix Mathematik für SCNMatrix4 Matrizen, so dass die verwendeten (einfach) Matrix Handhabung Methoden sind auch 'hausgemacht':

/* 
SCNVector4FromSCNVector3 

*/ 
SCNVector4 SCNVector4FromSCNVector3(SCNVector3 pV) { 
    return SCNVector4Make(pV.x, pV.y, pV.z, 0.0); 
} 

/* 
SCNVector3FromSCNVector4 

*/ 
SCNVector3 SCNVector3FromSCNVector4(SCNVector4 pV) { 
    return SCNVector3Make(pV.x, pV.y, pV.z); 
} 

/* 
SCNMatrix4MultV 

*/ 
SCNVector4 SCNMatrix4MultV(SCNMatrix4 pM, SCNVector4 pV) { 
    SCNVector4 r = { 
     pM.m11 * pV.x + pM.m12 * pV.y + pM.m13 * pV.z + pM.m14 * pV.w, 
     pM.m21 * pV.x + pM.m22 * pV.y + pM.m23 * pV.z + pM.m24 * pV.w, 
     pM.m31 * pV.x + pM.m32 * pV.y + pM.m33 * pV.z + pM.m34 * pV.w, 
     pM.m41 * pV.x + pM.m42 * pV.y + pM.m43 * pV.z + pM.m44 * pV.w 
    }; 
    return r; 
} 

Ich habe keine Ahnung, wenn Dies ist ein Fehler in SceneKit, oder wenn es vielleicht verboten ist, Transformationen auf den rootNode anzuwenden ... Wie auch immer: Problem gelöst :-)