CESIUM例子学习(十一)——3DTiles Clipping Planes(1)
3DTiles Clipping Planes例子,可以很容易實(shí)現(xiàn)對(duì)BIM、Point Cloud、Instanced、Model的任意剖切,其中Instanced是到底是一個(gè)什么對(duì)象,是怎么來的還不清楚。3DTiles Clipping Planes,對(duì)于BIM說來應(yīng)用場(chǎng)景是有的,比如,需要查看一個(gè)建筑內(nèi)部,應(yīng)用從上到下的剖分,可以查看內(nèi)部的結(jié)構(gòu)。但對(duì)于點(diǎn)云和model有什么用呢?反正到現(xiàn)在我還沒想出來。但從學(xué)習(xí)的角度去看,還是可以的。先從簡(jiǎn)單的模型剖切開始。
一、創(chuàng)建clippingPlanes并綁定到模型
直接使用?new Cesium.ClippingPlaneCollection創(chuàng)建clippingPlanes。從里面的參數(shù)可以看到創(chuàng)建多個(gè)剖切面,設(shè)置切面與模型相交線的線寬,如果不需要切面邊線,可設(shè)置為0;設(shè)置剖切面的顏色等。創(chuàng)建ClippingPlane時(shí)傳入的有一個(gè)new?Cesium.Cartesian3參數(shù),它定義了剖切面的任意性,傳入不同參數(shù),得到不同喑切面。如下圖是一個(gè)(1.0,1.0,-1.0)剖切面:
clippingPlanes綁定到模型只需要在創(chuàng)建模型entity時(shí),把clippingPlanes作為可選參數(shù)即可。代碼如下:
function loadModel (url) {clippingPlanes = new Cesium.ClippingPlaneCollection({planes: [//切面new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0),0.0),],edgeWidth: 2.0,// 切面與模型相交線的線寬,如果不需要切面邊線,可設(shè)置為0edgeColor: planeColor //切面顏色});var position = Cesium.Cartesian3.fromDegrees(116.43299999999988, 39.915999999999954, 300.0);var heading = Cesium.Math.toRadians(135.0);var pitch = 0.0;var roll = 0.0;var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);var orientation = Cesium.Transforms.headingPitchRollQuaternion(position,hpr);var entity = viewer.entities.add({name: url,position: position,orientation: orientation,model: {uri: url,scale: 8,minimumPixelSize: 100.0,clippingPlanes: clippingPlanes,//設(shè)置模型切面},});viewer.flyTo(entity)//加載切面到場(chǎng)景中for (var i = 0; i < clippingPlanes.length; ++i) {var plane = clippingPlanes.get(i);viewer.entities.add({position: position,orientation: orientation,plane: {dimensions: new Cesium.Cartesian2(50.0, 50.0),material: planeColor.withAlpha(0.1),plane: new Cesium.CallbackProperty(createPlaneUpdateFunction(plane), false),outline: true,outlineColor: planeColor,},});} } function createPlaneUpdateFunction (plane) {return function () {plane.distance = targetY;return plane;}; }代碼中創(chuàng)建?一個(gè)垂直于z軸的剖切面,并在創(chuàng)建模型時(shí)綁定到模型上,至此,剖切面已經(jīng)起作用。要注意的是源碼中有一個(gè)問題,模型的方向矩陣沒有應(yīng)用到剖切面上,即:模型使用了??orientation:?orientation,但剖切面沒有使用?:orientation:?orientation。如果模型有平移、旋轉(zhuǎn)操作時(shí)剖切面與被切面不一致。模型旋轉(zhuǎn)了135度,但剖切面沒有旋轉(zhuǎn),如下圖:
正常代碼繪制結(jié)果,如下圖:
從正常繪制結(jié)果圖來看,剖切面的大小并不影響剖切完整性,即剖切面小于模型也能完整切割,其它繪制剖切面也只是顯示效果和鼠標(biāo)的交互操作,并沒有別的作用。
二、鼠標(biāo)交互
鼠標(biāo)交互就是在加載剖切面時(shí)為plane設(shè)置一個(gè)屬性回調(diào)函數(shù),用回調(diào)函數(shù)實(shí)時(shí)更新plane的distance屬性,從而得到不同的剖切面。關(guān)鍵代碼:??plane:?new?Cesium.CallbackProperty(createPlaneUpdateFunction(plane),?false)。整個(gè)鼠標(biāo)交互代碼如下:
function addListener () {let scene = viewer.scenevar handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction(function (down) {var pickedObject = scene.pick(down.position);if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id) && Cesium.defined(pickedObject.id.plane)) {selectedPlane = pickedObject.id.plane;selectedPlane.material = planeColor.withAlpha(0.05);selectedPlane.outlineColor = planeColor;scene.screenSpaceCameraController.enableInputs = false;}}, Cesium.ScreenSpaceEventType.LEFT_DOWN);handler.setInputAction(function () {if (Cesium.defined(selectedPlane)) {selectedPlane.material = planeColor.withAlpha(0.1);selectedPlane.outlineColor = planeColor;selectedPlane = undefined;}scene.screenSpaceCameraController.enableInputs = true;}, Cesium.ScreenSpaceEventType.LEFT_UP);handler.setInputAction(function (movement) {if (Cesium.defined(selectedPlane)) {console.log('movement.endPosition=', movement.endPosition)var deltaY = movement.startPosition.y - movement.endPosition.y;console.log('deltaY=', deltaY)var deltaX = movement.startPosition.x - movement.endPosition.x;console.log('deltaX=', deltaX)targetY += deltaY;}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE); }三、問題
從交互代碼中可以看到,是利用鼠標(biāo)在屏幕上的坐標(biāo)來直接設(shè)置,在鼠標(biāo)拖動(dòng)函數(shù)中
var?deltaY?=?movement.startPosition.y?-?movement.endPosition.y;targetY?+=?deltaY;在屬性回調(diào)函數(shù)中:
?plane.distance?=?targetY;但問題是,雖然鼠標(biāo)y值能反應(yīng)出物體在地表的上下關(guān)系,但數(shù)值并不是一致的。也就是plane.distance與屏幕坐標(biāo)的數(shù)值不是一回事。plane.distance單位應(yīng)該是米,而屏幕坐標(biāo)是px。所以直接加就會(huì)出現(xiàn)問題,鼠標(biāo)與剖切面不在一起。因?yàn)槭髽?biāo)向上移動(dòng)1px,而剖切面向上移動(dòng)1米。如下圖:
但是現(xiàn)在也沒有更好的解決方案。問題先放著吧。
總結(jié)
以上是生活随笔為你收集整理的CESIUM例子学习(十一)——3DTiles Clipping Planes(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决:Clipping input da
- 下一篇: 移动安全--22--Android应用安