2014-06-23 7 views
5

Ist es möglich, SceneKits unprojectPoint zu verwenden, um einen 2D-Punkt in 3D zu konvertieren, ohne einen Tiefenwert zu haben? Ich muss nur die 3D-Position in der XZ-Ebene finden. Y kann immer 0 oder ein beliebiger Wert sein, da ich es nicht verwende.Wie konvertiert man den 2D-Punkt mit dem unprojectPoint von SceneKit in 3D, ohne einen Tiefenwert zu haben?

Ich versuche dies für iOS 8 Beta zu tun.

hatte ich etwas ähnliches mit JavaScript und Three.js (WebGL) wie folgt aus:

function getMouse3D(x, y) { 
    var pos = new THREE.Vector3(0, 0, 0); 
    var pMouse = new THREE.Vector3(
     (x/renderer.domElement.width) * 2 - 1, 
     -(y/renderer.domElement.height) * 2 + 1, 
     1 
    ); 
    // 
    projector.unprojectVector(pMouse, camera); 

    var cam = camera.position; 
    var m = pMouse.y/(pMouse.y - cam.y); 

    pos.x = pMouse.x + (cam.x - pMouse.x) * m; 
    pos.z = pMouse.z + (cam.z - pMouse.z) * m; 

    return pos; 
}; 

Aber ich weiß nicht, wie das Teil mit unprojectVector zu SceneKit übersetzen.


Was ich tun möchte, ist in der Lage, ein Objekt nur in der XZ-Ebene zu ziehen. Die vertikale Achse Y wird ignoriert.

Da sich das Objekt entlang einer Ebene bewegen müsste, wäre eine Lösung die hitTest-Methode, aber ich denke nicht, dass es in Bezug auf die Leistung für jedes Touch/Drag-Ereignis sehr gut ist. Außerdem würde es dem Objekt nicht erlauben, sich außerhalb der Ebene zu bewegen.

Ich habe eine Lösung basierend auf der angenommenen Antwort here versucht, aber es hat nicht funktioniert. Wird ein Objekt mit einem Tiefenwert für unprojectPoint gezogen, so bleibt das Objekt nicht in der +/- Z-Richtung. Es bleibt nicht zu lange unter dem Finger, sondern entfernt sich von ihm. Ich muss das gezogene Objekt unter dem Finger bleiben, egal wohin es in der XZ-Ebene bewegt wird.

Antwort

2

Erstens, suchen Sie tatsächlich nach einer Position in der XZ-Ebene oder der XY-Ebene? Standardmäßig sieht die Kamera in der -z-Richtung aus, sodass die x- und y-Achsen des 3D-Szenen-Kit-Koordinatensystems in die gleiche Richtung verlaufen wie im Koordinatensystem der 2D-Ansicht. (Nun, y ist standardmäßig in UIKit umgedreht, aber es ist immer noch die vertikale Achse.) Die xz-Ebene ist dann orthogonal zur Ebene des Bildschirms.

Zweitens ist ein Tiefenwert ein notwendiger Teil der Konvertierung von 2D nach 3D. Ich bin kein Experte für three.js, aber von ihrem library documentation (der offenbar nicht in verknüpft werden kann), ihre unprojectVector nimmt immer noch eine Vector3. Und das ist, was Sie oben für pMouse in Ihrem Code sind konstruieren - ein Vektor, dessen z- und y-Koordinaten kommen aus der 2D-Mausposition und deren z-Koordinate 1.

SceneKit der unprojectPoint die gleiche Art und Weise funktioniert - es nimmt einen Punkt, dessen Z-Koordinate sich auf eine Tiefe in clip space bezieht, und bildet dies auf einen Punkt im Weltbereich Ihrer Szene ab.

Wenn Ihr Weltbereich so ausgerichtet ist, dass die einzige Abweichung, die Ihnen wichtig ist, in den x- und y-Achsen liegt, können Sie den gewünschten z-Wert unprojectPoint übergeben und den z-Wert im Vektor ignorieren Komm zurück. Andernfalls übergeben Sie -1, um auf die ferne Clipping-Ebene, 1 für die nahe Clipping-Ebene, oder 0 für die Hälfte dazwischen - die Ebene, deren z-Koordinate (im Kameraraum) ist 0. Wenn Sie den unprojizierten Punkt zum Positionieren eines Knotens in der Szene verwenden, empfiehlt es sich, einfach verschiedene z-Werte (zwischen -1 und 1) auszuprobieren, bis Sie das gewünschte Verhalten erhalten.

Es ist jedoch eine gute Idee, darüber nachzudenken, wofür Sie einen nicht projizierten Vektor verwenden - wenn Sie als nächstes mit Kreuzungen mit Szenengeometrie testen würden, schauen Sie sich stattdessen hitTest: an.

+0

Bitte schauen Sie auf meine Antwort, um zu sehen, was ich versuche zu tun. – CAM