2017-09-06 8 views
0

の空の配列を持っている:私は上をクリックする何キューブユーザー知りたいhttps://threejs.org/examples/?q=pano#webgl_panorama_equirectangularThree.js:レイキャストは私のWebGLパノラマキューブのため、この例を使用していますと交差する

と私は、このためにRaycasterを使用することができます発見しました。

function onMouseDown(event) { 
     event.preventDefault(); 

     var mouseVector = new THREE.Vector3(
      (event.clientX/window.innerWidth) * 2 - 1, 
      - (event.clientY/window.innerHeight) * 2 + 1, 
      1); 

     //projector.unprojectVector(mouseVector, camera); 
     mouseVector.unproject(camera); 
     var raycaster = new THREE.Raycaster(camera.position, mouseVector.sub(camera.position).normalize()); 

     // create an array containing all objects in the scene with which the ray intersects 
     var intersects = raycaster.intersectObjects(scene.children); 
     console.log(intersects); 
     if (intersects.length>0){ 
      console.log("Intersected object:", intersects.length); 
      intersects[ 0 ].object.material.color.setHex(Math.random() * 0xffffff); 
     } 
     // ... 

しかしintersectsは常に空です:ドキュメントによると、私は次の関数を追加しました。私のシーンは

scene = new THREE.Scene(); 

として定義され、スカイボックスが追加されました:私は、この問題に関連した同様の記事を見てきましたが、この例に適用する方法を見つけ出すことができませんでした

var skyBox = new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), materials); 
skyBox.applyMatrix(new THREE.Matrix4().makeScale(1, 1, - 1)); 
scene.add(skyBox); 

。いずれの方向も高く評価されています。あなたの材料の定義にこれを追加すること

答えて

1

試してみてください。sideプロパティがTHREE.BackSideまたはTHREE.DoubleSideに設定されていない限り

var materials = new THREE.SomeMaterial({ 
    /* other settings */, 
    side: THREE.DoubleSide 
}); 

Raycasterは、バックフェースと交差しています。スケーリングがテクニカルに顔の向きを逆転させても、頂点の順序は変わらないので、Raycasterにとって重要です。

いくつかのさらなる説明

以下スニペットは-Zスケールで反転スカイボックスの中心にカメラから投影光線がどのように見えるか示しています。

ボックス自体が変わってしまっています。これは、-Z倍精度であり、法線がマテリアルに一致しないためです。しかし、そこにもそこにはありません。

緑色の矢印は元の光線を表します。赤い矢印は、Mesh.raycast関数内でそのレイに何が起こるかを表します。これはオブジェクトのワールドマトリックスの逆行列をレイに適用しますが、オブジェクトのジオメトリには適用しません。これはまったく別の問題です。

Mesh.raycastの中では、頂点/インデックスの順番に影響しないので、メッシュの三角形をチェックすると、元の順序になります。標準BoxGeometry/BoxBufferGeometryの場合、これは面がすべて幾何学的起点から外向きに向いていることを意味します。

これは、(変換行列がどのように影響するかにかかわらず)光線がまだそれらの三角形の背面​​を交差しようとしていることを意味し、材料がTHREE.DoubleSideに設定されていなければ動作しません。 (それはまたTHREE.BackSideに設定することができますが、-Z規模はそれを台無しにされます。)-ZスケールボックスはTHREE.DoubleSide(デフォルト)に設定されていない場合は0交差を生産するレイキャストのいずれかのボタンをクリックする

。 "Set THREE.DoubleSide"ボタンをクリックしてもう一度試してみてください。今度は交差します。

var renderer, scene, camera, controls, stats; 
 

 
var WIDTH = window.innerWidth, 
 
\t HEIGHT = window.innerHeight, 
 
\t FOV = 35, 
 
\t NEAR = 1, 
 
\t FAR = 1000, 
 
    ray1, ray2, mesh; 
 

 
function populateScene(){ 
 
\t var cubeGeo = new THREE.BoxBufferGeometry(10, 10, 10), 
 
\t \t cubeMat = new THREE.MeshPhongMaterial({ color: "red", transparent: true, opacity: 0.5 }); 
 
\t mesh = new THREE.Mesh(cubeGeo, cubeMat); 
 
    mesh.applyMatrix(new THREE.Matrix4().makeScale(1, 1, -1)); 
 
    mesh.updateMatrixWorld(true); 
 
\t scene.add(mesh); 
 
    
 
    var dir = new THREE.Vector3(0.5, 0.5, 1); 
 
    dir.normalize(); 
 
    ray1 = new THREE.Ray(new THREE.Vector3(), dir); 
 
    
 
    var arrow1 = new THREE.ArrowHelper(ray1.direction, ray1.origin, 20, 0x00ff00); 
 
    scene.add(arrow1); 
 
    
 
    var inverseMatrix = new THREE.Matrix4(); 
 
    inverseMatrix.getInverse(mesh.matrixWorld); 
 
    
 
    ray2 = ray1.clone(); 
 
    ray2.applyMatrix4(inverseMatrix); 
 
    
 
    var arrow2 = new THREE.ArrowHelper(ray2.direction, ray2.origin, 20, 0xff0000); 
 
    scene.add(arrow2); 
 
} 
 

 
function init() { 
 
\t document.body.style.backgroundColor = "slateGray"; 
 

 
\t renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); 
 

 
\t document.body.appendChild(renderer.domElement); 
 
