单击将相机放在三个js中的对象附近

时间:2016-05-11 05:47:36

标签: javascript math camera three.js raycasting

我正在尝试使用Three.js进行单击缩放功能,我在画布中加载了画布和一个对象。单击我试图将相机放置在交叉点附近(实际上就像缩放那样点)。

这就是我所做的,但是没有按照我想要的方式工作,点击相机位置的变化,但有时工作有时候相机会被放置在交叉点附近,有时则没有。

 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是一个全局查看器对象,它包含相机,画布,不同对象等。

0.9只是用于将相机放置在交叉点附近的数字。

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

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

加载的对象来自.obj或.dae文件,我希望这可以像点击对象上的任何点一样工作,并将相机放在该点附近。但相机正在移动,但有时并不接近我点击的位置。

  • intersects[0]是否给出了最近的交点?或者最靠近相机的方向?
  • 这里我的错误是什么?

我是三个j的新手,刚刚开始学习它。如果某些或某些逻辑错误帮助我。

3 个答案:

答案 0 :(得分:3)

计算位置有点复杂;你必须找到摄像机和交叉路口之间的段,然后将摄像机放置在沿着看到交叉点的段的交叉点的特定距离处。

试试这个:

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

答案 1 :(得分:1)

我创造了一个小提琴:http://jsfiddle.net/h5my29aL/

这并不困难。将您的物体视为行星,将您的相机视为卫星。您需要将摄像机放置在靠近物体的轨道上的某个位置。 Three包含一个distanceTo函数,使其变得简单。该示例使用了一个球体,但它可以使用任意网格。它测量从中心点到所需矢量的距离3。在您的情况下,vector3可能是拾取器光线返回的面部位置。但无论如何,lookAt被设置为网格,然后计算距顶点的距离,使得无论顶点或面与对象中心的距离如何,摄像机始终都是相同的高度。 / p>

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

答案 2 :(得分:0)

我从三个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);
                }
            }

由于格式化/更改了此处的回答代码,因此可能存在一些小问题。在实施之前检查代码。