2013-08-31 18 views
11

Sto riscontrando un po 'di difficoltà nel selezionare oggetti con la macchina ortografica utilizzando il raycaster. Tuttavia, non ho alcun problema quando uso una telecamera prospettica. L'unica cosa che sto cambiando quando si passa tra i due è il tipo di macchina fotografica.Telecamera ortografica e selezione di oggetti con raycast

Sono in grado di selezionare facce sulla vista ortografica, ma è solo vagamente correlato a dove sto facendo clic sullo schermo. Quando riesco a fare clic lontano dall'oggetto, tornerà ancora come se avesse colpito l'oggetto vicino al suo centro.

Qualche idea su cosa mi manca qui?

Sto basando gran parte del mio codice su questo example e spero di ottenere un risultato molto simile dal mio codice. (Questo esempio sto riferimento utilizza la fotocamera prospettiva)

Ogni aiuto è molto apprezzato

<html> 
<head> 
    <style> 
    canvas { 
     left: 0; 
     top: 0; 
     width: 100%; 
     height: 100%; 
     position: fixed; 
     background-color: #111115; 
    } 
    </style> 
</head> 
<body id='c'> 
    <script src="js/three.js"></script> 

    <script> 

    var obj = []; 
    var mouse ={}; 
    var zoom = 2; 

    var scene = new THREE.Scene(); 

    //switch between these two and see the difference: 
    //var camera = new THREE.OrthographicCamera(window.innerWidth/-zoom, window.innerWidth/zoom, window.innerHeight/zoom, window.innerHeight/-zoom, -1000, 1000); 
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000); 

    camera.position = new THREE.Vector3(100,100,100); 
    camera.lookAt(new THREE.Vector3(0,0,0)); 

    // this material causes a mesh to use colors assigned to faces 
    var material = new THREE.MeshBasicMaterial( 
    { color: 0xffffff, vertexColors: THREE.FaceColors }); 

    var sphereGeometry = new THREE.SphereGeometry(80, 32, 16); 
    for (var i = 0; i < sphereGeometry.faces.length; i++) 
    { 
     face = sphereGeometry.faces[ i ]; 
     face.color.setRGB(0, 0, 0.8 * Math.random() + 0.2);  
    } 
    obj['box'] = {}; 
    obj['box'] = new THREE.Mesh(sphereGeometry, material); 
    obj['box'].castShadow = true; 
    obj['box'].receiveShadow = true; 
    scene.add(obj['box']); 

    var ambientLight = new THREE.AmbientLight(0xbbbbbb); 
    scene.add(ambientLight); 

    var directionalLight = new THREE.DirectionalLight(0xffffff, 1); 
    directionalLight.position.set(-100, 40, 100); 
    directionalLight.castShadow = true; 
    directionalLight.shadowOnly = true; 
    directionalLight.shadowDarkness = .5; 
    scene.add(directionalLight); 

    var renderer = new THREE.WebGLRenderer(); 
    renderer.setSize(window.innerWidth, window.innerHeight); 
    renderer.shadowMapEnabled = true; 
    renderer.shadowMapSoft = true; 
    document.body.appendChild(renderer.domElement); 

    projector = new THREE.Projector(); 
    document.addEventListener('mousedown', onDocumentMouseDown, false); 
    function onDocumentMouseDown(event) { 
     // the following line would stop any other event handler from firing 
     // (such as the mouse's TrackballControls) 
     // event.preventDefault(); 

     console.log("Click."); 

     // update the mouse variable 
     mouse.x = (event.clientX/window.innerWidth) * 2 - 1; 
     mouse.y = - (event.clientY/window.innerHeight) * 2 + 1; 

     // find intersections 

     // create a Ray with origin at the mouse position 
     // and direction into the scene (camera direction) 
     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()); 

     // create an array containing all objects in the scene with which the ray intersects 
     var intersects = ray.intersectObjects([obj['box']]); 

     // if there is one (or more) intersections 
     if (intersects.length > 0) 
     { 
     console.log("Hit @ " + toString(intersects[0].point)); 
     console.log(intersects); 
     // change the color of the closest face. 
     intersects[ 0 ].face.color.setRGB(0.8 * Math.random() + 0.2, 0, 0); 
     intersects[ 0 ].object.geometry.colorsNeedUpdate = true; 
     } 
    } 

    function toString(v) { return "[ " + v.x + ", " + v.y + ", " + v.z + " ]"; } 

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

    console.log(camera); 
    console.log(obj['box']) 
    render(); 

    </script> 
</body> 

spero sia qualcosa di semplice che io proprio non lo so ancora.

Three.js R60

+1

Tip : Il piano 'near' di' OrthographicCamera' è negativo. Questo è dietro la macchina fotografica. Dovrebbe essere positivo. Inoltre, i primi quattro argomenti sono in coordinate globali, non in coordinate pixel, quindi non confondersi. – WestLangley

risposta

18

Ecco il modello da utilizzare quando raycasting sia con un ortogonale telecamera o prospettiva della telecamera:

var raycaster = new THREE.Raycaster(); // create once 
var mouse = new THREE.Vector2(); // create once 

... 

mouse.x = (event.clientX/renderer.domElement.clientWidth) * 2 - 1; 
mouse.y = - (event.clientY/renderer.domElement.clientHeight) * 2 + 1; 

raycaster.setFromCamera(mouse, camera); 

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

Three.js r.84

+1

thx. scomodo, quel codice di selezione dipende dal tipo di telecamera. – KregHEk

+0

... ma molto meglio di se stesso all'interno di WebGL :) – potomek

+0

Si prega di aggiungere la configurazione della fotocamera perché lo snippet che hai presentato dipende da esso. –

0

Una nota che potrebbe salvarti qualche problema. Se avete una macchina fotografica come questo:

var camera = new THREE.OrthographicCamera(0, window.innerWidth, -window.innerHeight, 0, -100, 100); 

Poi durante raycasting, assicurarsi di spostare l'origin.z ray a camera.far per esso a colpire nulla in tutta la gamma visibile:

this.ray.origin.set(0, 0, 0); 
this.camera.localToWorld(this.ray.origin); 
this.raycaster.setFromCamera(this.mouseCoord, this.camera); 
this.ray.origin.z = this.camera.far; 
Problemi correlati