Selecting FBX with raycaster

mh the only issue I can see is that raycasting occurs on the variable meshobj even when it’s undefined (model is not yet loaded).

I also see that you call requestAnimationFrame on two functions :

requestAnimationFrame(animate);

window.requestAnimationFrame(render);

Just remove the latter and put the render() call in your conditional block :

if (meshobj) {

    render()

    // meshobj.rotation.y += 0.002;

}

I copied you code and made these changes, for me it worked :

Here is my code :

Summary
import * as THREE from '../build/three.module.js';

import Stats from './jsm/libs/stats.module.js';

import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { FBXLoader } from './jsm/loaders/FBXLoader.js';

let container, stats, controls;
let camera, scene, renderer, light, mesh, grid, meshobj;

let mixer;

let composer, outlinePass;

init();

animate();

function init() {

    //選擇容器

    const canvas = document.querySelector('#infoe');

    //建立相機

    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 5000);

    camera.position.set(200, 500, 700);

    //建立場景

    scene = new THREE.Scene();

    scene.background = new THREE.Color(0xffffff);

    // scene.fog = new THREE.Fog(0xa0a0a0, 200, 1000);

    //建立燈光(半球光)

    light = new THREE.HemisphereLight(0x999999, 0x000000);

    light.position.set(0, 200, 0);

    scene.add(light);

    //建立燈光(定向光)

    light = new THREE.DirectionalLight(0x999999);

    light.position.set(0, 200, 100);

    light.castShadow = true;

    light.shadow.camera.top = 180;

    light.shadow.camera.bottom = - 100;

    light.shadow.camera.left = - 120;

    light.shadow.camera.right = 120;

    scene.add(light);

    // model 載入進度

    const onProgress = function (xhr) {

        if (xhr.lengthComputable) {

            const percentComplete = (xhr.loaded / xhr.total) * 100;

            console.log(Math.round(percentComplete, 2) + '% downloaded');

        }

    };

    const onError = function () { };

    const manager = new THREE.LoadingManager();

    // model 3D (FBX)

    var loader = new FBXLoader(manager);

    loader.load('models/fbx/Samba Dancing.fbx', function (object) {

        object.scale.multiplyScalar(1); //模型大小縮放

        meshobj = object

        meshobj.position.y = 100;

        scene.add(meshobj);

    }, onProgress, onError);

    //render 渲染彩現

    renderer = new THREE.WebGLRenderer({

        antialias: true,

        alpha: true

    });

    renderer.setSize( window.innerWidth, window.innerHeight )

    document.body.appendChild( renderer.domElement );

    //OrbitControls 滑鼠拖曳旋轉控制器

    controls = new OrbitControls(camera, document.body);

    controls.enableDamping = false; //拖拉慣性

    controls.campingFactor = 0.25;  //拖拉慣性阻尼參數搭配enableDamping使用

    controls.enableZoom = true; //相機變焦移動

    controls.enablePan = false; //相機平移

    controls.target.set(0, 100, 0);

    controls.update();

}

//canvas 畫面自訂義

function resizeRendererToDisplaySize(renderer) {

    const canvas = renderer.domElement;

    const width = canvas.clientWidth;

    const height = canvas.clientHeight;

    const needResize = canvas.width !== width || canvas.height !== height;

    if (needResize) {

        renderer.setSize(width, height, false);

    }

    return needResize;

}

//raycaster

let raycaster = new THREE.Raycaster();

let mouse = new THREE.Vector2(), INTERSECTED;

let selection = null;

function onMouseClick(event) {

    event.preventDefault();

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;

    mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;

}

function render() {

    //通過相機和滑鼠位置更新射線

    raycaster.setFromCamera(mouse, camera);

    // 計算物體和射線的焦點

    var intersects = raycaster.intersectObject(meshobj, true);

    if (intersects.length > 0) {

        if (INTERSECTED != intersects[0].object) {

            selection = intersects[0].object;

            // 當點擊其他地方回復顏色

            console.log( selection )

            if (selection) selection.material.color.set(selection.currentHex);

            // 設定新的顏色

            selection.material.color.set(0xff0000);

            // container.style.cursor = "pointer";

            console.log('點到你了');

        }

    } else {

        if (selection) selection.material.color.set(0x000000);

        selection = null;

        // container.style.cursor = "default";

    }

    renderer.render(scene, camera);

}

//動畫執行

function animate() {

    requestAnimationFrame(animate);

    if (resizeRendererToDisplaySize(renderer)) {

        const canvas = renderer.domElement;

        camera.aspect = canvas.clientWidth / canvas.clientHeight;

        camera.updateProjectionMatrix();

    }

    if (meshobj) {

    	render();
        // meshobj.rotation.y += 0.002;

    }

    renderer.render(scene, camera);

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

}

If it still doesn’t work for you, you will have to make a fiddle to demonstrate the issue.
You can use this fiddle as a template : https://jsfiddle.net/ofa7bj8x/

1 Like