OBJ Raycasting in Three.js


Greetings! I encountered an issue while working with three.js in my project. Specifically, I was trying to select a custom mesh that I loaded from an OBJ file.

To troubleshoot, I set up a simple raycaster, a cube, and my custom model (which is also a cube). Strangely, I can successfully raycast the cube but not the custom model. What could be causing this problem?

        var container, stats;
        var camera, scene, projector, renderer;
        var particleMaterial;

            var textureLoader;
            var modelLoader;

        var objects = [];

        init();
        animate();

        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.set( 0, 300, 500 );

            scene = new THREE.Scene();

                            var manager = new THREE.LoadingManager();
                            textureLoader = new THREE.ImageLoader( manager );
                            modelLoader = new THREE.OBJLoader(manager);




                            modelLoader.load( 'cube.obj', function ( object ) {

                                object.traverse( function ( child ) {

                                        if ( child instanceof THREE.Mesh ) {
                                                console.log("instance");
                                                child.geometry.computeFaceNormals();
                                                child.material = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } );

                                                child.material.side = THREE.DoubleSided;
                                        }

                                } );
                                objects.push(object);
                                object.position.x = 10;
                                object.position.y = 10;
                                object.scale.set(100,100,100);
                                scene.add(object);
                            });

                            var geometry = new THREE.SphereGeometry(150, 100, 100);
            for ( var i = 0; i < 1; i ++ ) {

                var object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) );
                object.position.x = Math.random() * 800 - 400;
                object.position.y = Math.random() * 800 - 400;
                object.position.z = Math.random() * 800 - 400;

                object.scale.x = Math.random() * 2 + 1;
                object.scale.y = Math.random() * 2 + 1;
                object.scale.z = Math.random() * 2 + 1;

                object.rotation.x = Math.random() * 2 * Math.PI;
                object.rotation.y = Math.random() * 2 * Math.PI;
                object.rotation.z = Math.random() * 2 * Math.PI;

                scene.add( object );

                objects.push( object );

            }

            var PI2 = Math.PI * 2;
            particleMaterial = new THREE.SpriteCanvasMaterial( {

                color: 0x000000,
                program: function ( context ) {

                    context.beginPath();
                    context.arc( 0, 0, 0.5, 0, PI2, true );
                    context.fill();

                }

            } );

            projector = new THREE.Projector();

            renderer = new THREE.WebGLRenderer();
            renderer.setClearColor( 0xf0f0f0 );
            renderer.setSize( window.innerWidth, window.innerHeight );

            container.appendChild( renderer.domElement );

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            container.appendChild( stats.domElement );

            document.addEventListener( 'mousedown', onDocumentMouseDown, false );

            //

            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

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

        }

        function onDocumentMouseDown( event ) {

            event.preventDefault();

            var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
            projector.unprojectVector( vector, camera );

            var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

            var intersects = raycaster.intersectObjects( objects );

            if ( intersects.length > 0 ) {
                                    console.log("intersected");
                intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );

                var particle = new THREE.Sprite( particleMaterial );
                particle.position = intersects[ 0 ].point;
                particle.scale.x = particle.scale.y = 16;
                scene.add( particle );

            }


        }

        //

        function animate() {

            requestAnimationFrame( animate );
                            scene.updateMatrixWorld();
            render();
            stats.update();

        }

        var radius = 600;
        var theta = 0;

        function render() {

            theta += 0.1;

            camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) );
            camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) );
            camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) );
            camera.lookAt( scene.position );

            renderer.render( scene, camera );

        }

After checking, I could select the sphere but not the custom obj. Any ideas on how to resolve this issue? Using Three.js r66.

UPDATE: The issue has been resolved. I just needed to add

var intersects = raycaster.intersectObjects( objects,true );

Answer №1

Make sure to set the recursive flag

var hits = raycaster.findIntersections( targets, true );

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering an issue with Server Side Rendering in React Router Dom where an error message pops up saying: "Warning: React.createElement: type is