\t document.body.style.overflow = "hidden"; 
 
\t document.body.style.margin = "0"; 
 
\t document.body.style.padding = "0"; 
 

 
\t scene = new THREE.Scene(); 
 

 
\t camera = new THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, NEAR, FAR); 
 
\t camera.position.z = 50; 
 
\t scene.add(camera); 
 

 
\t controls = new THREE.TrackballControls(camera, renderer.domElement); 
 
\t controls.dynamicDampingFactor = 0.5; 
 
\t controls.rotateSpeed = 3; 
 

 
\t var light = new THREE.PointLight(0xffffff, 1, Infinity); 
 
\t camera.add(light); 
 

 
\t stats = new Stats(); 
 
\t stats.domElement.style.position = 'absolute'; 
 
\t stats.domElement.style.top = '0'; 
 
\t document.body.appendChild(stats.domElement); 
 

 
\t resize(); 
 
\t window.onresize = resize; 
 

 
\t populateScene(); 
 

 
\t animate(); 
 
    
 
    var rayCaster = new THREE.Raycaster(); 
 
    document.getElementById("greenCast").addEventListener("click", function(){ 
 
    rayCaster.ray.copy(ray1); 
 
    alert(rayCaster.intersectObject(mesh).length + " intersections!"); 
 
    }); 
 
    document.getElementById("redCast").addEventListener("click", function(){ 
 
    rayCaster.ray.copy(ray2); 
 
    alert(rayCaster.intersectObject(mesh).length + " intersections!"); 
 
    }); 
 
    document.getElementById("setSide").addEventListener("click", function(){ 
 
    mesh.material.side = THREE.DoubleSide; 
 
    mesh.material.needsUpdate = true; 
 
    }); 
 
} 
 

 
function resize() { 
 
\t WIDTH = window.innerWidth; 
 
\t HEIGHT = window.innerHeight; 
 
\t if (renderer && camera && controls) { 
 
\t \t renderer.setSize(WIDTH, HEIGHT); 
 
\t \t camera.aspect = WIDTH/HEIGHT; 
 
\t \t camera.updateProjectionMatrix(); 
 
\t \t controls.handleResize(); 
 
\t } 
 
} 
 

 
function render() { 
 
\t renderer.render(scene, camera); 
 
} 
 

 
function animate() { 
 
\t requestAnimationFrame(animate); 
 
\t render(); 
 
\t controls.update(); 
 
\t stats.update(); 
 
} 
 

 
function threeReady() { 
 
\t init(); 
 
} 
 

 
(function() { 
 
\t function addScript(url, callback) { 
 
\t \t callback = callback || function() { }; 
 
\t \t var script = document.createElement("script"); 
 
\t \t script.addEventListener("load", callback); 
 
\t \t script.setAttribute("src", url); 
 
\t \t document.head.appendChild(script); 
 
\t } 
 

 
\t addScript("https://threejs.org/build/three.js", function() { 
 
\t \t addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() { 
 
\t \t \t addScript("https://threejs.org/examples/js/libs/stats.min.js", function() { 
 
\t \t \t \t threeReady(); 
 
\t \t \t }) 
 
\t \t }) 
 
\t }) 
 
})();
body{ 
 
    text-align: center; 
 
}
<input id="greenCast" type="button" value="Cast Green"> 
 
<input id="redCast" type="button" value="Cast Red"> 
 
<input id="setSide" type="button" value="Set THREE.DoubleSide">

+0

このソリューションでは、働いていました! – Vad

0

あなたが実際にカメラからあなたの線を決定するために簡単にプロセスを使用することがあります:

THREE.Raycaster.prototype.setFromCamera(Vector2, Camera); 

あなたがVector2にそうであるようにするだけで、その後、あなたのマウスの座標を定義要素をRaycasterに渡して、その要素を実行させます。それは、カメラからの光線と柱頭との交差の複雑さを隠し、あなたの問題を解決するはずです。

(もちろん、レイキャスターは光線に直接向き合う面を交差させますが、スカイボックスが逆さまになっているため、ジオメトリの面がボックスの内側を指しているため、カメラがボックスの内側にある場合は交差する必要があります。別の可能性は、あなたのボックスは遠くraycastersのデフォルトfar値よりもあるということである。)

function onMouseDown(event) { 
 

 
    event.preventDefault(); 
 

 
    var mouseVector = new THREE.Vector2(
 
     event.clientX/window.innerWidth * 2 - 1, 
 
     -event.clientY/window.innerHeight * 2 + 1 
 
    ); 
 

 
    var raycaster = new THREE.Raycaster; 
 
    raycaster.setFromCamera(mouseVector, camera); 
 

 
    var intersects = raycaster.intersectObjects(scene.children); 
 
     
 
    console.log(intersects); 
 
     
 
    if(intersects.length > 0){ 
 

 
     console.log("Intersected object:", intersects[ 0 ]); 
 
     intersects[ 0 ].object.material.color.setHex(Math.random() * 0xffffff); 
 

 
    } 
 

 
}

+1

FWIW、 'Raycaster.far'のデフォルトは' Infinity'です。問題はありません。 :) – TheJim01

+0

おかげで@何か、あなたの答えはまた私が理解するのを助けた – Vad

関連する問題