Raycasting and container in Three.js

依然范特西╮ 提交于 2019-12-11 06:56:11

问题


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 ?


回答1:


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
}



回答2:


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


来源:https://stackoverflow.com/questions/21575208/raycasting-and-container-in-three-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!