我有一个问题,我想在具有多种材质的物体上制作悬停鼠标。
示例here
function update()
{
// 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, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( scene.children );
// 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( 0xffff00 );
}
}
else // there are no intersections
{
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
}
if ( keyboard.pressed("z") )
{
// do something
}
controls.update();
}
它们不起作用。它始终显示“Uncaught TypeError:无法读取未定义的属性'setHex'”
我为此更改了交叉点代码,但也不起作用:
function update()
{
// 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, 1 );
projector.unprojectVector( vector, Camara );
var ray = new THREE.Raycaster( Camara.position, vector.sub( Camara.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( Escenario.children );
// INTERSECTED = El objeto en la escena actualmente más cercana a la cámara e intersectado por el Rayo proyectado desde la posición del ratón.
// Si hay una o más intersecciones (objetos encontrados con el ratón)
if ( intersects.length > 0 )
{
// Si el primer objeto encontrado es diferente del anterior encontrado
if (intersects[0].object != INTERSECTED)
{
// Restaura previamente el anterior al color del objeto original
if (INTERSECTED)
{
// INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
INTERSECTED.material = 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();
for(var p =0; p < INTERSECTED.material.materials.length; p++)
{
INTERSECTED.currentHex = INTERSECTED.material.materials[p].emissive.getHex();
}
// set a new color for closest object
//INTERSECTED.material.color.setHex(0xffff00);
}
}
else // there are no intersections
{
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED )
{
INTERSECTED.material = INTERSECTED.currentHex;
}
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
}
controls.update();
}
所有物体都保持黑色。这里加载了对象:
function mostrarPiso()
{
// Cargamos el modelo de la escuela. En el primer parámetro está la url del modelo y en el segundo la función que se ejcuta al cargarlo. En este caso estoy utilizando una función anónima.
loader.load("modelos/informaticaPlanta0/PlantaBajaSinHabitacion.js", function (geometry, materials)
{
let material = new THREE.MultiMaterial(materials);
let object = new THREE.Mesh(geometry, material);
object.name = "pabellon";
Escenario.add(object);
}
);
loader.load("modelos/informaticaPlanta0/PlantaBajaHabitacion.js", function (geometry, materials)
{
let material = new THREE.MultiMaterial(materials);
let object = new THREE.Mesh(geometry, material);
object.name = "habitacion";
Escenario.add(object);
}
);
}
完整的代码可以在这里看到: https://github.com/kathyer/Mousehover 我能做什么?谢谢!
答案 0 :(得分:0)
/**
* On mouse move event.
* @param event
*/
onMouseMove(event) {
event.preventDefault();
this.mouse.x = (event.offsetX / this.w) * 2 - 1;
this.mouse.y = -(event.offsetY / this.h) * 2 + 1;
// this.checkIntersection('hover');
}
/**
* Check if intersection happen.
*/
checkIntersection (operation?) {
// Setup the raycaster.
this.raycaster.setFromCamera(this.mouse, this.camera);
// console.log(this.cubeChilds);
const intersects = this.raycaster.intersectObjects(this.scene.children);
console.log(intersects);
if (operation === 'hover') {
}
// Change the material of the element that
this.mouse_highLighter (intersects);
}
mouse_highLighter (intersects) {
// function _exists(currentValue) {
// return currentValue < 40;
// }
console.log('mouse_highLighter start: ');
const new_material = new THREE.MeshBasicMaterial({
color: 0xff0000,
});
const new_green_material = new THREE.MeshBasicMaterial({
color: 0x00ff40,
});
// ? If intersected object exist
if ( intersects.length > 0 ) {
if ( this.INTERSECTED !== intersects[ 0 ].object ) {
// set the preview mesh material if exist
if ( this.INTERSECTED ) {
this.INTERSECTED.material = this.intersected_last_mat;
console.log('--1--');
}
this.INTERSECTED = intersects[ 0 ].object;
this.intersected_last_mat = this.INTERSECTED.material;
intersects[ 0 ].object.material = new_green_material;
console.log(this.INTERSECTED);
console.log('--2--');
}
} else {
if ( this.INTERSECTED ) {
this.INTERSECTED.material = this.intersected_last_mat;
console.log('--3--');
}
this.INTERSECTED = null;
console.log('--4--');
}
console.log('--5--');
this.render();
}