bruce-cesium 7.1.4 → 7.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bruce-cesium.es5.js +200 -39
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +198 -37
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +1 -1
- package/dist/lib/rendering/displaced-surface-primitive.js +42 -31
- package/dist/lib/rendering/displaced-surface-primitive.js.map +1 -1
- package/dist/lib/rendering/entity-render-engine-polygon.js +20 -4
- package/dist/lib/rendering/entity-render-engine-polygon.js.map +1 -1
- package/dist/lib/rendering/texture-frame-series-animator.js +135 -1
- package/dist/lib/rendering/texture-frame-series-animator.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +1 -1
- package/dist/types/rendering/displaced-surface-primitive.d.ts +5 -0
- package/dist/types/rendering/texture-frame-series-animator.d.ts +28 -0
- package/package.json +2 -2
package/dist/bruce-cesium.es5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as Cesium from 'cesium';
|
|
2
|
-
import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature,
|
|
3
|
-
import { Cartes, Entity as Entity$1, ENVIRONMENT, Calculator, ClientFile,
|
|
2
|
+
import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, DistanceDisplayCondition, ShaderSource, Cartesian3, Math as Math$1, Ellipsoid, Transforms, Matrix4, Geometry, GeometryAttribute, ComponentDatatype, PrimitiveType, BoundingSphere, GeometryPipeline, sampleTerrain, Texture, PixelFormat, Sampler, TextureWrap, TextureMinificationFilter, TextureMagnificationFilter, VertexArray, BufferUsage, ShaderProgram, RenderState, BlendingState, DrawCommand, Pass, Cartesian2, HeightReference, HorizontalOrigin, VerticalOrigin, ClassificationType, ConstantPositionProperty, ArcType, CornerType, ShadowMode, ColorBlendMode, HeadingPitchRoll, Model, JulianDate, Quaternion, ImageMaterialProperty, PolygonHierarchy, PolylineGraphics, Rectangle, SceneTransforms, NearFarScalar, Matrix3, KmlDataSource, GeoJsonDataSource, SceneMode, Ion, IonResource, Cesium3DTileStyle, HeadingPitchRange, Cesium3DTileColorBlendMode, OrthographicFrustum, EasingFunction, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, Cesium3DTileset, Intersect, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, CustomDataSource, PolygonPipeline, CesiumInspector, ClockRange, GeometryInstance, ScreenSpaceEventHandler, ScreenSpaceEventType, Fullscreen, CzmlDataSource } from 'cesium';
|
|
3
|
+
import { Cartes, Entity as Entity$1, ENVIRONMENT, Api, Calculator, ClientFile, EntityTag, EntityType, LRUCache, ObjectUtils, Style, Carto, Geometry as Geometry$1, EntityLod, MenuItem, ProjectView, ProjectViewBookmark, Tileset, ZoomControl, Bounds, Color as Color$1, BruceEvent, EntityCoords, DataLab, DelayQueue, EntityHistoricData, BruceApi, AccountConcept, RecordChangeFeed, EntityRelation, ProgramKey, EntitySource, Camera, ProjectViewTile, ProjectViewLegacyTile, Account, AccountLimits, Session, UrlUtils, ProjectViewBookmarkGroup, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, EntityRelationType } from 'bruce-models';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Ensures a number is returned from a given value.
|
|
@@ -39734,15 +39734,68 @@ var TextureFrameSeriesAnimator;
|
|
|
39734
39734
|
return Boolean(data && data.generation && Array.isArray(data.generation.Frames) && data.generation.Frames.length > 0);
|
|
39735
39735
|
}
|
|
39736
39736
|
TextureFrameSeriesAnimator.IsFrameArchiveMetadata = IsFrameArchiveMetadata;
|
|
39737
|
+
// How far covered values bleed outward into uncovered texels before the GPU samples them.
|
|
39738
|
+
const VALUE_DILATE_PASSES = 2;
|
|
39739
|
+
/*
|
|
39740
|
+
* Bleeds covered values outward into uncovered texels, leaving alpha untouched.
|
|
39741
|
+
*
|
|
39742
|
+
* The GPU samples the value texture with linear filtering, so an uncovered texel's RGB still gets
|
|
39743
|
+
* averaged into the vertices next to it even though its alpha is zero. Land sits at one end of the
|
|
39744
|
+
* ramp, so without this the coastline grows a row of spikes exactly where the data stops. Masking the
|
|
39745
|
+
* baseline creates more of these edges, which is what makes this necessary rather than cosmetic.
|
|
39746
|
+
*/
|
|
39747
|
+
function dilateValues(value, width, height, passes) {
|
|
39748
|
+
const texels = width * height;
|
|
39749
|
+
const filled = new Uint8Array(texels);
|
|
39750
|
+
for (let p = 0; p < texels; p++) {
|
|
39751
|
+
filled[p] = value[p * 4 + 3] !== 0 ? 1 : 0;
|
|
39752
|
+
}
|
|
39753
|
+
for (let pass = 0; pass < passes; pass++) {
|
|
39754
|
+
const source = value.slice();
|
|
39755
|
+
const wasFilled = filled.slice();
|
|
39756
|
+
for (let y = 0; y < height; y++) {
|
|
39757
|
+
for (let x = 0; x < width; x++) {
|
|
39758
|
+
const p = y * width + x;
|
|
39759
|
+
if (wasFilled[p]) {
|
|
39760
|
+
continue;
|
|
39761
|
+
}
|
|
39762
|
+
let sum = 0;
|
|
39763
|
+
let hits = 0;
|
|
39764
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
39765
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
39766
|
+
const nx = x + dx;
|
|
39767
|
+
const ny = y + dy;
|
|
39768
|
+
if (nx < 0 || ny < 0 || nx >= width || ny >= height || !wasFilled[ny * width + nx]) {
|
|
39769
|
+
continue;
|
|
39770
|
+
}
|
|
39771
|
+
sum += source[(ny * width + nx) * 4];
|
|
39772
|
+
hits++;
|
|
39773
|
+
}
|
|
39774
|
+
}
|
|
39775
|
+
if (hits > 0) {
|
|
39776
|
+
const v = Math.round(sum / hits);
|
|
39777
|
+
value[p * 4] = v;
|
|
39778
|
+
value[p * 4 + 1] = v;
|
|
39779
|
+
value[p * 4 + 2] = v;
|
|
39780
|
+
filled[p] = 1;
|
|
39781
|
+
}
|
|
39782
|
+
}
|
|
39783
|
+
}
|
|
39784
|
+
}
|
|
39785
|
+
}
|
|
39737
39786
|
const DEFAULT_CROSSFADE_MS = 900;
|
|
39738
39787
|
const DEFAULT_LOW_COLOR = { red: 255, green: 255, blue: 255, alpha: 0.12 };
|
|
39739
39788
|
const DEFAULT_HIGH_COLOR = { red: 21, green: 96, blue: 196, alpha: 0.92 };
|
|
39740
39789
|
class Animator {
|
|
39741
39790
|
constructor(options) {
|
|
39742
|
-
var _a;
|
|
39791
|
+
var _a, _b;
|
|
39743
39792
|
this.removeOnTick = null;
|
|
39744
39793
|
this.removeCrossfadeTick = null;
|
|
39745
39794
|
this.disposed = false;
|
|
39795
|
+
// One alpha byte per texel, 1 meaning the texel is baseline. Fetched once, the mesh does not move.
|
|
39796
|
+
this.baselineFlags = null;
|
|
39797
|
+
this.baselineDims = null;
|
|
39798
|
+
this.baselineLoad = null;
|
|
39746
39799
|
this.currentFrameIndex = -1;
|
|
39747
39800
|
// Single-in-flight fetch queue: only one Range GET outstanding at a time, and the NEXT one
|
|
39748
39801
|
// is chosen right before sending, this is what makes reprioritizing mid-scrub take effect
|
|
@@ -39782,6 +39835,8 @@ var TextureFrameSeriesAnimator;
|
|
|
39782
39835
|
this.frameDims = new Array(this.frames.length).fill(null);
|
|
39783
39836
|
this.valueCache = new Array(this.frames.length).fill(null);
|
|
39784
39837
|
this.produceValueCanvas = Boolean(options.produceValueCanvas);
|
|
39838
|
+
this.baselineMaskEntry = options.baselineMask || null;
|
|
39839
|
+
this.maskBaseline = (_b = options.maskBaseline) !== null && _b !== void 0 ? _b : Boolean(options.baselineMask);
|
|
39785
39840
|
this.valueCanvas = this.produceValueCanvas ? document.createElement("canvas") : null;
|
|
39786
39841
|
this.driveMaterial = options.driveMaterial !== false;
|
|
39787
39842
|
this.originalMaterial = options.entity.polygon.material;
|
|
@@ -39951,6 +40006,12 @@ var TextureFrameSeriesAnimator;
|
|
|
39951
40006
|
if (this.disposed) {
|
|
39952
40007
|
return;
|
|
39953
40008
|
}
|
|
40009
|
+
// Awaited before decoding rather than applied later, so no frame is ever cached unmasked and
|
|
40010
|
+
// then corrected once the mask lands.
|
|
40011
|
+
await this.ensureBaselineMask();
|
|
40012
|
+
if (this.disposed) {
|
|
40013
|
+
return;
|
|
40014
|
+
}
|
|
39954
40015
|
const decoded = await this.decodeAndTint(buffer);
|
|
39955
40016
|
if (this.disposed) {
|
|
39956
40017
|
return;
|
|
@@ -39985,8 +40046,81 @@ var TextureFrameSeriesAnimator;
|
|
|
39985
40046
|
// recovered from the tinted pixels afterwards.
|
|
39986
40047
|
const valuePixels = this.produceValueCanvas ? new Uint8ClampedArray(imageData.data) : undefined;
|
|
39987
40048
|
ApplyGrayscaleColorMask(imageData, this.lowColor, this.highColor);
|
|
40049
|
+
this.applyBaselineMask(imageData.data, valuePixels, canvas.width, canvas.height);
|
|
40050
|
+
if (valuePixels) {
|
|
40051
|
+
dilateValues(valuePixels, canvas.width, canvas.height, VALUE_DILATE_PASSES);
|
|
40052
|
+
}
|
|
39988
40053
|
return { pixels: imageData.data, width: canvas.width, height: canvas.height, valuePixels };
|
|
39989
40054
|
}
|
|
40055
|
+
/**
|
|
40056
|
+
* Fetches and decodes the archive's static baseline mask, at most once.
|
|
40057
|
+
*/
|
|
40058
|
+
ensureBaselineMask() {
|
|
40059
|
+
if (!this.maskBaseline || !this.baselineMaskEntry) {
|
|
40060
|
+
return Promise.resolve();
|
|
40061
|
+
}
|
|
40062
|
+
if (this.baselineLoad) {
|
|
40063
|
+
return this.baselineLoad;
|
|
40064
|
+
}
|
|
40065
|
+
const entry = this.baselineMaskEntry;
|
|
40066
|
+
const start = entry.ByteOffset;
|
|
40067
|
+
const end = entry.ByteOffset + entry.ByteLength - 1;
|
|
40068
|
+
this.baselineLoad = fetch(this.archiveUrl, { headers: { Range: `bytes=${start}-${end}` } })
|
|
40069
|
+
.then((response) => response.arrayBuffer())
|
|
40070
|
+
.then(async (buffer) => {
|
|
40071
|
+
if (this.disposed) {
|
|
40072
|
+
return;
|
|
40073
|
+
}
|
|
40074
|
+
const blob = new Blob([buffer], { type: "image/png" });
|
|
40075
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
40076
|
+
let image;
|
|
40077
|
+
try {
|
|
40078
|
+
image = await loadImage(objectUrl);
|
|
40079
|
+
}
|
|
40080
|
+
finally {
|
|
40081
|
+
URL.revokeObjectURL(objectUrl);
|
|
40082
|
+
}
|
|
40083
|
+
const canvas = document.createElement("canvas");
|
|
40084
|
+
canvas.width = image.width;
|
|
40085
|
+
canvas.height = image.height;
|
|
40086
|
+
const ctx = canvas.getContext("2d");
|
|
40087
|
+
ctx.drawImage(image, 0, 0);
|
|
40088
|
+
const pixels = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
40089
|
+
const flags = new Uint8Array(canvas.width * canvas.height);
|
|
40090
|
+
for (let p = 0; p < flags.length; p++) {
|
|
40091
|
+
flags[p] = pixels[p * 4 + 3] >= 128 ? 1 : 0;
|
|
40092
|
+
}
|
|
40093
|
+
this.baselineFlags = flags;
|
|
40094
|
+
this.baselineDims = { width: canvas.width, height: canvas.height };
|
|
40095
|
+
})
|
|
40096
|
+
.catch((e) => {
|
|
40097
|
+
// A missing or unreadable mask must not stop the animation; it just means nothing is hidden.
|
|
40098
|
+
console.warn("TextureFrameSeriesAnimator: could not load the baseline mask, drawing it instead.", e);
|
|
40099
|
+
});
|
|
40100
|
+
return this.baselineLoad;
|
|
40101
|
+
}
|
|
40102
|
+
/**
|
|
40103
|
+
* Clears alpha on baseline texels, which is what makes hiding the dry/land sentinel a render choice.
|
|
40104
|
+
*/
|
|
40105
|
+
applyBaselineMask(pixels, valuePixels, width, height) {
|
|
40106
|
+
const flags = this.baselineFlags;
|
|
40107
|
+
if (!flags || !this.baselineDims) {
|
|
40108
|
+
return;
|
|
40109
|
+
}
|
|
40110
|
+
// A mask from a different raster size cannot be indexed against this frame, and guessing a
|
|
40111
|
+
// resampling would silently hide the wrong ground.
|
|
40112
|
+
if (this.baselineDims.width !== width || this.baselineDims.height !== height) {
|
|
40113
|
+
return;
|
|
40114
|
+
}
|
|
40115
|
+
for (let p = 0; p < flags.length; p++) {
|
|
40116
|
+
if (flags[p]) {
|
|
40117
|
+
pixels[p * 4 + 3] = 0;
|
|
40118
|
+
if (valuePixels) {
|
|
40119
|
+
valuePixels[p * 4 + 3] = 0;
|
|
40120
|
+
}
|
|
40121
|
+
}
|
|
40122
|
+
}
|
|
40123
|
+
}
|
|
39990
40124
|
beginCrossfadeTo(idx) {
|
|
39991
40125
|
const to = this.frameCache[idx];
|
|
39992
40126
|
this.fadeFromValuePixels = this.displayedValuePixels === null && this.valueCache[idx]
|
|
@@ -40233,11 +40367,13 @@ void main() {
|
|
|
40233
40367
|
return _glsl300Support;
|
|
40234
40368
|
}
|
|
40235
40369
|
/*
|
|
40236
|
-
* Places grid node (fx, fy) on the ellipsoid,
|
|
40237
|
-
*
|
|
40238
|
-
* linear in a projected CRS, so stepping in degrees instead would skew the surface against the flat-textured polygon it replaces.
|
|
40370
|
+
* Places grid node (fx, fy) on the ellipsoid, stepping the way the raster was sampled.
|
|
40371
|
+
* A raster sampled at lon/lat has to be walked in degrees; one sampled linearly across a projected CRS has to be walked in tangent-plane metres.
|
|
40239
40372
|
*/
|
|
40240
|
-
function makePlacer(extent) {
|
|
40373
|
+
function makePlacer(extent, pixelPlacement) {
|
|
40374
|
+
if (pixelPlacement === "lonlat") {
|
|
40375
|
+
return (fx, fy) => Cartesian3.fromDegrees(Math$1.lerp(extent.West, extent.East, fx), Math$1.lerp(extent.North, extent.South, fy), 0);
|
|
40376
|
+
}
|
|
40241
40377
|
const ellipsoid = Ellipsoid.WGS84;
|
|
40242
40378
|
const centre = Cartesian3.fromDegrees((extent.West + extent.East) / 2, (extent.South + extent.North) / 2, 0);
|
|
40243
40379
|
const frame = Transforms.eastNorthUpToFixedFrame(centre);
|
|
@@ -40251,21 +40387,21 @@ void main() {
|
|
|
40251
40387
|
};
|
|
40252
40388
|
}
|
|
40253
40389
|
/*
|
|
40254
|
-
* Builds one tile's grid, plus a duplicated perimeter ring the shader pushes downwards to
|
|
40255
|
-
* the crack where a neighbouring tile at a different density interpolates the shared edge.
|
|
40390
|
+
* Builds one tile's grid, optionally plus a duplicated perimeter ring the shader pushes downwards to
|
|
40391
|
+
* cover the crack where a neighbouring tile at a different density interpolates the shared edge.
|
|
40256
40392
|
*/
|
|
40257
|
-
function buildGeometry(extent, resolution, patch) {
|
|
40393
|
+
function buildGeometry(extent, resolution, patch, pixelPlacement, withSkirt = false) {
|
|
40258
40394
|
const cols = resolution;
|
|
40259
40395
|
const rows = resolution;
|
|
40260
40396
|
const gridCount = (cols + 1) * (rows + 1);
|
|
40261
|
-
const perimeterCount = 2 * (cols + 1) + 2 * (rows + 1) - 4;
|
|
40397
|
+
const perimeterCount = withSkirt ? 2 * (cols + 1) + 2 * (rows + 1) - 4 : 0;
|
|
40262
40398
|
const count = gridCount + perimeterCount;
|
|
40263
40399
|
const positions = new Float64Array(count * 3);
|
|
40264
40400
|
const normals = new Float32Array(count * 3);
|
|
40265
40401
|
const sts = new Float32Array(count * 2);
|
|
40266
40402
|
const skirts = new Float32Array(count);
|
|
40267
40403
|
const ellipsoid = Ellipsoid.WGS84;
|
|
40268
|
-
const place = makePlacer(extent);
|
|
40404
|
+
const place = makePlacer(extent, pixelPlacement);
|
|
40269
40405
|
let v = 0;
|
|
40270
40406
|
for (let row = 0; row <= rows; row++) {
|
|
40271
40407
|
// Texture row 0 is the north edge, so t runs opposite to northing.
|
|
@@ -40316,26 +40452,28 @@ void main() {
|
|
|
40316
40452
|
loop.push(row * (cols + 1));
|
|
40317
40453
|
}
|
|
40318
40454
|
const skirtStart = gridCount;
|
|
40319
|
-
|
|
40320
|
-
|
|
40321
|
-
|
|
40322
|
-
|
|
40323
|
-
|
|
40324
|
-
|
|
40325
|
-
|
|
40326
|
-
|
|
40327
|
-
|
|
40328
|
-
|
|
40329
|
-
|
|
40330
|
-
|
|
40331
|
-
|
|
40332
|
-
|
|
40333
|
-
|
|
40334
|
-
|
|
40335
|
-
|
|
40336
|
-
|
|
40337
|
-
|
|
40338
|
-
|
|
40455
|
+
if (withSkirt) {
|
|
40456
|
+
loop.forEach((gridIndex, k) => {
|
|
40457
|
+
const target = skirtStart + k;
|
|
40458
|
+
positions[target * 3] = positions[gridIndex * 3];
|
|
40459
|
+
positions[target * 3 + 1] = positions[gridIndex * 3 + 1];
|
|
40460
|
+
positions[target * 3 + 2] = positions[gridIndex * 3 + 2];
|
|
40461
|
+
normals[target * 3] = normals[gridIndex * 3];
|
|
40462
|
+
normals[target * 3 + 1] = normals[gridIndex * 3 + 1];
|
|
40463
|
+
normals[target * 3 + 2] = normals[gridIndex * 3 + 2];
|
|
40464
|
+
sts[target * 2] = sts[gridIndex * 2];
|
|
40465
|
+
sts[target * 2 + 1] = sts[gridIndex * 2 + 1];
|
|
40466
|
+
skirts[target] = 1;
|
|
40467
|
+
});
|
|
40468
|
+
for (let k = 0; k < loop.length; k++) {
|
|
40469
|
+
const nextK = (k + 1) % loop.length;
|
|
40470
|
+
indices[i++] = loop[k];
|
|
40471
|
+
indices[i++] = skirtStart + k;
|
|
40472
|
+
indices[i++] = loop[nextK];
|
|
40473
|
+
indices[i++] = loop[nextK];
|
|
40474
|
+
indices[i++] = skirtStart + k;
|
|
40475
|
+
indices[i++] = skirtStart + nextK;
|
|
40476
|
+
}
|
|
40339
40477
|
}
|
|
40340
40478
|
const geometry = new Geometry({
|
|
40341
40479
|
attributes: {
|
|
@@ -40393,6 +40531,8 @@ void main() {
|
|
|
40393
40531
|
this.valueMax = (_b = options.valueMax) !== null && _b !== void 0 ? _b : 1;
|
|
40394
40532
|
this.exaggeration = (_c = options.exaggeration) !== null && _c !== void 0 ? _c : autoExaggeration(this.extent, this.valueMin, this.valueMax);
|
|
40395
40533
|
this.baseHeight = (_d = options.baseHeight) !== null && _d !== void 0 ? _d : 0;
|
|
40534
|
+
this.pixelPlacement = options.pixelPlacement;
|
|
40535
|
+
this.tileSkirts = Boolean(options.tileSkirts);
|
|
40396
40536
|
this.lowColor = toCesiumColor(options.lowColor || DEFAULT_LOW_COLOR);
|
|
40397
40537
|
this.highColor = toCesiumColor(options.highColor || DEFAULT_HIGH_COLOR);
|
|
40398
40538
|
this.tiles = buildTiles(hasCoverage);
|
|
@@ -40400,6 +40540,9 @@ void main() {
|
|
|
40400
40540
|
GetFollowsGround() {
|
|
40401
40541
|
return this.followGround;
|
|
40402
40542
|
}
|
|
40543
|
+
GetPixelPlacement() {
|
|
40544
|
+
return this.pixelPlacement;
|
|
40545
|
+
}
|
|
40403
40546
|
GetBaseHeight() {
|
|
40404
40547
|
return this.baseHeight;
|
|
40405
40548
|
}
|
|
@@ -40614,7 +40757,7 @@ void main() {
|
|
|
40614
40757
|
if (cached) {
|
|
40615
40758
|
return cached;
|
|
40616
40759
|
}
|
|
40617
|
-
const geometry = buildGeometry(this.extent, tier, tile.patch);
|
|
40760
|
+
const geometry = buildGeometry(this.extent, tier, tile.patch, this.pixelPlacement, this.tileSkirts);
|
|
40618
40761
|
const attributeLocations = GeometryPipeline.createAttributeLocations(geometry);
|
|
40619
40762
|
const mesh = {
|
|
40620
40763
|
attributeLocations,
|
|
@@ -40707,7 +40850,9 @@ void main() {
|
|
|
40707
40850
|
u_valueRange: () => self.valueMax - self.valueMin,
|
|
40708
40851
|
u_exaggeration: () => self.exaggeration,
|
|
40709
40852
|
u_baseHeight: () => self.baseHeight,
|
|
40710
|
-
u_skirtDepth: () =>
|
|
40853
|
+
u_skirtDepth: () => self.tileSkirts
|
|
40854
|
+
? Math.max(2, Math.abs(self.valueMax - self.valueMin) * self.exaggeration * SKIRT_FRACTION)
|
|
40855
|
+
: 0,
|
|
40711
40856
|
u_coverageCutoff: () => COVERAGE_CUTOFF,
|
|
40712
40857
|
u_lowColor: () => self.lowColor,
|
|
40713
40858
|
u_highColor: () => self.highColor,
|
|
@@ -40840,6 +40985,8 @@ var EntityRenderEnginePolygon;
|
|
|
40840
40985
|
}
|
|
40841
40986
|
}
|
|
40842
40987
|
const drawsDisplacedSurface = Boolean(extrusionArchive);
|
|
40988
|
+
// The displaced surface IS the entity's fill, drawn as its own primitive at the value's height.
|
|
40989
|
+
// Leaving the flat polygon filled as well shows a second copy of the parcel on the ground under it.
|
|
40843
40990
|
const hasFill = (drawsDisplacedSurface ? true
|
|
40844
40991
|
: fillType === Style.EPolygonFillType.Texture
|
|
40845
40992
|
? Boolean(textureDataUri || frameArchive || cFillColor.alpha > 0)
|
|
@@ -40928,6 +41075,7 @@ var EntityRenderEnginePolygon;
|
|
|
40928
41075
|
polygon: {
|
|
40929
41076
|
hierarchy: new PolygonHierarchy(posses, holePosses.map(x => new PolygonHierarchy(x))),
|
|
40930
41077
|
material: fillMaterial,
|
|
41078
|
+
fill: !drawsDisplacedSurface,
|
|
40931
41079
|
extrudedHeight: extrusion.value,
|
|
40932
41080
|
extrudedHeightReference: extrusion.exHeightRef,
|
|
40933
41081
|
shadows: ShadowMode.ENABLED,
|
|
@@ -40958,6 +41106,12 @@ var EntityRenderEnginePolygon;
|
|
|
40958
41106
|
if (!CompareCPolygonHierarchies(oldHierarchy, newHierarchy)) {
|
|
40959
41107
|
cEntity.polygon.hierarchy = new ConstantProperty(newHierarchy);
|
|
40960
41108
|
}
|
|
41109
|
+
// Toggling extrusion styling on an already-rendered entity flips this,
|
|
41110
|
+
// so it has to be reconciled rather than set only at creation.
|
|
41111
|
+
const oldFill = GetCValue(params.viewer, cEntity.polygon.fill);
|
|
41112
|
+
if (oldFill !== !drawsDisplacedSurface) {
|
|
41113
|
+
cEntity.polygon.fill = new ConstantProperty(!drawsDisplacedSurface);
|
|
41114
|
+
}
|
|
40961
41115
|
const oldExtrusion = GetCValue(params.viewer, cEntity.polygon.extrudedHeight);
|
|
40962
41116
|
if (oldExtrusion != extrusion.value) {
|
|
40963
41117
|
cEntity.polygon.extrudedHeight = new ConstantProperty(extrusion.value);
|
|
@@ -41011,7 +41165,7 @@ var EntityRenderEnginePolygon;
|
|
|
41011
41165
|
}
|
|
41012
41166
|
// Must run before any material is baked below: the Animator takes over polygon.material, so a bake
|
|
41013
41167
|
// has to know whether it is baking over a live animation or over a disposed one's restored material.
|
|
41014
|
-
const animator = syncTextureFrameArchive(cEntity, drawsDisplacedSurface ? null : frameArchive, params.viewer, style.textureColorMask);
|
|
41168
|
+
const animator = syncTextureFrameArchive(cEntity, drawsDisplacedSurface ? null : frameArchive, params.viewer, style.textureColorMask, style.maskTextureBaseline);
|
|
41015
41169
|
syncDisplacedSurface({
|
|
41016
41170
|
cEntity,
|
|
41017
41171
|
extrusionArchive,
|
|
@@ -41496,12 +41650,17 @@ function syncDisplacedSurface(params) {
|
|
|
41496
41650
|
frames: extrusionArchive.metadata.Frames,
|
|
41497
41651
|
textureColorMask: style.textureColorMask,
|
|
41498
41652
|
driveMaterial: false,
|
|
41499
|
-
produceValueCanvas: true
|
|
41653
|
+
produceValueCanvas: true,
|
|
41654
|
+
baselineMask: extrusionArchive.metadata.BaselineMask,
|
|
41655
|
+
// Off-type for the same reason as the fill path: the pinned bruce-models predates the field.
|
|
41656
|
+
maskBaseline: style.maskTextureBaseline
|
|
41500
41657
|
});
|
|
41501
41658
|
cEntity[EXTRUSION_ANIMATOR_KEY] = animator;
|
|
41502
41659
|
const mask = style.textureColorMask;
|
|
41503
41660
|
const surface = new DisplacedSurfacePrimitive.Surface({
|
|
41504
41661
|
extent,
|
|
41662
|
+
// The grid has to be walked the way the raster was sampled, or the surface skews across the extent.
|
|
41663
|
+
pixelPlacement: extrusionArchive.metadata.PixelPlacement,
|
|
41505
41664
|
source: null,
|
|
41506
41665
|
baseHeight: placement.baseHeight,
|
|
41507
41666
|
followGround: placement.followGround,
|
|
@@ -41593,7 +41752,7 @@ function disposeDisplacedSurface(cEntity, viewer) {
|
|
|
41593
41752
|
* @param viewer
|
|
41594
41753
|
* @param textureColorMask
|
|
41595
41754
|
*/
|
|
41596
|
-
function syncTextureFrameArchive(cEntity, frameArchive, viewer, textureColorMask) {
|
|
41755
|
+
function syncTextureFrameArchive(cEntity, frameArchive, viewer, textureColorMask, maskTextureBaseline) {
|
|
41597
41756
|
const existing = cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY];
|
|
41598
41757
|
if (frameArchive && existing && !existing.IsDisposed() && existing.GetArchiveUrl() === frameArchive.url) {
|
|
41599
41758
|
return existing;
|
|
@@ -41610,7 +41769,9 @@ function syncTextureFrameArchive(cEntity, frameArchive, viewer, textureColorMask
|
|
|
41610
41769
|
entity: cEntity,
|
|
41611
41770
|
archiveUrl: frameArchive.url,
|
|
41612
41771
|
frames: frameArchive.metadata.Frames,
|
|
41613
|
-
textureColorMask
|
|
41772
|
+
textureColorMask,
|
|
41773
|
+
baselineMask: frameArchive.metadata.BaselineMask,
|
|
41774
|
+
maskBaseline: maskTextureBaseline
|
|
41614
41775
|
});
|
|
41615
41776
|
cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY] = animator;
|
|
41616
41777
|
return animator;
|
|
@@ -43222,7 +43383,7 @@ var StyleUtils;
|
|
|
43222
43383
|
StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
|
|
43223
43384
|
})(StyleUtils || (StyleUtils = {}));
|
|
43224
43385
|
|
|
43225
|
-
const VERSION = "7.1.
|
|
43386
|
+
const VERSION = "7.1.5";
|
|
43226
43387
|
/**
|
|
43227
43388
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
43228
43389
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|