Raycaster 无法检测立方体
Raycaster fails to detect Cubes
如何将一个正方形和一个长方形组合成一个对象,使 Raycaster
可以成功检测到?
我创建了一个自定义的“树”对象,方法是制作一个“树干”——它只是一个长方形,然后将一个方形对象粘贴在该树干的顶部。
然后,我将那棵树“种”在一个球体之上,并试图让我的 raycaster
检测到它。
没用。
这是我的代码:
// My custom “Tree” Object:
var Tree = function(treeColor) {
this.mesh = new THREE.Object3D();
this.mesh.name = "tree";
// I start with the TRUNK - which is just an elongated Cube - meaning a Rectangle:
var trunkGeometry = new THREE.CubeGeometry(0.2, 0.5, 0.2);
var trunkMaterial = new THREE.MeshBasicMaterial({ color: "blue", wireframe: false });
var treeTrunk = new THREE.Mesh(trunkGeometry, trunkMaterial);
treeTrunk.position.set(0, 0, 0);
treeTrunk.rotation.x = -Math.PI * 0.5;
this.mesh.add(treeTrunk);
// Then I create the FOLIAGE - which is just a regular Cube:
var foliageGeometry = new THREE.CubeGeometry(0.5, 0.5, 0.5);
var foliageMaterial = new THREE.MeshBasicMaterial({ color: treeColor, wireframe: false });
var treeFoliage = new THREE.Mesh(foliageGeometry, foliageMaterial);
treeFoliage.position.set(0, 0.5, 0);
// And then I attach/add the FOLIAGE to the TRUNK:
treeTrunk.add(treeFoliage);
}
// Next I make a basic Sphere:
theSun = new THREE.Mesh(new THREE.SphereGeometry(3, 32, 24), new THREE.MeshBasicMaterial( {color: "white", wireframe: false} ));
scene.add(theSun);
// And then I make a Tree and add it to my Sphere (`theSun`):
var oneTree = new Tree("red");
let rx = Math.random() * Math.PI * 2;
let ry = Math.random() * Math.PI;
oneTree.mesh.position.setFromSphericalCoords(3.2, ry, rx);
oneTree.mesh.lookAt(theSun.position);
theSun.add(oneTree.mesh);
// Next I add both theSun and the Tree to my “objectsForRayCasterArray” - a global var I use in my raycaster test:
objectsForRayCasterArray.push(oneTree);
objectsForRayCasterArray.push(theSun);
// In my render() function, I do the usual raycasting business:
rayCaster = new THREE.Raycaster();
function render() {
requestAnimationFrame(render);
controls.update();
renderer.render(scene, camera);
// Raycasting stuff:
rayCaster.setFromCamera(mousePosition, camera);
var intersectingObjectsArray = rayCaster.intersectObjects(objectsForRayCasterArray);
if (intersectingObjectsArray.length > 0) {
if (intersectedObject != intersectingObjectsArray[0].object) {
console.log(“Intersected!”);
}
}
注意:当我使用相同的代码而不是 Tree
时,我只是在我的 Sphere
对象上放置了一个常规的 Cube
,一切正常。 raycaster
检测到 Cube
并触发 Alert
。
我最好的猜测是,由于您将 treeFoliage
嵌套在 treeTrunk
内,并且将 mesh
嵌套在 mesh
内,您将不得不使用递归相交测试。
根据文档,intersectObjects()
accepts a second argument 执行递归 hit-test。这意味着它将遍历所有后代,而不是仅仅对 top-level 个对象进行浅层检查:
rayCaster.intersectObjects(objectsForRayCasterArray, true);
如何将一个正方形和一个长方形组合成一个对象,使 Raycaster
可以成功检测到?
我创建了一个自定义的“树”对象,方法是制作一个“树干”——它只是一个长方形,然后将一个方形对象粘贴在该树干的顶部。
然后,我将那棵树“种”在一个球体之上,并试图让我的 raycaster
检测到它。
没用。
这是我的代码:
// My custom “Tree” Object:
var Tree = function(treeColor) {
this.mesh = new THREE.Object3D();
this.mesh.name = "tree";
// I start with the TRUNK - which is just an elongated Cube - meaning a Rectangle:
var trunkGeometry = new THREE.CubeGeometry(0.2, 0.5, 0.2);
var trunkMaterial = new THREE.MeshBasicMaterial({ color: "blue", wireframe: false });
var treeTrunk = new THREE.Mesh(trunkGeometry, trunkMaterial);
treeTrunk.position.set(0, 0, 0);
treeTrunk.rotation.x = -Math.PI * 0.5;
this.mesh.add(treeTrunk);
// Then I create the FOLIAGE - which is just a regular Cube:
var foliageGeometry = new THREE.CubeGeometry(0.5, 0.5, 0.5);
var foliageMaterial = new THREE.MeshBasicMaterial({ color: treeColor, wireframe: false });
var treeFoliage = new THREE.Mesh(foliageGeometry, foliageMaterial);
treeFoliage.position.set(0, 0.5, 0);
// And then I attach/add the FOLIAGE to the TRUNK:
treeTrunk.add(treeFoliage);
}
// Next I make a basic Sphere:
theSun = new THREE.Mesh(new THREE.SphereGeometry(3, 32, 24), new THREE.MeshBasicMaterial( {color: "white", wireframe: false} ));
scene.add(theSun);
// And then I make a Tree and add it to my Sphere (`theSun`):
var oneTree = new Tree("red");
let rx = Math.random() * Math.PI * 2;
let ry = Math.random() * Math.PI;
oneTree.mesh.position.setFromSphericalCoords(3.2, ry, rx);
oneTree.mesh.lookAt(theSun.position);
theSun.add(oneTree.mesh);
// Next I add both theSun and the Tree to my “objectsForRayCasterArray” - a global var I use in my raycaster test:
objectsForRayCasterArray.push(oneTree);
objectsForRayCasterArray.push(theSun);
// In my render() function, I do the usual raycasting business:
rayCaster = new THREE.Raycaster();
function render() {
requestAnimationFrame(render);
controls.update();
renderer.render(scene, camera);
// Raycasting stuff:
rayCaster.setFromCamera(mousePosition, camera);
var intersectingObjectsArray = rayCaster.intersectObjects(objectsForRayCasterArray);
if (intersectingObjectsArray.length > 0) {
if (intersectedObject != intersectingObjectsArray[0].object) {
console.log(“Intersected!”);
}
}
注意:当我使用相同的代码而不是 Tree
时,我只是在我的 Sphere
对象上放置了一个常规的 Cube
,一切正常。 raycaster
检测到 Cube
并触发 Alert
。
我最好的猜测是,由于您将 treeFoliage
嵌套在 treeTrunk
内,并且将 mesh
嵌套在 mesh
内,您将不得不使用递归相交测试。
根据文档,intersectObjects()
accepts a second argument 执行递归 hit-test。这意味着它将遍历所有后代,而不是仅仅对 top-level 个对象进行浅层检查:
rayCaster.intersectObjects(objectsForRayCasterArray, true);