javascript - Cámara ortográfica y selección de objetos con raycast
three.js raycasting (2)
Me cuesta un poco seleccionar objetos con la cámara ortográfica usando el raycaster. Sin embargo, no tengo ningún problema cuando uso una cámara en perspectiva. Lo único que estoy cambiando cuando cambio entre los dos es la cámara tipo.
Puedo seleccionar rostros en la vista ortográfica, pero solo se relaciona vagamente con el lugar donde estoy haciendo clic en la pantalla. Cuando puedo hacer clic lejos del objeto y todavía volverá como si hubiera golpeado el objeto cerca de su centro.
¿Alguna idea sobre lo que me falta aquí?
Estoy basando gran parte de mi código en este ejemplo , y espero obtener un resultado muy similar de mi código. (este ejemplo al que me refiero utiliza la cámara de perspectiva)
Cualquier ayuda es muy apreciada
<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>
Espero que sea algo simple que aún no sé.
three.js r60
Este es el patrón para usar cuando se proyecta con una cámara ortográfica o una cámara en perspectiva:
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
Una nota más que podría ahorrarle algunos problemas. Si tienes una cámara como esta:
var camera = new THREE.OrthographicCamera(0, window.innerWidth, -window.innerHeight, 0, -100, 100);
Luego, durante la emisión de rayos, asegúrese de mover el rayo origin.z a camera.far para que golpee cualquier cosa en todo el rango visible:
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;