ThreeJS - 如何只选择一种类型的对象?
ThreeJS - how to pick just one type of objects?
我是 ThreeJS 的新手,我在通过光线投射拾取对象时遇到问题。我创建了一些球体和一些线,但只想在鼠标悬停时更改球体。我想我需要在光线投射代码中添加一些条件,但我不知道是什么...
这是我的代码,希望大家能帮忙:
这将创建对象:
var numSpheres = 10;
var angRand = [numSpheres];
var spread = 10;
var radius = windowY/5;
var radiusControl = 20;
//sphere
var sphereGeometry = new THREE.SphereGeometry(0.35, 100, 100);
//line
var lineGeometry = new THREE.Geometry();
var lineMaterial = new THREE.LineBasicMaterial({
color: 0xCCCCCC
});
//create dynamically
for (var i = 0; i < numSpheres; i++) {
var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x334455});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
var line = new THREE.Line(lineGeometry, lineMaterial);
angRand[i] = Math.floor((Math.random() * 360) + 1);//random angle for each sphere/line
var radiusIncr = spread * (angRand[i]+200)/180;
var xPos = Math.cos((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
var yPos = Math.sin((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
var offsetY = Math.floor((Math.random()*5)+1);
sphere.position.x = xPos/radiusControl;
sphere.position.y = yPos/radiusControl + offsetY;
lineGeometry.vertices.push(
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(sphere.position.x, sphere.position.y, 0)
);
scene.add(sphere);
scene.add(line);
}
这是我的光线投射:
var mouse = {
x: 0,
y: 0
},
INTERSECTED;
window.addEventListener('mousemove', onMouseMove, false);
window.requestAnimationFrame(render);
function onMouseMove(event) {
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components
//event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
//console.log(mouse.x + " | " + mouse.y);
}
function mousePos() {
// find intersections
// create a Ray with origin at the mouse position
// and direction into the scene (camera direction)
var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
vector.unproject(camera);
var ray = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
ray.linePrecision = 1;
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects(scene.children, true);
//console.log(intersects.length);
// INTERSECTED = the object in the scene currently closest to the camera
// and intersected by the Ray projected from the mouse position
// if there is one (or more) intersections
if (intersects.length > 0) {
// if the closest object intersected is not the currently stored intersection object
if (intersects[0].object != INTERSECTED) {
// restore previous intersection object (if it exists) to its original color
if (INTERSECTED)
INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
// store reference to closest object as current intersection object
INTERSECTED = intersects[0].object;
// store color of closest object (for later restoration)
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// set a new color for closest object
INTERSECTED.material.color.setHex(0xEE7F00);
//INTERSECTED.radius.set( 1, 2, 2 );
}
} else // there are no intersections
{
// restore previous intersection object (if it exists) to its original color
if (INTERSECTED)
INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
//INTERSECTED.scale.set( 1, 1, 1 );
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
}
}
光线投射 returns 对象的相交数组,它本身包含有关光线命中的信息。
因为你只有球体和线,你可以在几何类型 intersects[0].object.geometry.type
上分支,它可以是 'LineGeometry'
或 'SphereGeometry'
.
编辑: 必需的 jsfiddle,请参阅控制台以获取命中输出。
http://jsfiddle.net/z43hjqm9/1/
为了简化鼠标操作,您可以使用 class EventsControls。尝试通过这个 example.
<script src="js/controls/EventsControls.js"></script>
EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.attachEvent('mouseOver', function() {
this.container.style.cursor = 'pointer';
this.mouseOvered.material = selMaterial;
...
});
EventsControls.attachEvent('mouseOut', function() {
this.container.style.cursor = 'auto';
this.mouseOvered.material = autoMaterial;
...
});
//
function render() {
EventsControls.update();
controls.update();
renderer.render(scene, camera);
}
在您的代码中,
var intersects = ray.intersectObjects(scene.children, true);
调用的第一个参数是一个对象,将对其进行评估以查看它或其任何后代(递归为真)是否与射线相交。
因此,只需创建一个对象目标并将球体添加到其中(而不是线条)。
这将使您的通话也更加有效
1.use不同的数组放置不同的对象
a.for 所有 objectType1,在 scene.add(objectType1)-> 做 array1.push(objectType1)
之后
b.for 所有 objectType 2,在 scene.add(objectType2)-> 做 array2.push(objectType2)
之后
现在,无论您想交互哪种类型的对象,都将该数组传递给 intersect as-
var intersects = raycaster.intersectObjects( arrayType1,true);
现在只有 arrayType1 对象会交互。
我是 ThreeJS 的新手,我在通过光线投射拾取对象时遇到问题。我创建了一些球体和一些线,但只想在鼠标悬停时更改球体。我想我需要在光线投射代码中添加一些条件,但我不知道是什么...
这是我的代码,希望大家能帮忙:
这将创建对象:
var numSpheres = 10;
var angRand = [numSpheres];
var spread = 10;
var radius = windowY/5;
var radiusControl = 20;
//sphere
var sphereGeometry = new THREE.SphereGeometry(0.35, 100, 100);
//line
var lineGeometry = new THREE.Geometry();
var lineMaterial = new THREE.LineBasicMaterial({
color: 0xCCCCCC
});
//create dynamically
for (var i = 0; i < numSpheres; i++) {
var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x334455});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
var line = new THREE.Line(lineGeometry, lineMaterial);
angRand[i] = Math.floor((Math.random() * 360) + 1);//random angle for each sphere/line
var radiusIncr = spread * (angRand[i]+200)/180;
var xPos = Math.cos((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
var yPos = Math.sin((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
var offsetY = Math.floor((Math.random()*5)+1);
sphere.position.x = xPos/radiusControl;
sphere.position.y = yPos/radiusControl + offsetY;
lineGeometry.vertices.push(
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(sphere.position.x, sphere.position.y, 0)
);
scene.add(sphere);
scene.add(line);
}
这是我的光线投射:
var mouse = {
x: 0,
y: 0
},
INTERSECTED;
window.addEventListener('mousemove', onMouseMove, false);
window.requestAnimationFrame(render);
function onMouseMove(event) {
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components
//event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
//console.log(mouse.x + " | " + mouse.y);
}
function mousePos() {
// find intersections
// create a Ray with origin at the mouse position
// and direction into the scene (camera direction)
var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
vector.unproject(camera);
var ray = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
ray.linePrecision = 1;
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects(scene.children, true);
//console.log(intersects.length);
// INTERSECTED = the object in the scene currently closest to the camera
// and intersected by the Ray projected from the mouse position
// if there is one (or more) intersections
if (intersects.length > 0) {
// if the closest object intersected is not the currently stored intersection object
if (intersects[0].object != INTERSECTED) {
// restore previous intersection object (if it exists) to its original color
if (INTERSECTED)
INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
// store reference to closest object as current intersection object
INTERSECTED = intersects[0].object;
// store color of closest object (for later restoration)
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// set a new color for closest object
INTERSECTED.material.color.setHex(0xEE7F00);
//INTERSECTED.radius.set( 1, 2, 2 );
}
} else // there are no intersections
{
// restore previous intersection object (if it exists) to its original color
if (INTERSECTED)
INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
//INTERSECTED.scale.set( 1, 1, 1 );
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
}
}
光线投射 returns 对象的相交数组,它本身包含有关光线命中的信息。
因为你只有球体和线,你可以在几何类型 intersects[0].object.geometry.type
上分支,它可以是 'LineGeometry'
或 'SphereGeometry'
.
编辑: 必需的 jsfiddle,请参阅控制台以获取命中输出。 http://jsfiddle.net/z43hjqm9/1/
为了简化鼠标操作,您可以使用 class EventsControls。尝试通过这个 example.
<script src="js/controls/EventsControls.js"></script>
EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.attachEvent('mouseOver', function() {
this.container.style.cursor = 'pointer';
this.mouseOvered.material = selMaterial;
...
});
EventsControls.attachEvent('mouseOut', function() {
this.container.style.cursor = 'auto';
this.mouseOvered.material = autoMaterial;
...
});
//
function render() {
EventsControls.update();
controls.update();
renderer.render(scene, camera);
}
在您的代码中,
var intersects = ray.intersectObjects(scene.children, true);
调用的第一个参数是一个对象,将对其进行评估以查看它或其任何后代(递归为真)是否与射线相交。
因此,只需创建一个对象目标并将球体添加到其中(而不是线条)。
这将使您的通话也更加有效
1.use不同的数组放置不同的对象
a.for 所有 objectType1,在 scene.add(objectType1)-> 做 array1.push(objectType1)
之后
b.for 所有 objectType 2,在 scene.add(objectType2)-> 做 array2.push(objectType2)
现在,无论您想交互哪种类型的对象,都将该数组传递给 intersect as-
var intersects = raycaster.intersectObjects( arrayType1,true);
现在只有 arrayType1 对象会交互。