Exploring the use of raycasting and containers in Three.js

I've been facing challenges with raycasting on small circle geometries on a sphere. Despite knowing that raycasting can't be done with sprites, I still encounter issues when using circle geometries. Sometimes the raycasting doesn't only work on circles but also around them. Is there anyone who has any ideas? You can take a look at this JSBin for reference.

Edit: I have updated my JSBin to make it more user-friendly. You can now click on any circle geometries and see how it works here. Make sure to run it with only the output tab open for better results.

This issue is related to the renderer's width and height properties. Since my sphere isn't in fullscreen mode, it fails to work properly. Does anyone know how to set it up correctly to ensure perfect functionality?

Answer №1

The method for calculating intersections was found to be incorrect initially, but here is the revised version that works effectively:

    mouse.x = ( ( event.clientX - renderer.domElement.offsetLeft ) / renderer.domElement.width ) * 2 - 1;
    mouse.y = - ( ( event.clientY - renderer.domElement.offsetTop ) / renderer.domElement.height ) * 2 + 1;

There have been minor adjustments made to the values of mouse x and y compared to previous examples, ensuring their accuracy.

    var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);

    projector.unprojectVector(vector, camera);
    var ray = new THREE.Raycaster(camera.position, vector.sub(
            camera.position).normalize());

    var intersects = ray.intersectObjects(objects);

    if ( intersects.length > 0 ) {
    //perform relevant action
}

Answer №2

If you are seeking something similar to this, your code may require some minor adjustments. Please refer to the following link: http://jsfiddle.net/ebeit303/rjJ6q/

// Initializing standard global variables
var container, scene, camera, renderer, controls, stats;
var clock = new THREE.Clock();

// Custom global variables
var targetList = [];
var projector, mouse = { x: 0, y: 0 };

init();
animate();

// Function Definitions      
function init() 
{

    // Setting up SCENE
    scene = new THREE.Scene();
    
    // Setting up CAMERA
    var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
    var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 100000;
    camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
    scene.add(camera);
    camera.position.set(600,0,-1200);
    camera.lookAt(scene.position);  
    
    // Rendering
    renderer = new THREE.CanvasRenderer(); 
    renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
    container = document.getElementById( 'ThreeJS' );
    container.appendChild( renderer.domElement );
   
    // Creating Sphere Geometry with randomized colors
    var faceColorMaterial = new THREE.MeshBasicMaterial( 
    { color: 0xffffff, vertexColors: THREE.FaceColors } );

    var sphereGeometry = new THREE.SphereGeometry( 500, 64, 64 );
    for ( var i = 0; i < sphereGeometry.faces.length; i++ ) 
    {
        face = sphereGeometry.faces[ i ];   
        face.color.setRGB( 0, 0, 0.8 * Math.random() + 0.2 );       
    }
    var sphere = new THREE.Mesh( sphereGeometry, faceColorMaterial );
    sphere.rotation.set(0, 14.5, 0);
    scene.add(sphere);

    // Adding additional elements to the sphere
    var j=0;

    for (var i =0; i<100;i+=5){
        var circle = new THREE.CircleGeometry(5, 8, 0, Math.PI * 2);
        var circleMaterial = new THREE.MeshBasicMaterial({color: 0xDEF2EF});
        circleMaterial.side = THREE.DoubleSide;

        var mesh = new THREE.Mesh(circle, circleMaterial);

        var Alon = i - 90;
        var Alat = j;

        var Aphi = Math.PI/2 - Alat * Math.PI / 180;
        var Atheta = 2 * Math.PI - Alon * Math.PI / 180;

        mesh.position.x = Math.sin(Aphi) * Math.cos(Atheta) * (501);
        mesh.position.y = Math.cos(Aphi) * (501);
        mesh.position.z = Math.sin(Aphi) * Math.sin(Atheta) * (501);    
        mesh.verticesNeedUpdate = true;
        mesh.lookAt( sphere.position );

        sphere.add(mesh);
        targetList.push(mesh);

        j++;
    }

    projector = new THREE.Projector();

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

}

function onDocumentMouseDown( event ) 
{
    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

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

    var intersects = ray.intersectObjects( targetList );

    if ( intersects.length > 0 )
    {       
        intersects[ 0 ].object.material.color.setRGB( 0.8 * Math.random() + 0.2,
                                                     0.8 * Math.random() + 0.2,
                                                     0.8 * Math.random() + 0.2 );
    }

}

function animate() 
{
    requestAnimationFrame( animate );
    render();       
}


function render() 
{
    renderer.render( scene, camera );
}

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

Attach a unique anti-forgery identifier to XMLHttpRequest

Essentially, I am having an issue with validating the token in my JavaScript code. Everything works fine without validation, but once I try to validate the token, I receive an error stating The required anti-forgery form field "__RequestVerificationToken" ...

Is it possible to manually trigger a version change transaction in IndexedDB?

