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.umd.js
CHANGED
|
@@ -39622,15 +39622,68 @@
|
|
|
39622
39622
|
return Boolean(data && data.generation && Array.isArray(data.generation.Frames) && data.generation.Frames.length > 0);
|
|
39623
39623
|
}
|
|
39624
39624
|
TextureFrameSeriesAnimator.IsFrameArchiveMetadata = IsFrameArchiveMetadata;
|
|
39625
|
+
// How far covered values bleed outward into uncovered texels before the GPU samples them.
|
|
39626
|
+
const VALUE_DILATE_PASSES = 2;
|
|
39627
|
+
/*
|
|
39628
|
+
* Bleeds covered values outward into uncovered texels, leaving alpha untouched.
|
|
39629
|
+
*
|
|
39630
|
+
* The GPU samples the value texture with linear filtering, so an uncovered texel's RGB still gets
|
|
39631
|
+
* averaged into the vertices next to it even though its alpha is zero. Land sits at one end of the
|
|
39632
|
+
* ramp, so without this the coastline grows a row of spikes exactly where the data stops. Masking the
|
|
39633
|
+
* baseline creates more of these edges, which is what makes this necessary rather than cosmetic.
|
|
39634
|
+
*/
|
|
39635
|
+
function dilateValues(value, width, height, passes) {
|
|
39636
|
+
const texels = width * height;
|
|
39637
|
+
const filled = new Uint8Array(texels);
|
|
39638
|
+
for (let p = 0; p < texels; p++) {
|
|
39639
|
+
filled[p] = value[p * 4 + 3] !== 0 ? 1 : 0;
|
|
39640
|
+
}
|
|
39641
|
+
for (let pass = 0; pass < passes; pass++) {
|
|
39642
|
+
const source = value.slice();
|
|
39643
|
+
const wasFilled = filled.slice();
|
|
39644
|
+
for (let y = 0; y < height; y++) {
|
|
39645
|
+
for (let x = 0; x < width; x++) {
|
|
39646
|
+
const p = y * width + x;
|
|
39647
|
+
if (wasFilled[p]) {
|
|
39648
|
+
continue;
|
|
39649
|
+
}
|
|
39650
|
+
let sum = 0;
|
|
39651
|
+
let hits = 0;
|
|
39652
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
39653
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
39654
|
+
const nx = x + dx;
|
|
39655
|
+
const ny = y + dy;
|
|
39656
|
+
if (nx < 0 || ny < 0 || nx >= width || ny >= height || !wasFilled[ny * width + nx]) {
|
|
39657
|
+
continue;
|
|
39658
|
+
}
|
|
39659
|
+
sum += source[(ny * width + nx) * 4];
|
|
39660
|
+
hits++;
|
|
39661
|
+
}
|
|
39662
|
+
}
|
|
39663
|
+
if (hits > 0) {
|
|
39664
|
+
const v = Math.round(sum / hits);
|
|
39665
|
+
value[p * 4] = v;
|
|
39666
|
+
value[p * 4 + 1] = v;
|
|
39667
|
+
value[p * 4 + 2] = v;
|
|
39668
|
+
filled[p] = 1;
|
|
39669
|
+
}
|
|
39670
|
+
}
|
|
39671
|
+
}
|
|
39672
|
+
}
|
|
39673
|
+
}
|
|
39625
39674
|
const DEFAULT_CROSSFADE_MS = 900;
|
|
39626
39675
|
const DEFAULT_LOW_COLOR = { red: 255, green: 255, blue: 255, alpha: 0.12 };
|
|
39627
39676
|
const DEFAULT_HIGH_COLOR = { red: 21, green: 96, blue: 196, alpha: 0.92 };
|
|
39628
39677
|
class Animator {
|
|
39629
39678
|
constructor(options) {
|
|
39630
|
-
var _a;
|
|
39679
|
+
var _a, _b;
|
|
39631
39680
|
this.removeOnTick = null;
|
|
39632
39681
|
this.removeCrossfadeTick = null;
|
|
39633
39682
|
this.disposed = false;
|
|
39683
|
+
// One alpha byte per texel, 1 meaning the texel is baseline. Fetched once, the mesh does not move.
|
|
39684
|
+
this.baselineFlags = null;
|
|
39685
|
+
this.baselineDims = null;
|
|
39686
|
+
this.baselineLoad = null;
|
|
39634
39687
|
this.currentFrameIndex = -1;
|
|
39635
39688
|
// Single-in-flight fetch queue: only one Range GET outstanding at a time, and the NEXT one
|
|
39636
39689
|
// is chosen right before sending, this is what makes reprioritizing mid-scrub take effect
|
|
@@ -39670,6 +39723,8 @@
|
|
|
39670
39723
|
this.frameDims = new Array(this.frames.length).fill(null);
|
|
39671
39724
|
this.valueCache = new Array(this.frames.length).fill(null);
|
|
39672
39725
|
this.produceValueCanvas = Boolean(options.produceValueCanvas);
|
|
39726
|
+
this.baselineMaskEntry = options.baselineMask || null;
|
|
39727
|
+
this.maskBaseline = (_b = options.maskBaseline) !== null && _b !== void 0 ? _b : Boolean(options.baselineMask);
|
|
39673
39728
|
this.valueCanvas = this.produceValueCanvas ? document.createElement("canvas") : null;
|
|
39674
39729
|
this.driveMaterial = options.driveMaterial !== false;
|
|
39675
39730
|
this.originalMaterial = options.entity.polygon.material;
|
|
@@ -39839,6 +39894,12 @@
|
|
|
39839
39894
|
if (this.disposed) {
|
|
39840
39895
|
return;
|
|
39841
39896
|
}
|
|
39897
|
+
// Awaited before decoding rather than applied later, so no frame is ever cached unmasked and
|
|
39898
|
+
// then corrected once the mask lands.
|
|
39899
|
+
await this.ensureBaselineMask();
|
|
39900
|
+
if (this.disposed) {
|
|
39901
|
+
return;
|
|
39902
|
+
}
|
|
39842
39903
|
const decoded = await this.decodeAndTint(buffer);
|
|
39843
39904
|
if (this.disposed) {
|
|
39844
39905
|
return;
|
|
@@ -39873,8 +39934,81 @@
|
|
|
39873
39934
|
// recovered from the tinted pixels afterwards.
|
|
39874
39935
|
const valuePixels = this.produceValueCanvas ? new Uint8ClampedArray(imageData.data) : undefined;
|
|
39875
39936
|
ApplyGrayscaleColorMask(imageData, this.lowColor, this.highColor);
|
|
39937
|
+
this.applyBaselineMask(imageData.data, valuePixels, canvas.width, canvas.height);
|
|
39938
|
+
if (valuePixels) {
|
|
39939
|
+
dilateValues(valuePixels, canvas.width, canvas.height, VALUE_DILATE_PASSES);
|
|
39940
|
+
}
|
|
39876
39941
|
return { pixels: imageData.data, width: canvas.width, height: canvas.height, valuePixels };
|
|
39877
39942
|
}
|
|
39943
|
+
/**
|
|
39944
|
+
* Fetches and decodes the archive's static baseline mask, at most once.
|
|
39945
|
+
*/
|
|
39946
|
+
ensureBaselineMask() {
|
|
39947
|
+
if (!this.maskBaseline || !this.baselineMaskEntry) {
|
|
39948
|
+
return Promise.resolve();
|
|
39949
|
+
}
|
|
39950
|
+
if (this.baselineLoad) {
|
|
39951
|
+
return this.baselineLoad;
|
|
39952
|
+
}
|
|
39953
|
+
const entry = this.baselineMaskEntry;
|
|
39954
|
+
const start = entry.ByteOffset;
|
|
39955
|
+
const end = entry.ByteOffset + entry.ByteLength - 1;
|
|
39956
|
+
this.baselineLoad = fetch(this.archiveUrl, { headers: { Range: `bytes=${start}-${end}` } })
|
|
39957
|
+
.then((response) => response.arrayBuffer())
|
|
39958
|
+
.then(async (buffer) => {
|
|
39959
|
+
if (this.disposed) {
|
|
39960
|
+
return;
|
|
39961
|
+
}
|
|
39962
|
+
const blob = new Blob([buffer], { type: "image/png" });
|
|
39963
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
39964
|
+
let image;
|
|
39965
|
+
try {
|
|
39966
|
+
image = await loadImage(objectUrl);
|
|
39967
|
+
}
|
|
39968
|
+
finally {
|
|
39969
|
+
URL.revokeObjectURL(objectUrl);
|
|
39970
|
+
}
|
|
39971
|
+
const canvas = document.createElement("canvas");
|
|
39972
|
+
canvas.width = image.width;
|
|
39973
|
+
canvas.height = image.height;
|
|
39974
|
+
const ctx = canvas.getContext("2d");
|
|
39975
|
+
ctx.drawImage(image, 0, 0);
|
|
39976
|
+
const pixels = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
39977
|
+
const flags = new Uint8Array(canvas.width * canvas.height);
|
|
39978
|
+
for (let p = 0; p < flags.length; p++) {
|
|
39979
|
+
flags[p] = pixels[p * 4 + 3] >= 128 ? 1 : 0;
|
|
39980
|
+
}
|
|
39981
|
+
this.baselineFlags = flags;
|
|
39982
|
+
this.baselineDims = { width: canvas.width, height: canvas.height };
|
|
39983
|
+
})
|
|
39984
|
+
.catch((e) => {
|
|
39985
|
+
// A missing or unreadable mask must not stop the animation; it just means nothing is hidden.
|
|
39986
|
+
console.warn("TextureFrameSeriesAnimator: could not load the baseline mask, drawing it instead.", e);
|
|
39987
|
+
});
|
|
39988
|
+
return this.baselineLoad;
|
|
39989
|
+
}
|
|
39990
|
+
/**
|
|
39991
|
+
* Clears alpha on baseline texels, which is what makes hiding the dry/land sentinel a render choice.
|
|
39992
|
+
*/
|
|
39993
|
+
applyBaselineMask(pixels, valuePixels, width, height) {
|
|
39994
|
+
const flags = this.baselineFlags;
|
|
39995
|
+
if (!flags || !this.baselineDims) {
|
|
39996
|
+
return;
|
|
39997
|
+
}
|
|
39998
|
+
// A mask from a different raster size cannot be indexed against this frame, and guessing a
|
|
39999
|
+
// resampling would silently hide the wrong ground.
|
|
40000
|
+
if (this.baselineDims.width !== width || this.baselineDims.height !== height) {
|
|
40001
|
+
return;
|
|
40002
|
+
}
|
|
40003
|
+
for (let p = 0; p < flags.length; p++) {
|
|
40004
|
+
if (flags[p]) {
|
|
40005
|
+
pixels[p * 4 + 3] = 0;
|
|
40006
|
+
if (valuePixels) {
|
|
40007
|
+
valuePixels[p * 4 + 3] = 0;
|
|
40008
|
+
}
|
|
40009
|
+
}
|
|
40010
|
+
}
|
|
40011
|
+
}
|
|
39878
40012
|
beginCrossfadeTo(idx) {
|
|
39879
40013
|
const to = this.frameCache[idx];
|
|
39880
40014
|
this.fadeFromValuePixels = this.displayedValuePixels === null && this.valueCache[idx]
|
|
@@ -40116,11 +40250,13 @@ void main() {
|
|
|
40116
40250
|
return _glsl300Support;
|
|
40117
40251
|
}
|
|
40118
40252
|
/*
|
|
40119
|
-
* Places grid node (fx, fy) on the ellipsoid,
|
|
40120
|
-
*
|
|
40121
|
-
* linear in a projected CRS, so stepping in degrees instead would skew the surface against the flat-textured polygon it replaces.
|
|
40253
|
+
* Places grid node (fx, fy) on the ellipsoid, stepping the way the raster was sampled.
|
|
40254
|
+
* 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.
|
|
40122
40255
|
*/
|
|
40123
|
-
function makePlacer(extent) {
|
|
40256
|
+
function makePlacer(extent, pixelPlacement) {
|
|
40257
|
+
if (pixelPlacement === "lonlat") {
|
|
40258
|
+
return (fx, fy) => Cesium.Cartesian3.fromDegrees(Cesium.Math.lerp(extent.West, extent.East, fx), Cesium.Math.lerp(extent.North, extent.South, fy), 0);
|
|
40259
|
+
}
|
|
40124
40260
|
const ellipsoid = Cesium.Ellipsoid.WGS84;
|
|
40125
40261
|
const centre = Cesium.Cartesian3.fromDegrees((extent.West + extent.East) / 2, (extent.South + extent.North) / 2, 0);
|
|
40126
40262
|
const frame = Cesium.Transforms.eastNorthUpToFixedFrame(centre);
|
|
@@ -40134,21 +40270,21 @@ void main() {
|
|
|
40134
40270
|
};
|
|
40135
40271
|
}
|
|
40136
40272
|
/*
|
|
40137
|
-
* Builds one tile's grid, plus a duplicated perimeter ring the shader pushes downwards to
|
|
40138
|
-
* the crack where a neighbouring tile at a different density interpolates the shared edge.
|
|
40273
|
+
* Builds one tile's grid, optionally plus a duplicated perimeter ring the shader pushes downwards to
|
|
40274
|
+
* cover the crack where a neighbouring tile at a different density interpolates the shared edge.
|
|
40139
40275
|
*/
|
|
40140
|
-
function buildGeometry(extent, resolution, patch) {
|
|
40276
|
+
function buildGeometry(extent, resolution, patch, pixelPlacement, withSkirt = false) {
|
|
40141
40277
|
const cols = resolution;
|
|
40142
40278
|
const rows = resolution;
|
|
40143
40279
|
const gridCount = (cols + 1) * (rows + 1);
|
|
40144
|
-
const perimeterCount = 2 * (cols + 1) + 2 * (rows + 1) - 4;
|
|
40280
|
+
const perimeterCount = withSkirt ? 2 * (cols + 1) + 2 * (rows + 1) - 4 : 0;
|
|
40145
40281
|
const count = gridCount + perimeterCount;
|
|
40146
40282
|
const positions = new Float64Array(count * 3);
|
|
40147
40283
|
const normals = new Float32Array(count * 3);
|
|
40148
40284
|
const sts = new Float32Array(count * 2);
|
|
40149
40285
|
const skirts = new Float32Array(count);
|
|
40150
40286
|
const ellipsoid = Cesium.Ellipsoid.WGS84;
|
|
40151
|
-
const place = makePlacer(extent);
|
|
40287
|
+
const place = makePlacer(extent, pixelPlacement);
|
|
40152
40288
|
let v = 0;
|
|
40153
40289
|
for (let row = 0; row <= rows; row++) {
|
|
40154
40290
|
// Texture row 0 is the north edge, so t runs opposite to northing.
|
|
@@ -40199,26 +40335,28 @@ void main() {
|
|
|
40199
40335
|
loop.push(row * (cols + 1));
|
|
40200
40336
|
}
|
|
40201
40337
|
const skirtStart = gridCount;
|
|
40202
|
-
|
|
40203
|
-
|
|
40204
|
-
|
|
40205
|
-
|
|
40206
|
-
|
|
40207
|
-
|
|
40208
|
-
|
|
40209
|
-
|
|
40210
|
-
|
|
40211
|
-
|
|
40212
|
-
|
|
40213
|
-
|
|
40214
|
-
|
|
40215
|
-
|
|
40216
|
-
|
|
40217
|
-
|
|
40218
|
-
|
|
40219
|
-
|
|
40220
|
-
|
|
40221
|
-
|
|
40338
|
+
if (withSkirt) {
|
|
40339
|
+
loop.forEach((gridIndex, k) => {
|
|
40340
|
+
const target = skirtStart + k;
|
|
40341
|
+
positions[target * 3] = positions[gridIndex * 3];
|
|
40342
|
+
positions[target * 3 + 1] = positions[gridIndex * 3 + 1];
|
|
40343
|
+
positions[target * 3 + 2] = positions[gridIndex * 3 + 2];
|
|
40344
|
+
normals[target * 3] = normals[gridIndex * 3];
|
|
40345
|
+
normals[target * 3 + 1] = normals[gridIndex * 3 + 1];
|
|
40346
|
+
normals[target * 3 + 2] = normals[gridIndex * 3 + 2];
|
|
40347
|
+
sts[target * 2] = sts[gridIndex * 2];
|
|
40348
|
+
sts[target * 2 + 1] = sts[gridIndex * 2 + 1];
|
|
40349
|
+
skirts[target] = 1;
|
|
40350
|
+
});
|
|
40351
|
+
for (let k = 0; k < loop.length; k++) {
|
|
40352
|
+
const nextK = (k + 1) % loop.length;
|
|
40353
|
+
indices[i++] = loop[k];
|
|
40354
|
+
indices[i++] = skirtStart + k;
|
|
40355
|
+
indices[i++] = loop[nextK];
|
|
40356
|
+
indices[i++] = loop[nextK];
|
|
40357
|
+
indices[i++] = skirtStart + k;
|
|
40358
|
+
indices[i++] = skirtStart + nextK;
|
|
40359
|
+
}
|
|
40222
40360
|
}
|
|
40223
40361
|
const geometry = new Cesium.Geometry({
|
|
40224
40362
|
attributes: {
|
|
@@ -40276,6 +40414,8 @@ void main() {
|
|
|
40276
40414
|
this.valueMax = (_b = options.valueMax) !== null && _b !== void 0 ? _b : 1;
|
|
40277
40415
|
this.exaggeration = (_c = options.exaggeration) !== null && _c !== void 0 ? _c : autoExaggeration(this.extent, this.valueMin, this.valueMax);
|
|
40278
40416
|
this.baseHeight = (_d = options.baseHeight) !== null && _d !== void 0 ? _d : 0;
|
|
40417
|
+
this.pixelPlacement = options.pixelPlacement;
|
|
40418
|
+
this.tileSkirts = Boolean(options.tileSkirts);
|
|
40279
40419
|
this.lowColor = toCesiumColor(options.lowColor || DEFAULT_LOW_COLOR);
|
|
40280
40420
|
this.highColor = toCesiumColor(options.highColor || DEFAULT_HIGH_COLOR);
|
|
40281
40421
|
this.tiles = buildTiles(hasCoverage);
|
|
@@ -40283,6 +40423,9 @@ void main() {
|
|
|
40283
40423
|
GetFollowsGround() {
|
|
40284
40424
|
return this.followGround;
|
|
40285
40425
|
}
|
|
40426
|
+
GetPixelPlacement() {
|
|
40427
|
+
return this.pixelPlacement;
|
|
40428
|
+
}
|
|
40286
40429
|
GetBaseHeight() {
|
|
40287
40430
|
return this.baseHeight;
|
|
40288
40431
|
}
|
|
@@ -40497,7 +40640,7 @@ void main() {
|
|
|
40497
40640
|
if (cached) {
|
|
40498
40641
|
return cached;
|
|
40499
40642
|
}
|
|
40500
|
-
const geometry = buildGeometry(this.extent, tier, tile.patch);
|
|
40643
|
+
const geometry = buildGeometry(this.extent, tier, tile.patch, this.pixelPlacement, this.tileSkirts);
|
|
40501
40644
|
const attributeLocations = Cesium.GeometryPipeline.createAttributeLocations(geometry);
|
|
40502
40645
|
const mesh = {
|
|
40503
40646
|
attributeLocations,
|
|
@@ -40590,7 +40733,9 @@ void main() {
|
|
|
40590
40733
|
u_valueRange: () => self.valueMax - self.valueMin,
|
|
40591
40734
|
u_exaggeration: () => self.exaggeration,
|
|
40592
40735
|
u_baseHeight: () => self.baseHeight,
|
|
40593
|
-
u_skirtDepth: () =>
|
|
40736
|
+
u_skirtDepth: () => self.tileSkirts
|
|
40737
|
+
? Math.max(2, Math.abs(self.valueMax - self.valueMin) * self.exaggeration * SKIRT_FRACTION)
|
|
40738
|
+
: 0,
|
|
40594
40739
|
u_coverageCutoff: () => COVERAGE_CUTOFF,
|
|
40595
40740
|
u_lowColor: () => self.lowColor,
|
|
40596
40741
|
u_highColor: () => self.highColor,
|
|
@@ -40722,6 +40867,8 @@ void main() {
|
|
|
40722
40867
|
}
|
|
40723
40868
|
}
|
|
40724
40869
|
const drawsDisplacedSurface = Boolean(extrusionArchive);
|
|
40870
|
+
// The displaced surface IS the entity's fill, drawn as its own primitive at the value's height.
|
|
40871
|
+
// Leaving the flat polygon filled as well shows a second copy of the parcel on the ground under it.
|
|
40725
40872
|
const hasFill = (drawsDisplacedSurface ? true
|
|
40726
40873
|
: fillType === BModels.Style.EPolygonFillType.Texture
|
|
40727
40874
|
? Boolean(textureDataUri || frameArchive || cFillColor.alpha > 0)
|
|
@@ -40810,6 +40957,7 @@ void main() {
|
|
|
40810
40957
|
polygon: {
|
|
40811
40958
|
hierarchy: new Cesium.PolygonHierarchy(posses, holePosses.map(x => new Cesium.PolygonHierarchy(x))),
|
|
40812
40959
|
material: fillMaterial,
|
|
40960
|
+
fill: !drawsDisplacedSurface,
|
|
40813
40961
|
extrudedHeight: extrusion.value,
|
|
40814
40962
|
extrudedHeightReference: extrusion.exHeightRef,
|
|
40815
40963
|
shadows: Cesium.ShadowMode.ENABLED,
|
|
@@ -40840,6 +40988,12 @@ void main() {
|
|
|
40840
40988
|
if (!CompareCPolygonHierarchies(oldHierarchy, newHierarchy)) {
|
|
40841
40989
|
cEntity.polygon.hierarchy = new Cesium.ConstantProperty(newHierarchy);
|
|
40842
40990
|
}
|
|
40991
|
+
// Toggling extrusion styling on an already-rendered entity flips this,
|
|
40992
|
+
// so it has to be reconciled rather than set only at creation.
|
|
40993
|
+
const oldFill = GetCValue(params.viewer, cEntity.polygon.fill);
|
|
40994
|
+
if (oldFill !== !drawsDisplacedSurface) {
|
|
40995
|
+
cEntity.polygon.fill = new Cesium.ConstantProperty(!drawsDisplacedSurface);
|
|
40996
|
+
}
|
|
40843
40997
|
const oldExtrusion = GetCValue(params.viewer, cEntity.polygon.extrudedHeight);
|
|
40844
40998
|
if (oldExtrusion != extrusion.value) {
|
|
40845
40999
|
cEntity.polygon.extrudedHeight = new Cesium.ConstantProperty(extrusion.value);
|
|
@@ -40893,7 +41047,7 @@ void main() {
|
|
|
40893
41047
|
}
|
|
40894
41048
|
// Must run before any material is baked below: the Animator takes over polygon.material, so a bake
|
|
40895
41049
|
// has to know whether it is baking over a live animation or over a disposed one's restored material.
|
|
40896
|
-
const animator = syncTextureFrameArchive(cEntity, drawsDisplacedSurface ? null : frameArchive, params.viewer, style.textureColorMask);
|
|
41050
|
+
const animator = syncTextureFrameArchive(cEntity, drawsDisplacedSurface ? null : frameArchive, params.viewer, style.textureColorMask, style.maskTextureBaseline);
|
|
40897
41051
|
syncDisplacedSurface({
|
|
40898
41052
|
cEntity,
|
|
40899
41053
|
extrusionArchive,
|
|
@@ -41378,12 +41532,17 @@ void main() {
|
|
|
41378
41532
|
frames: extrusionArchive.metadata.Frames,
|
|
41379
41533
|
textureColorMask: style.textureColorMask,
|
|
41380
41534
|
driveMaterial: false,
|
|
41381
|
-
produceValueCanvas: true
|
|
41535
|
+
produceValueCanvas: true,
|
|
41536
|
+
baselineMask: extrusionArchive.metadata.BaselineMask,
|
|
41537
|
+
// Off-type for the same reason as the fill path: the pinned bruce-models predates the field.
|
|
41538
|
+
maskBaseline: style.maskTextureBaseline
|
|
41382
41539
|
});
|
|
41383
41540
|
cEntity[EXTRUSION_ANIMATOR_KEY] = animator;
|
|
41384
41541
|
const mask = style.textureColorMask;
|
|
41385
41542
|
const surface = new exports.DisplacedSurfacePrimitive.Surface({
|
|
41386
41543
|
extent,
|
|
41544
|
+
// The grid has to be walked the way the raster was sampled, or the surface skews across the extent.
|
|
41545
|
+
pixelPlacement: extrusionArchive.metadata.PixelPlacement,
|
|
41387
41546
|
source: null,
|
|
41388
41547
|
baseHeight: placement.baseHeight,
|
|
41389
41548
|
followGround: placement.followGround,
|
|
@@ -41475,7 +41634,7 @@ void main() {
|
|
|
41475
41634
|
* @param viewer
|
|
41476
41635
|
* @param textureColorMask
|
|
41477
41636
|
*/
|
|
41478
|
-
function syncTextureFrameArchive(cEntity, frameArchive, viewer, textureColorMask) {
|
|
41637
|
+
function syncTextureFrameArchive(cEntity, frameArchive, viewer, textureColorMask, maskTextureBaseline) {
|
|
41479
41638
|
const existing = cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY];
|
|
41480
41639
|
if (frameArchive && existing && !existing.IsDisposed() && existing.GetArchiveUrl() === frameArchive.url) {
|
|
41481
41640
|
return existing;
|
|
@@ -41492,7 +41651,9 @@ void main() {
|
|
|
41492
41651
|
entity: cEntity,
|
|
41493
41652
|
archiveUrl: frameArchive.url,
|
|
41494
41653
|
frames: frameArchive.metadata.Frames,
|
|
41495
|
-
textureColorMask
|
|
41654
|
+
textureColorMask,
|
|
41655
|
+
baselineMask: frameArchive.metadata.BaselineMask,
|
|
41656
|
+
maskBaseline: maskTextureBaseline
|
|
41496
41657
|
});
|
|
41497
41658
|
cEntity[TEXTURE_FRAME_SERIES_ANIMATOR_KEY] = animator;
|
|
41498
41659
|
return animator;
|
|
@@ -43089,7 +43250,7 @@ void main() {
|
|
|
43089
43250
|
StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
|
|
43090
43251
|
})(exports.StyleUtils || (exports.StyleUtils = {}));
|
|
43091
43252
|
|
|
43092
|
-
const VERSION = "7.1.
|
|
43253
|
+
const VERSION = "7.1.5";
|
|
43093
43254
|
/**
|
|
43094
43255
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
43095
43256
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|