把線條貼到3dtiles上需要用到兩個屬性:clampToGround和classificationType。
clampToGround屬性用來表示該線段要貼地。1.54版以後貼地中的地字同時指代地形和3dtiles數據。
貼地
地
還有一個屬性classificationType,則用來描述是否只貼地形(ClassificationType.TERRAIN),或者只貼3dtiles數據(ClassificationType.CESIUM_3D_TILE),或者二者都貼(ClassificationType.BOTH)。默認情況下是二者都貼。
Entity API源碼如下:
var polyline2 = viewer.entities.add({ polyline : { positions : positions2, clampToGround : true, width : 5, material : new Cesium.PolylineOutlineMaterialProperty({ color : Cesium.Color.ORANGE, outlineWidth : 2, outlineColor : Cesium.Color.BLACK }) } });
Primitive API源碼如下:
// Polyline Glow scene.groundPrimitives.add(new Cesium.GroundPolylinePrimitive({ geometryInstances : new Cesium.GeometryInstance({ geometry : new Cesium.GroundPolylineGeometry({ positions : positions, width : 10.0 }) }), appearance : new Cesium.PolylineMaterialAppearance({ material : Cesium.Material.fromType(Cesium.Material.PolylineGlowType) }) }));
Cesium 1.54版本以前,雖然可以做到幾何體貼地,但是只能純色貼入,並不能貼紋理。1.54版本以後,官方終於可以給3dtile數據貼上紋理了。效果如下:
源碼如下:
var entity = viewer.entities.add({ polygon : { hierarchy : new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromRadiansArray([-1.3194369277314022, 0.6988062530900625, -1.3193955980204217, 0.6988091578771254, -1.3193931220959367, 0.698743632490865, -1.3194358224045408, 0.6987471965556998])), material : ../images/Cesium_Logo_Color.jpg } });
Cesium增加了新的示例模型,路徑如下:
/Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf
相關測試源碼如下:
var viewer = new Cesium.Viewer(cesiumContainer);
var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 5000.0); var entity = viewer.entities.add({ position : position, model : { uri : ../../../Specs/Data/Models/Box-Textured-Webp/CesiumBoxWebp.gltf, minimumPixelSize : 128, maximumScale : 20000 } }); viewer.trackedEntity = entity;
下圖中綠色線條即恆向線。
可以觀察紅色線條和綠色線條的差別:給定的起點和終點相同,但是繪製出來的線條卻不一樣。其中紅色線條描述的是地表最近距離的曲線,而綠色線條則描述的是恆向線,任意位置的延伸方向都是恆定的。圖中起點和終點的緯度都是35,所以綠色線條是和35度緯度線是重合的。
var redLine = viewer.entities.add({ name : Red line on terrain, polyline : { positions : Cesium.Cartesian3.fromDegreesArray([-75, 35, -125, 35]), width : 5, material : Cesium.Color.RED, clampToGround : true } });
var greenRhumbLine = viewer.entities.add({ name : Green rhumb line, polyline : { positions : Cesium.Cartesian3.fromDegreesArray([-75, 35, -125, 35]), width : 5, arcType : Cesium.ArcType.RHUMB, material : Cesium.Color.GREEN }
Polylines on 3D Tiles示例用來描述將線段貼到3dtiles上,其中3dtiles數據有有兩類。一類是傾斜攝影的,另外一類是BIM的。在電廠BIM模型的示例中可以看出,線條是貼在BIM模型的管線上的。
點擊查看本地Demo(需要本地編譯源碼才可使用)
從上面的截圖可以看出,貼地模式下線條是貼到3dtiles數據上了,不過會從上往下貫穿所有地方,畢竟沒有高度上的限制,這樣的話,對於BIM數據其實還是有問題的。有些地方並沒有管線,但是照樣會畫上線條。
貼地模式使用起來也很簡單,只需要用到clampToGround和classificationType屬性,另外注意一下,height不要賦值。源碼截取如下:
var powerplant = scene.primitives.add( new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(8564), show: false }) ); var pipes = viewer.entities.add({ polyline : { positions : Cesium.Cartesian3.fromDegreesArray([ -76.36053390920833, 34.949935893493596, -76.36055481641581, 34.94993589886988, -76.36055477047704, 34.94992280693651 ]), width : 6, material : new Cesium.PolylineDashMaterialProperty({ color : Cesium.Color.YELLOW, dashLength: 20.0 }), show: false, clampToGround : true, classificationType: Cesium.ClassificationType.CESIUM_3D_TILE } });
這個示例用來展示輪胎轉速隨車輛運動速度快慢自動調整。該示例代碼則描述如何將position轉化為速度,再轉化為輪胎轉動角度,最後通過nodeTransformations屬性作用於Model,從而實現車輛輪胎的轉動。
源碼截取如下,position是一個SamplePositionProperty,通過在不同的時間點上設置不同的運動位置,來創建一個加速運動的車輛。velocityVectorProperty則根據position計算出每個時間點的速度。再由速度計算出輪胎轉動的角度。(註:貌似這個地方的角度計算只是近似值,只有numberOfSamples越大時越準確。)
var numberOfSamples = 100; for (var i = 0; i <= numberOfSamples; ++i) { var factor = (i / numberOfSamples); var time = Cesium.JulianDate.addSeconds(start, factor * totalSeconds, new Cesium.JulianDate());
// Lerp using a non-linear factor so that the vehicle accelerates. var locationFactor = Math.pow(factor, 2); var location = Cesium.Cartesian3.lerp(startPosition, endPosition, locationFactor, new Cesium.Cartesian3()); position.addSample(time, location); // Rotate the wheels based on how fast the vehicle is moving at each timestep. velocityVectorProperty.getValue(time, velocityVector); var metersPerSecond = Cesium.Cartesian3.magnitude(velocityVector); var wheelRadius = 0.52;//in meters. var circumference = Math.PI * wheelRadius * 2; var rotationsPerSecond = metersPerSecond / circumference;
wheelAngle += ((Math.PI * 2 * totalSeconds) / numberOfSamples) * rotationsPerSecond; wheelAngleProperty.addSample(time, wheelAngle); }
歡迎關注 Cesium實驗室 ,QQ群號:595512567。