Question

I have been struggling with issues concerning raycasting on small circlegeometries on a sphere.

I know raycasting can't be done with sprites and this is why I use circlegeometries, but it doesn't work all the time, and moreover the raycasting doesn't always work on circles but sometimes around them as well.

Does anybody have an idea ? Here is a JSBin to show you basically

Edit : I updated my previous version of JSBin, you can click any circleGeometries it will work here, run it with output tab only open for better results

This is related to the renderer width and height properties, my sphere isn't in fullscreen and this is why it fails.

Does anybody have an idea on how to set up it right in order to get this to work perfectly ?

Était-ce utile?

La solution

The formula used to compute intersections wasn't the good one, here is the one that works :

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

mouse x and y have slightly changed from the examples you can get, and are now fine.

    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 ) {
    //do something
}

Autres conseils

if you looking for some thing like this....Your code might need little changes... check this link http://jsfiddle.net/ebeit303/rjJ6q/

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

// FUNCTIONS        
function init() 
{

    // SCENE
    scene = new THREE.Scene();
    // 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);  
    // RENDERER

        renderer = new THREE.CanvasRenderer(); 
    renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
    container = document.getElementById( 'ThreeJS' );
    container.appendChild( renderer.domElement );
    // EVENTS

    // CONTROLS 

    // this material causes a mesh to use colors assigned to faces
    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);

    //targetList.push(sphere);

    var j=0;

    for (var i =0; i<100;i+=5){
    //var circle = new THREE.CubeGeometry(5,5,5);
    var circle = new THREE.CircleGeometry(5, 8, 0, Math.PI * 2);
    //THREE.GeometryUtils.triangulateQuads(circle);
    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++;
    }


    // initialize object to perform world/screen calculations
    projector = new THREE.Projector();

    // when the mouse moves, call the given function
    document.addEventListener( 'mousedown', onDocumentMouseDown, false );

}

function onDocumentMouseDown( event ) 
{


    // update the mouse variable
    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 );
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top