1. 程式人生 > 其它 >Cesium隨筆:視錐繪製(下)

Cesium隨筆:視錐繪製(下)

0.前言

上一次Cesium隨筆中介紹的視錐的繪製方法並不準確,使用camera.debugShow便可以檢查到實際視錐和我們計算的視錐的姿態的誤差情況,本文將簡單介紹正確的視錐繪製方法,重點說明怎麼根據兩點來計算視錐的姿態。
筆者的可視域分析已經成功做出來,使用ShadowMap並對ShadowMapShader進行修改便可以實現(需要在原始碼中修改GLSL以改變陰影著色效果),不過後續生產環境還需要藉助後期處理技術將功能獨立出來。

GIF.gif

1.根據兩點計算相機射向

參考自SandCastle裡面的根據兩點計算射線的例子,

let spotLightCamera = new Cesium.Camera(window.app.viewer.scene);
let direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(this.secondPos, this.firstPos, new Cesium.Cartesian3()), new Cesium.Cartesian3());
spotLightCamera.position = this.firstPos;//firstPos是相機起點
spotLightCamera.direction=direction;//direction是相機面向的方向


2.視錐繪製部分

視錐繪製程式碼參考自Cesium原始碼中的Camera debug show部分

let scratchRight = new Cesium.Cartesian3();
let scratchRotation = new Cesium.Matrix3();
var scratchOrientation = new Cesium.Quaternion();
let position = spotLightCamera.positionWC;
let direction = spotLightCamera.directionWC;
let up = spotLightCamera.upWC;
let right = spotLightCamera.rightWC;
right = Cesium.Cartesian3.negate(right, scratchRight);

let rotation = scratchRotation;
Cesium.Matrix3.setColumn(rotation, 0, right, rotation);
Cesium.Matrix3.setColumn(rotation, 1, up, rotation);
Cesium.Matrix3.setColumn(rotation, 2, direction, rotation);
//計算視錐姿態
let orientation = Cesium.Quaternion.fromRotationMatrix(rotation, scratchOrientation);
//視錐輪廓線圖形
let instanceOutline = new Cesium.GeometryInstance({
                geometry: new Cesium.FrustumOutlineGeometry({
                    frustum: spotLightCamera.frustum,
                    origin: this.firstPos,
                    orientation: orientation
                }),
                id: "pri" + window.app.viewer.scene.primitives.length + 1,
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 0.0, 1.0)),
                    show: new Cesium.ShowGeometryInstanceAttribute(true)
                }
            });
//新增圖元
let newPrimitive = window.app.viewer.scene.primitives.add(new Cesium.Primitive({
                geometryInstances: instanceOutline,
                appearance: new Cesium.PerInstanceColorAppearance()
            }));

對了,上述程式碼之前別忘了先修改視錐的相關引數(不修改的話使用預設引數畫出來的視錐會突破天際),上一篇隨筆中有相關引數的說明。

spotLightCamera.frustum.near=1;
spotLightCamera.frustum.far=100;

除了上述方法外還可以直接使用DebugCameraPrimitive實體繪製視錐,但缺點是該實體好像不方便修改near和far引數。

3.總結

Cesium中模型的平移、縮放、旋轉是通過ModelMatrix這個矩陣引數來實現的,學好矩陣運算對理解三維世界很有幫助。

本文轉自 https://www.jianshu.com/p/f2c9a4cac078

,如有侵權,請聯絡刪除。