2016-06-08 9 views
0

Ich versuche ein sehr kleines Werkzeug in WebGL zu schreiben, das mir erlaubt, in UV'ed Meshes zu malen. Eine der Herausforderungen besteht darin, einen Weg zu finden, die Position der Maus in die Position zu bringen, die ich in der geladenen Textur malen soll. Hat jemand ein Beispiel oder kann ich dazu Literatur empfehlen?Übersetzen 3D-Pick in Textur Projektion?

Antwort

2

Der "Trick", den Sie suchen, ist wahrscheinlich THREE.Raycaster.setFromCamera().das macht eine einfache Version von dem, was ich denke, du versuchst zu tun. Er rendert eine einfache Szene mit einer texturierten Kugel in einer Leinwand und legt eine Kopie der auf die Kugel angewendeten Textur in einer anderen Leinwand ab. Durch Klicken auf die Kugel wird ein roter Punkt an der entsprechenden Stelle der Textur in der zweiten Leinwand gezeichnet.

Die interessanten Punkte sind:

In init() wir einen Klick Hander zum Rendern Leinwand definieren, genannt clickCanvas. Es gibt die x- und y-Koordinaten des Klick-Ereignis zu getClickPosition():

function getClickPosition(n, x, y) { 
     var rect; 

     rect = n.getBoundingClientRect(); 
     return([ 
       (x - rect.left)/n.clientWidth, 
       (y - rect.top)/n.clientHeight 
     ]); 
} 

Dies übersetzt die x und y-Koordinaten zu einer UV-isch geordnetes Paar von Werten zwischen 0 und 1. Diese Werte übergeben werden, zu projectLocation():

function projectLocation(x, y) { 
     var c, i, v, p; 

     // Bounds check our coords 
     if(x < 0) x = 0; 
     if(x > 1) x = 1; 
     if(y < 0) y = 0; 
     if(y > 1) y = 1; 

     // Convert our values from the range [0, 1] to the range [-1, 1] 
     v = new THREE.Vector2(); 
     v.x = x * 2 - 1; 
     v.y = (-y * 2) + 1; 

     raycaster.setFromCamera(v, camera); 
     i = raycaster.intersectObjects(scene.children, true); 
     if(i.length > 0) { 
       getLocation(i[0]); 
     } 
} 

Diese die UV-isch Koordinaten nimmt und wandelt sie in Werte zwischen -1 und 1, das ist, was der THREE.Raycaster() möchte (in diesem Beispiel wäre es sauberer haben getClickPosition() tun dies automatisch, aber in realen Code möchten Sie vielleicht die relative Position des Klicks im DOM-Element). Der Rajaster findet heraus, ob irgendetwas einen Strahl schneidet, der von der Stelle, an der der Klick aufgetreten ist (auf das "Kameraobjektiv"), in die Szene projiziert wird. Von dort wird das Kreuzungsobjekt (falls vorhanden) zu getLocation() übergibt:

function getLocation(intersect) { 
     var uv; 

     uv = intersect.uv; 
     x = Math.round(uv.x * texture.image.width); 
     y = Math.round((1 - uv.y) * texture.image.height); 

     canvasCtx.lineWidth = 1; 
     canvasCtx.fillStyle = 'red'; 
     canvasCtx.fillRect(x - 1, y - 1, 2, 2); 
     canvasCtx.fill(); 
} 

Der Schnitt Objekt enthält die UV-Koordinaten des Schnittpunktes. getLocation() übersetzt diese in XY-Koordinaten in der Textur.