我正在尝试使用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的新手,刚刚开始学习它。如果某些或某些逻辑错误帮助我。
答案 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的例子中得到了我想要的东西。
这就是我所做的。
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);
}
}
由于格式化/更改了此处的回答代码,因此可能存在一些小问题。在实施之前检查代码。