这是3D可视化教程系列的文章,如果第一次阅读请先阅读《3D可视化教程导读》

源码及3D项目文件

  源码及工程项目都放到github上。
  源码:threejs-example

效果

  可在线访问看效果8-聚焦靠近 展示网址。双击物体时,摄像头聚焦并不断靠近该物体:
8-聚焦

代码说明

  Three.js官方自己搞的编辑器editor里有一个叫focus的函数,就是实现此功能,可自行搜索其源代码。我在它的源代码的基础上,添加了“摄像头慢慢移动到指定位置”以及“orbit修改”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
const box = new THREE.Box3();
const delta = new THREE.Vector3();
const center = new THREE.Vector3();
const sphere = new THREE.Sphere();
// 聚焦靠近
function focus ( target ) {

var distance;

box.setFromObject( target );
// 计算物体的大小
if ( box.isEmpty() === false ) {

box.getCenter( center );
distance = box.getBoundingSphere( sphere ).radius;

} else {

// Focusing on an Group, AmbientLight, etc

center.setFromMatrixPosition( target.matrixWorld );
distance = 0.1;

}
// 物体中心位置 再加上该物体大小的4倍作为间距,得到摄像头新位置
delta.set( 0, 0, 1 );
delta.applyQuaternion( camera.quaternion );
delta.multiplyScalar( distance * 4 );
// 摄像头从原位置 到新位置
const cameraStart = camera.position.clone();
const cameraEnd = center.add( delta );
// orbit 从原目标位置 到新目标位置,新目标为所聚焦的物体。
const orbitStart = orbit.target.clone();
const orbitEnd = target.position.clone();

const start = {
cameraX:cameraStart.x,
cameraY:cameraStart.y,
cameraZ:cameraStart.z,
orbitX:orbitStart.x,
orbitY:orbitStart.y,
orbitZ:orbitStart.x,
};

const end = {
cameraX:cameraEnd.x,
cameraY:cameraEnd.y,
cameraZ:cameraEnd.z,
orbitX:orbitEnd.x,
orbitY:orbitEnd.y,
orbitZ:orbitEnd.x,
};

const position = target.position;
orbit.target.set(position.x || 0.01,position.y|| 0.01,position.z|| 0.01);
new TWEEN.Tween(start)
.to(end, 1000)
.onUpdate(function (val) {
// 改变摄像头位置
camera.position.set(val.cameraX || 0, val.cameraY || 0, val.cameraZ || 0);
// 改变orbit 目标位置
orbit.target.set(val.orbitX || 0,val.orbitY|| 0,val.orbitZ|| 0);
orbit.update();
})
.start();
}

只聚焦到物体正面

  在实际业务中,我们聚焦物体时,不仅仅是想把摄像头移动并对准该物体,还想对准的是该物体的“正面”,而不是其它角度。 单纯靠代码是无法判断该模型的正面到底是哪里,所以要想实现这个功能,就需要另外想办法实现。
  我的解决方案是,定一个判断物体正面的规则,我建模时必须保证从X轴正方向 向 原点看该物体,就是该物体的正面。然后我代码里,在计算间距时,就只添加其正X轴的值,就可以实现对准该物体的正面。