Estoy intentando hacer una función de hacer clic para ampliar con Three.js, tengo un lienzo y un objeto cargado en el lienzo. Al hacer clic, estoy tratando de colocar la cámara cerca del punto de intersección (en realidad, como hacer zoom en ese punto).

Esto es lo que he hecho, pero no funciona como quería, al hacer clic en los cambios de posición de la cámara, pero funciona parcialmente, a veces la cámara se coloca cerca del punto de intersección, otras veces no.

 onmousedown = function (event) {

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

                 event.preventDefault();
                mouse.x = (event.clientX / self.renderer.domElement.clientWidth) * 2 - 1;
                mouse.y = -(event.clientY / self.renderer.domElement.clientHeight) * 2 + 1;
                raycaster.setFromCamera(mouse, self.camera);
                var objects = [];
                for (var i = 0; i < self.scene.children.length; i++) {
                         if (self.scene.children[i] instanceof  THREE.Group) {
                        objects.push(self.scene.children[i]);
                    }
                }
                console.log(objects);
                var intersects = raycaster.intersectObjects( objects,true );
                console.log(intersects.length);
                if (intersects.length > 0) {
                            self.camera.up = new THREE.Vector3(0, 0, 1);
                    self.camera.lookAt(new THREE.Vector3(0, 0, 0));
                    self.camera.position.z = intersects[0].point.z * .9;
                    self.camera.position.x = intersects[0].point.x * .9;
                    self.camera.position.y = intersects[0].point.y * .9;



                }

            };

Aquí self es un objeto de visor global que contiene cámara, lienzo, diferentes objetos, etc.

0.9 es solo un número utilizado para colocar la cámara cerca del punto de intersección.

La cámara utilizada es PerspectiveCamera y los controles son TrackballControls

new THREE.PerspectiveCamera(90, this.width / this.height, 1, 1000);

Los objetos cargados son de archivos .obj o .dae, espero que esto funcione como hacer clic en cualquier punto del objeto y colocar la cámara cerca de ese punto. Pero la cámara se mueve pero a veces no está cerca del punto en el que hice clic.

  • ¿intersects[0] da el punto de intersección más cercano? o más cercano en la dirección de la cámara?
  • ¿Cuál es mi error aquí?

Soy nuevo en tres js, acabo de comenzar a aprenderlo. Si algo o alguna lógica está mal, ayúdame con eso.

2
Arun Xavier 11 may. 2016 a las 08:47

3 respuestas

La mejor respuesta

Me he acercado un poco a lo que quiero con un ejemplo de Three js.

Tres calcomanías web JS

Esto es lo que he hecho.

function zoomCam(event) {

var point_mouse = new THREE.Vector2(),
    var point_x = null;
    var point_y = null;
            if (event.changedTouches) {

                point_x = event.changedTouches[ 0 ].pageX;
                point_y = event.changedTouches[ 0 ].pageY;
            } else {

                point_x = event.clientX;
                point_y = event.clientY;
            }

            point_mouse.x = (point_x / window.innerWidth) * 2 - 1;
            point_mouse.y = -(point_y / window.innerHeight) * 2 + 1;

            if (sceneObjects.length > 0) {

                var raycaster = new THREE.Raycaster();
                raycaster.setFromCamera(point_mouse, camera);
                var intersects = raycaster.intersectObjects(sceneObjects, true);
                if (intersects.length > 0) {
                    var p = intersects[ 0 ].point;
                var n = intersects[ 0 ].face.normal.clone();
                n.multiplyScalar(10);
                n.add(intersects[ 0 ].point);
                camera.position.copy(n);
                camera.lookAt(p);
                }
            }

Puede haber algunos problemas menores al formatear / cambiar el código para responder aquí. Verifique el código antes de implementar.

0
Arun Xavier 24 may. 2016 a las 08:35

He creado un violín: http://jsfiddle.net/h5my29aL/

No es tan dificil. Piense en su objeto como un planeta y su cámara como un satélite. Debe colocar la cámara en algún lugar de una órbita cerca de su objeto. Tres contiene una función distanceTo que lo hace simple. El ejemplo usa una esfera, pero funcionará con una malla arbitraria. Mide la distancia desde el punto central al vector deseado3. En su caso, el vector3 es probablemente la posición de la cara devuelta por un rayo selector. Pero de todos modos, el lookAt se establece en la malla, y luego se calcula una distancia desde el vértice para que la cámara esté siempre a la misma altitud, independientemente de la distancia de un vértice o cara desde el centro del objeto.

var point = THREE.GeometryUtils.randomPointsInGeometry( geometry, 1 );

    var altitude = 100;

    var rad = mesh.position.distanceTo( point[0] );
    var coeff = 1+ altitude/rad;

    camera.position.x = point[0].x * coeff;
    camera.position.y = point[0].y * coeff;
    camera.position.z = point[0].z * coeff;
    camera.lookAt(mesh.position);
1
Radio 13 may. 2016 a las 15:21

La posición es un poco complicada de calcular; debe encontrar el segmento entre la cámara y la intersección y luego colocar la cámara a una distancia específica de la intersección a lo largo del segmento mirando hacia el punto de intersección.

Prueba esto:

var length=[the desiderated distance camera-intersection]
var dir = camera.position.clone().sub(intersects[0].point).normalize().multiplyScalar(length);
camera.position = intersects[0].point.clone().add(dir);
camera.lookAt(intersects[0].point);
3
Davide Necchi 11 may. 2016 a las 08:46