Can't detect GLB model with Raycaster

Hello everyone Can someone help me with my issue I need to detect my model with click, I am using Three.js in Vue.js. I successfully load my glb model into scene but after I cant detect my model with click
I am using RAYCASTER to approach this task.
below is my code
Thank you In Advance.

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';


export default {
  name: 'THREETest',
  data: function() {
    return {
      camera: null,
      scene: null,
      renderer: null,
      gltf: null,
      orbit: null,
      control: null,
      loader: null,
      array_buffer: null,

      raycaster: null,
      mouse: null,
      intersects: null,

    };
  },
  mounted: function() {

    let container = this.$refs.container;
    // SET AND ADD CAMERA
    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
    this.camera.position.z = 1;

    // ADD SCENE
    this.scene = new THREE.Scene();

    // ADD LIGHT TO SCENE
    this.light = new THREE.AmbientLight(0xffffff, 5.3);
    this.scene.add(this.light);

    // RENDER IN PAGE
    this.renderer = new THREE.WebGLRenderer({antialias: true});
    this.renderer.setClearColor('#dbdbdb');
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.gammaFactor = 1.5;
    this.renderer.gammaOutput = true;
    container.appendChild(this.renderer.domElement);

    // SET GRID HELPER
    const size = 10;
    const divisions = 25;
    this.gridHelper = new THREE.GridHelper( size, divisions );
    this.scene.add( this.gridHelper );

    // SET ORBIT CONTROLS
    this.orbit = new OrbitControls( this.camera, this.renderer.domElement );
    this.orbit.addEventListener("change", () => this.renderer.render(this.scene, this.camera));

    // SET MODEL CONTROL
    this.control = new TransformControls( this.camera, this.renderer.domElement );
    this.control.setSize(1);
    this.control.addEventListener( 'change', () => { this.renderer.render(this.scene, this.camera); });

    // EVENT LISTNER TO ENABLE ORBIT CAMERA AND CHANGE VALUE OF INPUTS
    this.control.addEventListener( 'dragging-changed', ( event ) => {
      this.orbit.enabled = ! event.value
    });

    this.raycaster = new THREE.Raycaster();
    this.mouse = new THREE.Vector2();

    const onMouseClick = (event) => {
      event.preventDefault();
      // calculate mouse position in normalized device coordinates
      // (-1 to +1) for both components
      this.mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
      this.mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
      // update the picking ray with the camera and mouse position
      this.raycaster.setFromCamera( this.mouse, this.camera );
      this.intersects = this.raycaster.intersectObjects( this.gltfobject, true );

      this.intersects.map((rayobject) => {
        if (rayobject.object.name.lenght > 0 ) {
          console.log(rayobject.object.name)
        }
      })

    };


    // window.addEventListener( 'mousemove', onMouseMove, false );

    window.addEventListener( 'mousedown', onMouseClick, false);

     this.renderer.render(this.scene, this.camera);
 },

 methods: {
   loaderGLTF: function() {
     // ADD GLTFLOADER
     this.loader = new GLTFLoader();

       if (this.array_buffer !== null ) {

         this.loader.parse(this.array_buffer, '',

          gltf => {
              this.scene.add(gltf.scene);
              gltf.scene.name = "Name of Glb File"

              // ADD CONTROLS TO MODEL
              this.control.attach( gltf.scene );
              this.scene.add( this.control );

              gltf.scene.scale.set(5, 5, 5);

              this.renderer.render(this.scene, this.camera);

       }, error => {
            console.log(error)
       });
     }
   },

   fileReader: function() {
     const file = this.$refs.file.files[0]
     const reader = new FileReader();

     reader.onload = (e) => {
       this.array_buffer = e.target.result;
    };

    reader.readAsArrayBuffer(file);
   },
  },
}

A typo: .length

It was case. Thank You
But one more question pleas
I set the name of my glb file but it returns “defaulte1” how it comes

gltf.scene is not a mesh, or points, or lines, it’s THREE.Object3D() that is just a container and it can’t be detected by a raycaster.
Maybe makes sense to use .traverseAncestors:

Something like that, after you get an array of intersected objects (it’s just from a scratch, I didin’t test it):

this.intersects = this.raycaster.intersectObjects( this.gltfobject, true );
if (this.intersects.length != 0) {
    var obj = this.intersects[0].object;
    obj.traverseAncestors( a => {
        if (a.name.length > 0) console.log(a.name);
    })
}

Prisoner Thank you :slight_smile:

Hello I have a question about Raycaster that I can’t find in the Internet
I was wonder what content raycaster.intersectObjects() returns after intersects,

and why we use .traverseAncestors

thank you.

Everything is in the docs, my friend.
https://threejs.org/docs/#api/en/core/Raycaster.intersectObject

1 Like

What should we use instead?
Traversing ancestors, we simply look for parent objects with some conditions.