Specific Error: A warning has occurred: React.createElement: the type provided is invalid -- it was expecting a string (for built-in components) or a class/function (for composite components), but instead received an object. in Posts in Connect(Po ...

Is there an Angular Profile service offering getter and setter properties?

Can a singleton Angular service be created with getters and setters along with logic implementation? I was provided with the following code snippet and tasked with replicating it in an Angular service. Although it may seem straightforward, I'm finding ...

What is causing this JavaScript function to output '2'?

Recently, I came across an unusual JavaScript function: (function f(){ function f(){ return 1; } return f(); function f(){ return 2; } })(); To my surprise, it returns 2 instead of crashing the browsers as expected due to recursion. Curious ...

The div is incorrect and causing the label and input to move in the wrong direction

Whenever I try to adjust the position of the current-grade-name-input, the entire grade-point-input moves along with it inexplicably. /* final grade calculator: (wanted-grade - (current-grade * (1 - final%))) / final% Ex: have a 80 an ...

Can routes be nested in React components?

I'm curious to know if there's a way to integrate nested routes in React, where the Navbar component serves as the parent for dashboard and properties. <Router> <Routes> <Route path='/' element={<Home />} /> ...

Is it possible to create a development build using Npm with React and Typescript?

I have successfully set up a TypeScript React app by using the command below: npx create-react-app my-app --template typescript However, running "npm start" generates development javascript files and launches a development server which is not id ...

Enhance text by hovering over it

I am currently working on implementing a unique feature using jQuery and CSS. Rather than just inheriting the width, I want to create a magic line that extends to the next index item. Scenario: 1: Hover over Element one ELEMENT ONE ELEMENT TWO ELEM ...

Experience the click action that comes equipped with two unique functions: the ability to effortlessly add or remove a class

Currently, I am in the process of creating a list of anchor links that contain nested anchor links, and there are a few functionalities that I am looking to implement. Upon clicking on a link: Add a class of "current" Remove the class of "current" from ...

What steps should be taken to develop a Hybrid Mobile App concept?

We are currently developing our first hybrid mobile application with a monetizable idea in mind. After conducting some research, it seems that to reach our end goal we will need: A Front End UI Framework: options include Ionic or AngularGap (although d ...

Tidy up Three.js WebGL environments

While working on my WebGl-Scenes in Three.js with a WebGlRenderer, I've run into an issue during the cleanup process. Since I frequently change views in my application, I find myself having to render new scenes regularly. Up until now, my solution has ...

Utilizing jQuery for Populating Text Fields and Selecting Checkboxes

Is there a way to take user input and store it in a variable, then insert that information into a webpage like this one? To clarify, I'm looking for a way for an app to transfer data from a variable into an input field on a website (similar to the ex ...

I am encountering a JQuery syntax error while using Bootstrap 3 button-dropdown links

I'm trying to replicate the example found here in order to create a similar markup: <div class="btn-group"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> ...

Having trouble executing "npm install" following the clone from GitHub in React

After cloning a repository from GitHub, I attempted to run "npm install" but encountered the following error: https://i.sstatic.net/QM4RZ.png Since the project is still in development, should I install or add anything else to successfully run it? ...

Strategies for accessing a collection of DOM elements in React

Currently, I'm embarking on a challenge to complete 50 projects in 50 days by Brad Traversy. However, I've decided to take it up a notch by building them in Next.js with React since that's what I work with professionally. Unfortunately, thi ...

Transforming FormData string key names into a Json Object that is easily accessible

Recently, I encountered an issue where my frontend (JS) was sending a request to my backend (Node Typescript) using FormData, which included images. Here is an example of how the data was being sent: https://i.stack.imgur.com/5uARo.png Upon logging the r ...

issue with transparent html5

Here is the code snippet I am struggling with: function clear(){ context2D.clearRect(0, 0, canvas.width, canvas.height); } function drawCharacterRight(){ clear(); context2D.setTransform(1, 0.30, 1, -0.30, 10, 380);//having issues here c ...

Is there a way to minimize the use of .value in Vue 3?

After recently diving into Vue 3, I find myself struggling to grasp some key concepts of the composition API. My current challenge involves converting a library from Vue 2 to Vue 3, where a reactive property named layout is being passed down to child compo ...

Creating a Dynamic Slideshow on Autopilot

My JavaScript skills are not perfect and I'm feeling a bit lost. I have this code for a slideshow, but I want to make it automatic while also allowing users to navigate between images freely. I'm struggling to figure out how to implement this fun ...

Sorting Columns in PrimeVue DataTable by Date and Time

I am using a PrimeVue DataTable () with the following structure: <DataTable :rows = "5" :value = "apiItems" > <Column v-for="data in columns" :field="data.field" :header="data.header&q ...

Issue when transmitting information from Angular to Express

I'm attempting to send data from Angular to Express.js Below is my TypeScript function connected to the button: upload(): void { const nameFromId = document.getElementById('taskName') as HTMLInputElement; this.taskName = nameFromI ...