tileset.modelMatrix
这个属性能够在数据自己的基础上再进行坐标变换,不熟悉转换矩阵各个部分的含义的可参考图形学有关资料。算法
此文不必定是最佳算法,可是提供一种思路。转载请注明出处 全网@秋意正寒 。性能
tileset.modelMatrix
tileset .readyPromise .then(tileset => { const tileset_center = tileset.boundingSphere.center; // Cartesian3 const frompoint_to_world_matrix = Cesium.Transforms.eastNorthUpToFixedFrame(tileset_center); // Matrix4 const local_translation = new Cesium.Cartesian3(310, -140, 10); // 向模型中心为原点,正北为y,正东为x,地心朝上为z分别平移 3十、-140、10米 const result = new Cesium.Cartesian3(0,0,0); Cesium.Matrix4.multiplyByPoint(frompoint_to_world_matrix, local_translation, result); // 转换矩阵左乘局部平移向量,结果存储在 result 中,结果是世界坐标下的平移终点向量 const targetpoint_to_world_matrix = Cesium.Transforms.eastNorthUpToFixedFrame(result); const world_translation = new Cesium.Cartesian3( targetpoint_to_world_matrix[12] - frompoint_to_world_matrix[12], targetpoint_to_world_matrix[13] - frompoint_to_world_matrix[13], targetpoint_to_world_matrix[14] - frompoint_to_world_matrix[14], ); // 向量相减,获得世界坐标下的平移向量 tileset.modelMatrix = Cesium.Matrix4.fromTranslation(world_translation); // 构造平移矩阵并赋值 viewer.zoomTo(tileset); });
解释:spa
cesium 的场景数据最终都是世界坐标的,因此要求的是绿向量的世界坐标表达,而后构造平移矩阵。code
如今是已知红向量和局部坐标的绿向量,要先求蓝向量,才能获得世界坐标的绿向量。orm
先平移到世界坐标中心,而后在世界坐标中心求平移,最后再移动回原点。blog
tileset.modelMatrix
\(= M_{backToOrigin}·M_{localTranslation}·M_{moveToWorldCenter}\)ip
读者可自行实现。get
局部旋转,应该先将模型移动到世界坐标中心,旋转后,再移动到原来的地方io
即console
tileset.modelMatrix
\(= M_{backToOrigin}·M_{localRotate}·M_{moveToWorldCenter}\)
其中,\(M_{moveToWorldCenter}\) 是一个平移矩阵,只需使用模型中心向量取个负值便可
\(M_{backToOrigin}\) 则是从世界坐标中心再移动到模型原点
注意,这里是左乘优先顺序,从右往左乘。
旋转矩阵比较容易构造,就不细说了。
这个思路的计算量比较大!
tileset .readyPromise .then(tileset => { const tileset_center = tileset.boundingSphere.center; // Cartesian3 //console.log(tileset_center); const backto_matrix = Cesium.Matrix4.fromTranslation(tileset_center); const moveto_vec = Cesium.Cartesian3.multiplyByScalar(tileset_center, -1, new Cesium.Cartesian3()); //console.log(moveto_vec); const moveto_matrix = Cesium.Matrix4.fromTranslation(moveto_vec); /* 绕x(即东方轴)转90度 */ const cos_rotateX = Math.cos(Math.PI/2); const sin_rotateX = Math.sin(Math.PI/2); const arr = [1,0,0,0, 0, cos_rotateX, sin_rotateX,0, 0,-sin_rotateX,cos_rotateX,0, 0,0,0,1]; const rotateX_matrix = Cesium.Matrix4.fromArray(arr); /* 计算最终矩阵 */ const temp = Cesium.Matrix4.multiply(rotateX_matrix, moveto_matrix, new Cesium.Matrix4()); const r = Cesium.Matrix4.multiply(backto_matrix, temp, new Cesium.Matrix4()); tileset.modelMatrix = r; // 构造平移矩阵并赋值 viewer.zoomTo(tileset); });
能够看到会产生很是多中间变量,会引起 JS 的GC,并且矩阵计算自己也比较复杂。
缩放思路和旋转相似,先移动到世界坐标系中心,缩放,而后再移动到原来的地方
tileset.modelMatrix
\(= M_{backToOrigin}·M_{localScale}·M_{moveToWorldCenter}\)
读者可自行实现。
思路不必定是最佳算法,有更高性能的算法可在评论区指出。