I have been working on a Chrome extension that uses the IndexedDB to store data client-side in an IDBObjectStore within an IDBDatabase. The data structure requires users to be able to modify the object store freely, such as adding new objects or modifying ...

Customizing Geonames JSON Ajax Request

Having found the code I needed from a sample website, I am now seeking help to customize it to only display results from the USA. This is the current code snippet: $(function() { function log( message ) { $( "<div>" ).text( message ).pr ...

How to add suspense and implement lazy loading for a modal using Material-UI

Currently, I am implementing <Suspense /> and lazy() to enhance the performance of my project. While everything seems to be working smoothly, I have observed some minor changes in DOM handling that are causing me slight confusion. Consider this scen ...

Unforeseen anomalies arise when deleting an element from an array in a React application

I've been scouring for a solution, but I could really use some human guidance. I have a basic form where users can input additional fields. They also have the option to delete irrelevant fields. The problem arises when trying to remove these fields. ...

Leveraging the power of jQuery/javascript in conjunction with Google Forms

Currently, I am attempting to utilize jQuery and JavaScript with an iframe that contains a Google form. The code snippet is displayed below: <body> <iframe id="myFormFrame" src="https://docs.google.com/forms/d/smfjkafj809890dfafhfdfd/viewform?emb ...

Is it possible to navigate between jQuery EditInPlace fields using the Tab key?

Seeking advice on implementing tab functionality for a page with multiple jquery EditInPlace fields. The goal is to allow users to navigate between fields by pressing the tab key. Currently using the 'jquery-in-place-editor' plugin available at: ...

How can I import a component directly from a webpack bundle in React?

Under normal circumstances, components are imported from another JavaScript file. However, in my project, I am looking to import a component from the webpack-created bundle. Step 1: Generate a bundle for the ABC folder, naming it abc.bundle.js Note: The ...

There seems to be a mysterious absence of chuck norris jokes in

I'm attempting to call two different APIs by clicking a button to display a random joke on the screen. I've created two separate functions to fetch the APIs and used Math.random() to generate a random number. If the number is greater than 50, one ...

Create a TypeScript interface that represents an object type

I have a Data Structure, and I am looking to create an interface for it. This is how it looks: const TransitReport: { title: string; client: string; data: { overdueReviews: number; outstandingCovenantBreaches ...

"Challenges Encountered When Using Angular in Conjunction with Bootstrap

Is there a way to apply ng-disable on a Bootstrap Modal Dialog when the form in a Partial View displayed in the Modal is Invalid? Working with Asp.net MVC, I am facing an issue where I include a Partial View in a Modal form. The form should display detail ...

Differences in file loading in Node.js: comparing the use of .load versus command-line

Currently, I am in the process of developing a basic server using vanilla JavaScript and Node.js. For this purpose, I have created a file named database.js, which includes abstractions for database interactions (specifically with redis). One of my objecti ...

Angular Karma encountered an error: TypeError - It is unable to read the property '_id' as it is undefined

Encountering an issue while testing with karma jasmine, the error message appears as... TypeError: Cannot read property '_id' of undefined This is the Component.ts file: import { Component, OnInit } from '@angular/core'; import { ApiSe ...

Removing duplicate elements from an array using lodash

What is the best way to remove duplicate values from an array? var numbers = [1, 1, 5, 5, 4, 9]; I want my result to be: var numbers = [4, 9]; Is there a method in lodash that can help me achieve this? ...

Leveraging Webpack for the exclusive creation of a vendor bundle

Presently, our AngularJS project relies on Bower for front-end dependencies and the bower-concat Grunt task to merge bower_components into a single libraries.js file. Similarly, we assemble library CSS files into a libraries.css. Looking ahead, we aim to ...

Is there a way for me to insert a hook into the DOM after a promise has finished updating

Currently, I am tasked with maintaining a code snippet that resembles the following structure: {#await details} {#each values as value, i} <td id="{`${config.id}_${i}`}">{value}</td> {/each} {:then details_result} {#each de ...

Is there a way for mocha to conduct a recursive search within my `src` directory in order to find a specific

In my npm project, I want to replicate the structure used by Meteor: there is a source file called client.js and its corresponding test file named client.tests.js residing in the src/ directory. The tests should be executed with the npm test command. I am ...

HTML two-row horizontal list with truncation

My dilemma involves a horizontal list of items that expand the full width of their container and wrap onto the next line. However, I only want to show two lines of items initially, with a "show more" link to reveal additional rows in increments of two unti ...

Switching Over to Burger Menu

I created a burger menu using HTML, CSS, and jQuery that switches from a full-width menu to a burger menu. However, I'm facing an issue with toggling the dropdown when the menu collapses. Here's my code: <!DOCTYPE html> <html> < ...

Leveraging $http in Angular without the need for $scope

When using the syntax <div ng-controller="BuildingsCtrl as bc"> to avoid using $scope (as mentioned here), how should I incorporate $http? In other words, how can I refactor the following code without relying on $scope? angular.module('atlasAn ...