2

I have a problem,I want to make a hover mouse on an object that has multi-material.

Sample 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();
}

They don't work. It always shows "Uncaught TypeError: Cannot read property 'setHex' of undefined"

I changed the intersection code for this but doesn't work too:

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();
}

All objects stay black. The objects are loaded here:

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);
        }
    );
}

The complete code can be seen here: https://github.com/kathyer/Mousehover What can i do? thanks!

Edric
  • 24,639
  • 13
  • 81
  • 91
Kathyer
  • 21
  • 4
  • It can be better if you give more details such as is it working normally? which line do you get error on? – the_bluescreen Jun 09 '17 at 14:30
  • yes, sample of scene: http://i.imgur.com/SvBKoWn.png When i move the mouse pointer in the room it should look like this http://i.imgur.com/leozYuw.png Or other colors or textures The lines with error are 176, 163 and 169, thanks! complete code: https://github.com/kathyer/Mousehover/blob/master/js/render.js – Kathyer Jun 09 '17 at 14:56
  • Because you try to set a colour on a multimaterial, which doesn't have the `color` property, but it has the `materials` property, an array of materials. – prisoner849 Jun 09 '17 at 15:17
  • Thanks a lot prisoner849 how can copy the array of materials of an object in auxiliar variable to change the material original? and then change the modified material to the material of auxiliar variable when mouse over change – Kathyer Jun 09 '17 at 15:47
  • I have exactly the same s error – George C. Mar 14 '18 at 07:04

1 Answers1

0

Try this. check the console to see how is work. good luck all

  /**
   * 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();

  }
George C.
  • 6,574
  • 12
  • 55
  • 80