在three.js中创建出来的几何体都是平行于坐标轴的,有时候我们在项目中需要对几何体的姿态进行一定的变化,举个例子,我们给地球添加一个地点标注的时候,所创建的地点标注应该是和地球相切的,而不是平行于坐标轴。下面是对几何体姿态进行变化的方法。
1、geometry的姿态变化
1.1、平移再旋转
geometry.translate(0, 0, height/2+R); //平移柱子到地球表面
const SphereCoord = lon2xyz(R, coord[i][0], coord[i][1]); //经纬度坐标转球面坐标
geometry.lookAt(new Vector3(SphereCoord.x, SphereCoord.y, SphereCoord.z)); //通过looKAt调整几何体姿态变化
1.2、旋转再平移
// 经纬度转球面坐标
var SphereCoord = lon2xyz(R, 0, 0);//SphereCoord球面坐标
// 先旋转后平移
geometry.lookAt(new THREE.Vector3(SphereCoord.x, SphereCoord.y, SphereCoord.z));
// 沿着旋转后柱子高度方向平移
var v3 = new Vector3(SphereCoord.x, SphereCoord.y, SphereCoord.z).normalize().multiplyScalar(R+height / 2);
geometry.translate(v3.x, v3.y, v3.z);
使用geometry进行姿态变化的话,一般都是场景中有大量的几何体需要进行姿态变化,可以提高渲染的效率(将所进行姿态变化后的几何体放数组里,使用BufferGeometryUtils.mergeBufferGeometries(geometryArr)进行合并渲染)。lookAt()实际是四元数的变化。
2、mesh的姿态变化
this.mesh = new Mesh(this.geometry, this.material);
const coord = lon2xyz(R, log, lat); //经纬度转球面坐标
this.mesh.position.set(coord.x, coord.y, coord.z);//设置模型的位置
// 模型姿态设置
const markNormal = new Vector3(coord.x, coord.y, coord.z).normalize();//归一化相当于创建一个单位向量
const normal = new Vector3(0, 0, 1); //mesh初始的法向量
// 四元数旋转姿态变化
this.mesh.quaternion.setFromUnitVectors(normal, markNormal); //normal法向量转换为markNormal法向量
return this.mesh;