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}\)
讀者可自行實現。
思路不必定是最佳算法,有更高性能的算法可在評論區指出。