这一小节主要学的是关于物体的位置移动,旋转,缩放一系列操作。
Vector3
mesh
网格物理模型中的position
属性是继承于Vector3
的。Vector3
是一个类,用于定位空间中的东西。
Vector3
有很多有用的方法。例如Vector3中介绍的
//打印模型到场景中心的距离
console.log(cube.position.length());//打印两个不同Vector3之间的距离,这里是模型到相机的距离
//也可以是一个指定坐标的Vector3之间的距离
console.log(cube.position.distanceTo(camera.position));
console.log(cube.position.distanceTo(new THREE.Vector3(0, 1, 2)));//使用normalize将模型的位置重置为1,无论之前位置在哪
cube.position.normalize();//使用set更改模型位置
cube.position.set(0, 0, 0);
辅助观察坐标系
//AxesHelper:辅助观察的坐标系,参数为辅助线的长度,默认为1
//红轴为X轴,绿轴为Y轴,蓝轴为Z轴
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
等比例缩放模型
//使用scale修改模型的大小(?),等比例缩放
cube.scale.x = 1.2;
cube.scale.y = 0.7;
cube.scale.z = 0.5;
cube.scale.set(1.2, 0.7, 0.5);
旋转模型
使用rotation
旋转模型,rotation
有xyz三个参数(properties),但是它不是Vector3,它是一个Euler
When we change the x,y,and z properties we can imagine putting a stick through your object's center in the axis's direction and then rotating that object on that stick.
当我们更改x、y和z属性时,我们可以想象将一根棍子沿着轴的方向穿过物体的中心,然后旋转那根棍子上的物体。
//值以弧度表示,转半圈大约是3.14159,可以使用Math.PI
cube.rotation.y = 3.14159;
cube.rotation.y = Math.PI;//同时,为了确保旋转不出错,可以使用gimbal lock(万向节锁?),reorder,也就是调整了旋转的顺序
//下面这个是先x轴旋转,然后是y轴旋转
cube.rotation.x = 3.14159;
cube.rotation.y = Math.PI;
//如果这样写,那就是先旋转y轴,在旋转x轴
cube.rotation.reorder('YXZ')
cube.rotation.x = 3.14159;
cube.rotation.y = Math.PI;
Euler
旋转是很容易理解的,但是由于不同的旋转顺序会得到不同的旋转结果,所以在THREE.js和3D软件中,都使用Quaternion来表示旋转,Quaternion
是一种更加数学的表达方式。
在旋转物体(改变rotation
)时,Quaternion
就会更新。
还可以使用.lookAt
方法实现旋转,这个方法会将物体的负z面
面对你所填入的目标。
Object3D instances have a lookAt(...)method which rotates the object so that its -z faces the target you provided.The target must be a Vector3
//将摄像机朝向某个模型
camera.lookAt(0, 0, 0);
camera.lookAt(cube.position);
Group
为了方便操作,可以将很多个Object
放入一个Group中,并对这个Group
使用position
,rotation
,scale
,lookAt
这些操作
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );const cubeA = new THREE.Mesh( geometry, material );
cubeA.position.set( 100, 100, 0 );const cubeB = new THREE.Mesh( geometry, material );
cubeB.position.set( -100, -100, 0 );//create a group and add the two cubes
//These cubes can now be rotated / scaled etc as a group
const group = new THREE.Group();
group.add( cubeA );
group.add( cubeB );//do something about group
group.scale.set(5, 0.5, 1);
group.rotation.y = Math.PI * 0.25;
group.rotation.x = Math.PI * 0.25;scene.add( group );