2017-02-15 3 views
0

Was ich erreichen möchte, ist ein Laserstrahl, der 2 Punkte im Raum verbindet.ThreeJS Object 3d connect 2 Punkte

Ich dachte, dass vielleicht durch das Rendern einer lineGeometry und das Anhängen von 6 auf der x-Achse gedrehten Ebenen den Trick machen, aber es scheint, dass es komplizierter ist. Diese

ist, wie ich den Laserstrahl erzeugen, so weit so gut

window.lazor = new THREE.Object3D(); 
     var material = new THREE.MeshBasicMaterial({ 
      blending : THREE.AdditiveBlending, 
      color  : 0x4444aa, 
      side  : THREE.DoubleSide, 
      depthWrite : false, 
      transparent : true 
     }) 
     var geometry = new THREE.PlaneBufferGeometry(100, 0.1) 
     var nPlanes = 3; 
     for(var i = 0; i < nPlanes; i++){ 
      var mesh = new THREE.Mesh(geometry, material) 
      mesh.rotation.x = i/nPlanes * Math.PI 
      lazor.add(mesh); 
     } 

     window.lazor.rotation.y = Math.PI/2 

Was in ich suche ist an beiden Enden der object3D auf 2 Punkte (vec3) zu machen.

Liniengeometrie scheint den Trick zu machen (Länge wird immer gleich dem Abstand zwischen den 2 Punkten sein), durch Aktualisieren der zweiten Ecke zum Vector3 muss sie sich mit jedem Frame verbinden, aber ich bin nicht sicher was Ansatz sollte ich mit dem `Object3D 'machen (Ich bin mir nicht sicher, wie ich herausfinden soll, wo sich jedes Ende des Object3D befindet)

Antwort

1

Sie möchten eine Ebene erstellen, die sich über zwei 3D-Punkte erstreckt.

Die Lösung besteht darin, eine PlaneBufferGeometry zu erstellen und die Geometrie so zu transformieren, dass ein Ende im Ursprung liegt und die Geometrie mit der positiven z-Achse ausgerichtet ist.

in Ihrem Fall also, Ihre Laser zu schaffen, würden Sie so etwas tun:

// material 
var material = new THREE.MeshBasicMaterial({ 

    blending : THREE.AdditiveBlending, 
    color  : 0x4444aa, 
    side  : THREE.DoubleSide, 
    depthWrite : false, 
    transparent : true 

}); 

// geometry 
var geometry = new THREE.PlaneBufferGeometry(1, 100); 
geometry.rotateX(- Math.PI/2); // so it aligns with the z-axis 
geometry.translate(0, 0, 50); // so one end is at the origin 

// laser 
laser = new THREE.Object3D(); 
laser.position.set(10, 10, 10); 
scene.add(laser); 

var nPlanes = 3; 

for(var i = 0; i < nPlanes; i++){ 

    var mesh = new THREE.Mesh(geometry, material); 

    mesh.rotation.z = i/nPlanes * Math.PI; // rotate around z-axis 

    laser.add(mesh); 

} 

// laser target 
target = new THREE.Object3D(); // or some character in the scene 
target.position.set(200, 200, 200); // or wherever it happens to be 

Dann in der Schleife machen

laser.lookAt(target.position); 

Das einzige, was ein Problem sein kann, ist der Laser muss ein Kind der Szene direkt sein, weil lookAt() in diesem Sinne begrenzt ist.

Wenn Sie die Länge des Lasers dynamisch ändern, ist die einfachste Sache zu tun, dies zu tun:

laser.scale.z = 2; 

three.js r.84

+0

Tatsächlich zielen Kind Teil einer ist Gruppe, die leider nicht entfernt werden kann, da sie sich je nach der Zielposition des Spielers bewegen soll, dies soll Gleitkommafehler an riesigen Koordinaten beheben –

+0

Denken Sie über meine Antwort für mehr als 5 Minuten nach, bevor Sie sie ablehnen. Das Ziel ist das Objekt, auf das der Laser zeigt. Außerdem hat three.js r85dev das Problem der großen Koordinaten gemildert. – WestLangley

+0

Ich habe den Code implementiert und es geschafft, den Strahl genau dort auszurichten, wo ich es brauchte, indem ich die Matrixworld des Ziels erhielt. Wusste nicht über die Gleitkomma-Korrektur in R85 ​​(was super ist). Aber alles funktioniert gut und glatt .. dachte, dass Vec3.lookAt (x, y, z) könnte eine teure Operation zu verwenden, aber bis jetzt funktioniert es wie ein Charme –