单击以将相机放置在 Three js 中的对象附近

Click to place camera near an object in Three js

我正在尝试使用 Three.js 进行点击缩放功能,我有一个 canvas 和一个加载到 canvas.On 中的对象 我正在尝试放置相机在交点附近(实际上就像放大那个点)。

这是我所做的,但没有按我想要的方式工作,点击相机位置会发生变化,但部分工作有时相机位于交叉点附近,有时则不然。

 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;



                }

            };

这里 self 是一个全局查看器对象,它包含相机、canvas、不同的对象等

0.9 只是一个数字,用于将相机放置在交点附近。

使用的相机是 PerspectiveCamera,控件是 TrackballControls

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

加载的对象来自 .obj 或 .dae 文件,我希望它的工作方式类似于单击对象上的任意点并将相机放在该点附近。但是相机在移动,但有时不在我点击的位置附近。

我是三个 js 的新手,刚开始学习 it.If 某些东西或某些逻辑错误帮助我。

位置计算有点复杂;您必须找到相机和交叉点之间的线段,然后将相机放置在距交叉点特定距离处,沿着线段寻找交叉点。

试试这个:

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

我创建了一个fiddle:http://jsfiddle.net/h5my29aL/

没那么难。把你的物体想象成一颗行星,把你的相机想象成一颗卫星。您需要将相机定位在靠近物体的轨道中的某个位置。三包含 distanceTo 函数,使其变得简单。该示例使用球体,但它适用于任意网格。它测量从中心点到所需 vector3 的距离。在您的情况下, vector3 可能是拾取器射线返回的面部位置。但无论如何,lookAt 设置为网格,然后计算与顶点的距离,以便无论顶点或面与对象中心的距离如何,相机始终处于相同的高度。

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

通过 Three js 中的示例,我已经接近我想要的结果。

Three JS webgl_decals

这就是我所做的。

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

我formatted/changed这里回答的代码可能会有一些小问题。执行前检查代码。