bruce-cesium 7.6.1 → 7.6.3
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 +2535 -385
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +2524 -382
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +3 -1
- package/dist/lib/bruce-cesium.js.map +1 -1
- package/dist/lib/rendering/cesium-animated-property.js +63 -107
- package/dist/lib/rendering/cesium-animated-property.js.map +1 -1
- package/dist/lib/rendering/entity-gatherer.js +11 -3
- package/dist/lib/rendering/entity-gatherer.js.map +1 -1
- package/dist/lib/rendering/menu-item-creator.js +44 -23
- package/dist/lib/rendering/menu-item-creator.js.map +1 -1
- package/dist/lib/rendering/menu-item-manager.js +199 -17
- package/dist/lib/rendering/menu-item-manager.js.map +1 -1
- package/dist/lib/rendering/menu-item-styles.js +151 -0
- package/dist/lib/rendering/menu-item-styles.js.map +1 -0
- package/dist/lib/rendering/relation-render-engine.js +24 -5
- package/dist/lib/rendering/relation-render-engine.js.map +1 -1
- package/dist/lib/rendering/render-managers/common/entity-label-group.js +13 -9
- package/dist/lib/rendering/render-managers/common/entity-label-group.js.map +1 -1
- package/dist/lib/rendering/render-managers/common/entity-label.js +68 -7
- package/dist/lib/rendering/render-managers/common/entity-label.js.map +1 -1
- package/dist/lib/rendering/render-managers/common/entity-rerender-maintain-state.js +44 -5
- package/dist/lib/rendering/render-managers/common/entity-rerender-maintain-state.js.map +1 -1
- package/dist/lib/rendering/render-managers/common/entity-simulation.js +483 -0
- package/dist/lib/rendering/render-managers/common/entity-simulation.js.map +1 -0
- package/dist/lib/rendering/render-managers/common/historic-trail.js +123 -0
- package/dist/lib/rendering/render-managers/common/historic-trail.js.map +1 -0
- package/dist/lib/rendering/render-managers/common/historic-utils.js +17 -6
- package/dist/lib/rendering/render-managers/common/historic-utils.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-datalab-render-manager.js +13 -2
- package/dist/lib/rendering/render-managers/entities/entities-datalab-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js +20 -2
- package/dist/lib/rendering/render-managers/entities/entities-ids-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-loaded-render-manager.js +13 -2
- package/dist/lib/rendering/render-managers/entities/entities-loaded-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js +66 -5
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/entities/entity-render-manager.js +11 -1
- package/dist/lib/rendering/render-managers/entities/entity-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/other/assembly-render-manager.js +745 -106
- package/dist/lib/rendering/render-managers/other/assembly-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/other/legacy-relations-render-manager.js +23 -1
- package/dist/lib/rendering/render-managers/other/legacy-relations-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/other/relations-render-manager.js +23 -1
- package/dist/lib/rendering/render-managers/other/relations-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-arb-render-manager.js +19 -0
- package/dist/lib/rendering/render-managers/tilesets/tileset-arb-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js +145 -40
- package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js +18 -0
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/tileset-styler.js +1 -1
- package/dist/lib/rendering/tileset-styler.js.map +1 -1
- package/dist/lib/rendering/visual-register-culler.js +2 -0
- package/dist/lib/rendering/visual-register-culler.js.map +1 -1
- package/dist/lib/rendering/visuals-register.js +89 -20
- package/dist/lib/rendering/visuals-register.js.map +1 -1
- package/dist/lib/utils/entity-utils.js +43 -2
- package/dist/lib/utils/entity-utils.js.map +1 -1
- package/dist/lib/widgets/tabs-left-panel/widget-left-panel-tab-menu-items.js +64 -12
- package/dist/lib/widgets/tabs-left-panel/widget-left-panel-tab-menu-items.js.map +1 -1
- package/dist/lib/widgets/widget-info-view.js +20 -7
- package/dist/lib/widgets/widget-info-view.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +3 -1
- package/dist/types/rendering/cesium-animated-property.d.ts +8 -6
- package/dist/types/rendering/entity-gatherer.d.ts +6 -1
- package/dist/types/rendering/menu-item-manager.d.ts +58 -1
- package/dist/types/rendering/menu-item-styles.d.ts +30 -0
- package/dist/types/rendering/relation-render-engine.d.ts +10 -0
- package/dist/types/rendering/render-managers/common/entity-label-group.d.ts +3 -2
- package/dist/types/rendering/render-managers/common/entity-label.d.ts +4 -0
- package/dist/types/rendering/render-managers/common/entity-rerender-maintain-state.d.ts +20 -0
- package/dist/types/rendering/render-managers/common/entity-simulation.d.ts +126 -0
- package/dist/types/rendering/render-managers/common/historic-trail.d.ts +30 -0
- package/dist/types/rendering/render-managers/common/historic-utils.d.ts +4 -0
- package/dist/types/rendering/render-managers/entities/entities-datalab-render-manager.d.ts +7 -1
- package/dist/types/rendering/render-managers/entities/entities-ids-render-manager.d.ts +7 -1
- package/dist/types/rendering/render-managers/entities/entities-loaded-render-manager.d.ts +7 -1
- package/dist/types/rendering/render-managers/entities/entities-render-manager.d.ts +10 -1
- package/dist/types/rendering/render-managers/entities/entity-render-manager.d.ts +7 -1
- package/dist/types/rendering/render-managers/other/assembly-render-manager.d.ts +79 -2
- package/dist/types/rendering/render-managers/other/legacy-relations-render-manager.d.ts +5 -0
- package/dist/types/rendering/render-managers/other/relations-render-manager.d.ts +5 -0
- package/dist/types/rendering/render-managers/render-manager.d.ts +14 -1
- package/dist/types/rendering/render-managers/tilesets/tileset-arb-render-manager.d.ts +8 -1
- package/dist/types/rendering/render-managers/tilesets/tileset-cad-render-manager.d.ts +16 -2
- package/dist/types/rendering/render-managers/tilesets/tileset-entities-render-manager.d.ts +8 -1
- package/dist/types/rendering/tileset-styler.d.ts +2 -0
- package/dist/types/rendering/visuals-register.d.ts +13 -0
- package/dist/types/utils/entity-utils.d.ts +6 -0
- package/dist/types/widgets/tabs-left-panel/widget-left-panel-tab-menu-items.d.ts +1 -0
- package/dist/types/widgets/widget-info-view.d.ts +1 -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, LRUCache, ProjectViewTile, ENVIRONMENT, Calculator, ClientFile, Entity as Entity$1, EntityLod, EntityTag, EntityType, ObjectUtils, Style, UrlUtils,
|
|
2
|
+
import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, Math as Math$1, Cartesian3, JulianDate, Quaternion, Transforms, HeadingPitchRoll, HeightReference, Matrix4, ConstantPositionProperty, DistanceDisplayCondition, ColorBlendMode, ShadowMode, ClassificationType, Model, ShaderSource, Ellipsoid, Geometry, GeometryAttribute, ComponentDatatype, PrimitiveType, BoundingSphere, GeometryPipeline, Cartesian2, Cartesian4, sampleTerrain, Texture, PixelFormat, Sampler, TextureWrap, TextureMinificationFilter, TextureMagnificationFilter, PixelDatatype, VertexArray, BufferUsage, ShaderProgram, RenderState, BlendingState, DrawCommand, Pass, ArcType, CornerType, ImageMaterialProperty, PolygonHierarchy, PolylineGraphics, Rectangle, SceneMode, IntersectionTests, Ray, SceneTransforms, HorizontalOrigin, VerticalOrigin, NearFarScalar, Matrix3, KmlDataSource, GeoJsonDataSource, FeatureDetection, Cesium3DTileStyle, Cesium3DTileColorBlendMode, HeadingPitchRange, Ion, IonResource, Cesium3DTileset, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, Intersect, OrthographicFrustum, EasingFunction, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, PolygonPipeline, GeometryInstance, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, CesiumInspector, ClockRange, DynamicEnvironmentMapManager, CustomDataSource, ScreenSpaceEventHandler, ScreenSpaceEventType, Fullscreen, CzmlDataSource } from 'cesium';
|
|
3
|
+
import { Cartes, LRUCache, ProjectViewTile, ENVIRONMENT, Calculator, ClientFile, Entity as Entity$1, EntityLod, EntityTag, EntityType, ObjectUtils, Style, UrlUtils, Carto, Geometry as Geometry$1, Bounds, ClientFileValueMap, Color as Color$1, MenuItem, ProjectView, ProjectViewBookmark, Tileset, ZoomControl, BruceEvent, EntityCoords, Api, DataLab, DelayQueue, AccountConcept, RecordChangeFeed, BruceApi, EntityRelation, EntitySource, ProgramKey, ProjectViewLegacyTile, Camera, Account, AccountLimits, Session, ProjectViewBookmarkGroup, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, EntityRelationType, EntityHistoricData } from 'bruce-models';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Ensures a number is returned from a given value.
|
|
@@ -2623,13 +2623,13 @@ var CesiumAnimatedProperty;
|
|
|
2623
2623
|
class AnimateTPositionSeries {
|
|
2624
2624
|
constructor(params) {
|
|
2625
2625
|
this.lastCalcAttitude = null;
|
|
2626
|
-
// Cache for calculated values.
|
|
2626
|
+
// Cache for calculated values: the scene time and set of positions they were worked out for.
|
|
2627
2627
|
this.lastCalcTime = null;
|
|
2628
|
+
this.lastCalcRevision = -1;
|
|
2628
2629
|
this.lastCalcPos3d = null;
|
|
2629
|
-
this.lastCalcPosApplyOverTime = false;
|
|
2630
|
-
this.lastCalcPos3dApplyOverTimeTarget = null;
|
|
2631
|
-
this.lastCalcPos3dApplyOverTimeTimeStart = null;
|
|
2632
2630
|
this.lastCalcHeading = null;
|
|
2631
|
+
// Bumped whenever the positions change, so a still clock re-applies a changed series.
|
|
2632
|
+
this.revision = 0;
|
|
2633
2633
|
this.removal = null;
|
|
2634
2634
|
// Track the timeline range for which we have data.
|
|
2635
2635
|
this.minDate = null;
|
|
@@ -2659,6 +2659,7 @@ var CesiumAnimatedProperty;
|
|
|
2659
2659
|
if (!newPositions || newPositions.length === 0) {
|
|
2660
2660
|
return;
|
|
2661
2661
|
}
|
|
2662
|
+
this.revision++;
|
|
2662
2663
|
// Add new positions to our map, overwriting any existing positions with the same timestamp
|
|
2663
2664
|
for (const pos of newPositions) {
|
|
2664
2665
|
const key = pos.dateTime.toISOString();
|
|
@@ -2682,6 +2683,17 @@ var CesiumAnimatedProperty;
|
|
|
2682
2683
|
}
|
|
2683
2684
|
}
|
|
2684
2685
|
}
|
|
2686
|
+
/**
|
|
2687
|
+
* Replaces every position with these, eg. once some that were simulated have been cleared.
|
|
2688
|
+
* @param positions Positions to animate through from now on.
|
|
2689
|
+
*/
|
|
2690
|
+
replacePositions(positions) {
|
|
2691
|
+
this.positionsMap.clear();
|
|
2692
|
+
this.positions = [];
|
|
2693
|
+
this.minDate = null;
|
|
2694
|
+
this.maxDate = null;
|
|
2695
|
+
this.addPositions(positions);
|
|
2696
|
+
}
|
|
2685
2697
|
/**
|
|
2686
2698
|
* Get the current date range covered by our positions.
|
|
2687
2699
|
*/
|
|
@@ -2729,106 +2741,47 @@ var CesiumAnimatedProperty;
|
|
|
2729
2741
|
/*
|
|
2730
2742
|
* Returns the attitude of the record at an index, or nothing recorded when it names none.
|
|
2731
2743
|
*/
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2744
|
+
/*
|
|
2745
|
+
* Pitch and roll between two positions the short way round; an angle only one names is held.
|
|
2746
|
+
*/
|
|
2747
|
+
attitudeBetween(indexLast, indexNext, timeMs) {
|
|
2748
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2749
|
+
const a = indexLast >= 0 ? (_a = this.positions) === null || _a === void 0 ? void 0 : _a[indexLast] : null;
|
|
2750
|
+
const b = indexNext >= 0 ? (_b = this.positions) === null || _b === void 0 ? void 0 : _b[indexNext] : null;
|
|
2751
|
+
const span = a && b ? b.dateTime.getTime() - a.dateTime.getTime() : 0;
|
|
2752
|
+
const t = span > 0 ? (timeMs - a.dateTime.getTime()) / span : 0;
|
|
2753
|
+
const turn = (x, y) => {
|
|
2754
|
+
if (x == null || y == null) {
|
|
2755
|
+
return x !== null && x !== void 0 ? x : null;
|
|
2756
|
+
}
|
|
2757
|
+
return x + (Math$1.negativePiToPi(Math$1.toRadians(y - x)) * 180 / Math.PI) * t;
|
|
2758
|
+
};
|
|
2759
|
+
return { pitch: turn((_c = a === null || a === void 0 ? void 0 : a.pitch) !== null && _c !== void 0 ? _c : null, (_d = b === null || b === void 0 ? void 0 : b.pitch) !== null && _d !== void 0 ? _d : null), roll: turn((_e = a === null || a === void 0 ? void 0 : a.roll) !== null && _e !== void 0 ? _e : null, (_f = b === null || b === void 0 ? void 0 : b.roll) !== null && _f !== void 0 ? _f : null) };
|
|
2736
2760
|
}
|
|
2761
|
+
/*
|
|
2762
|
+
* Places the series at the scene's time, exactly rather than eased, so what moves with it never lags the clock.
|
|
2763
|
+
*/
|
|
2737
2764
|
update() {
|
|
2765
|
+
var _a;
|
|
2738
2766
|
if (!this.positions || this.positions.length === 0) {
|
|
2739
2767
|
return;
|
|
2740
2768
|
}
|
|
2741
|
-
//
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
const currentRealTimeMs = Date.now();
|
|
2746
|
-
// Calculate the ideal position based on current time.
|
|
2747
|
-
const targetPosition = this.calculatePosition(nowTimeMs);
|
|
2748
|
-
// Initialize if this is the first update.
|
|
2749
|
-
if (!this.lastCalcPos3d) {
|
|
2750
|
-
this.lastCalcPos3d = targetPosition.pos3d;
|
|
2751
|
-
this.lastCalcAttitude = this.attitudeAt(targetPosition.indexLast);
|
|
2752
|
-
this.onUpdate(targetPosition.pos3d, this.lastCalcHeading, this.lastCalcAttitude);
|
|
2753
|
-
return;
|
|
2754
|
-
}
|
|
2755
|
-
// Check if target has changed.
|
|
2756
|
-
if (!this.lastCalcPos3dApplyOverTimeTarget ||
|
|
2757
|
-
!Cartesian3.equals(this.lastCalcPos3dApplyOverTimeTarget, targetPosition.pos3d)) {
|
|
2758
|
-
// If we were already interpolating, get the current interpolated position as our new starting point.
|
|
2759
|
-
if (this.lastCalcPosApplyOverTime && this.lastCalcPos3dApplyOverTimeTimeStart) {
|
|
2760
|
-
// Calculate where we are in the current interpolation.
|
|
2761
|
-
const currentInterpolatedPos = this.interpolatePos3dOverTime(this.lastCalcPos3dApplyOverTimeTimeStart, currentRealTimeMs);
|
|
2762
|
-
// Use this as our new starting position.
|
|
2763
|
-
this.lastCalcPos3d = currentInterpolatedPos;
|
|
2764
|
-
}
|
|
2765
|
-
// Set new target and start time.
|
|
2766
|
-
this.lastCalcPos3dApplyOverTimeTarget = targetPosition.pos3d;
|
|
2767
|
-
this.lastCalcPos3dApplyOverTimeTimeStart = currentRealTimeMs;
|
|
2768
|
-
this.lastCalcPosApplyOverTime = true;
|
|
2769
|
-
}
|
|
2770
|
-
// Calculate the interpolated position.
|
|
2771
|
-
let pos3d;
|
|
2772
|
-
if (this.lastCalcPosApplyOverTime) {
|
|
2773
|
-
pos3d = this.interpolatePos3dOverTime(this.lastCalcPos3dApplyOverTimeTimeStart, currentRealTimeMs);
|
|
2774
|
-
// If we've reached the target, update our base position.
|
|
2775
|
-
if (Cartesian3.distance(pos3d, this.lastCalcPos3dApplyOverTimeTarget) < 0.01) {
|
|
2776
|
-
this.lastCalcPos3d = this.lastCalcPos3dApplyOverTimeTarget;
|
|
2777
|
-
this.lastCalcPosApplyOverTime = false;
|
|
2778
|
-
}
|
|
2769
|
+
// The clock's time is the frame being drawn; the last render time is the frame before it.
|
|
2770
|
+
const nowTimeMs = JulianDate.toDate(this.viewer.clock.currentTime).getTime();
|
|
2771
|
+
if (nowTimeMs === this.lastCalcTime && this.revision === this.lastCalcRevision) {
|
|
2772
|
+
return;
|
|
2779
2773
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
const currentToTargetDistance = Cartesian3.distance(this.lastCalcPos3d, this.lastCalcPos3dApplyOverTimeTarget);
|
|
2788
|
-
if (currentToTargetDistance >= minDistanceThreshold) {
|
|
2789
|
-
const lastPos = {
|
|
2790
|
-
pos3d: this.lastCalcPos3d,
|
|
2791
|
-
dateTime: this.lastCalcPos3dApplyOverTimeTimeStart ? new Date(this.lastCalcPos3dApplyOverTimeTimeStart) : null,
|
|
2792
|
-
heading: null
|
|
2793
|
-
};
|
|
2794
|
-
const nextPos = {
|
|
2795
|
-
pos3d: this.lastCalcPos3dApplyOverTimeTarget,
|
|
2796
|
-
dateTime: null,
|
|
2797
|
-
heading: null
|
|
2798
|
-
};
|
|
2799
|
-
if (lastPos && nextPos) {
|
|
2800
|
-
this.lastCalcHeading = this.calculateHeading(nowTimeMs, lastPos, nextPos);
|
|
2801
|
-
}
|
|
2802
|
-
}
|
|
2803
|
-
}
|
|
2774
|
+
this.lastCalcTime = nowTimeMs;
|
|
2775
|
+
this.lastCalcRevision = this.revision;
|
|
2776
|
+
const target = this.calculatePosition(nowTimeMs);
|
|
2777
|
+
const lastPos = this.positions[target.indexLast];
|
|
2778
|
+
const nextPos = this.positions[target.indexNext];
|
|
2779
|
+
if (lastPos && nextPos) {
|
|
2780
|
+
this.lastCalcHeading = (_a = this.calculateHeading(nowTimeMs, lastPos, nextPos)) !== null && _a !== void 0 ? _a : this.lastCalcHeading;
|
|
2804
2781
|
}
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
const nextPos = posses[targetPosition.indexNext];
|
|
2809
|
-
if (lastPos && nextPos) {
|
|
2810
|
-
this.lastCalcHeading = this.calculateHeading(nowTimeMs, lastPos, nextPos);
|
|
2811
|
-
}
|
|
2812
|
-
}
|
|
2813
|
-
// Provide the calculated values to the caller.
|
|
2814
|
-
this.lastCalcAttitude = this.attitudeAt(targetPosition.indexLast);
|
|
2815
|
-
this.onUpdate(pos3d, this.lastCalcHeading, this.lastCalcAttitude);
|
|
2816
|
-
}
|
|
2817
|
-
interpolatePos3dOverTime(startTimeMs, currentTimeMs) {
|
|
2818
|
-
const lastPos = this.lastCalcPos3d;
|
|
2819
|
-
const targetPos = this.lastCalcPos3dApplyOverTimeTarget;
|
|
2820
|
-
if (!lastPos || !targetPos) {
|
|
2821
|
-
return lastPos ? lastPos : targetPos;
|
|
2822
|
-
}
|
|
2823
|
-
const interpolationDuration = 200;
|
|
2824
|
-
const elapsedTime = currentTimeMs - startTimeMs;
|
|
2825
|
-
let progress = Math.min(elapsedTime / interpolationDuration, 1.0);
|
|
2826
|
-
// Optional step to make it smoother.
|
|
2827
|
-
progress = this.easeInOutQuad(progress);
|
|
2828
|
-
return Cartesian3.lerp(lastPos, targetPos, progress, new Cartesian3());
|
|
2829
|
-
}
|
|
2830
|
-
easeInOutQuad(t) {
|
|
2831
|
-
return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
|
|
2782
|
+
this.lastCalcPos3d = target.pos3d;
|
|
2783
|
+
this.lastCalcAttitude = this.attitudeBetween(target.indexLast, target.indexNext, nowTimeMs);
|
|
2784
|
+
this.onUpdate(target.pos3d, this.lastCalcHeading, this.lastCalcAttitude);
|
|
2832
2785
|
}
|
|
2833
2786
|
/**
|
|
2834
2787
|
* Pre-process headings in the series.
|
|
@@ -2854,14 +2807,14 @@ var CesiumAnimatedProperty;
|
|
|
2854
2807
|
* Calculate the position at the given time.
|
|
2855
2808
|
*/
|
|
2856
2809
|
calculatePosition(currentTimeMs) {
|
|
2810
|
+
var _a, _b;
|
|
2857
2811
|
const posses = this.positions;
|
|
2858
2812
|
// No positions to interpolate
|
|
2859
2813
|
if (!posses || posses.length === 0) {
|
|
2860
2814
|
return {
|
|
2861
2815
|
pos3d: new Cartesian3(),
|
|
2862
2816
|
indexLast: -1,
|
|
2863
|
-
indexNext: -1
|
|
2864
|
-
applyOverTime: false
|
|
2817
|
+
indexNext: -1
|
|
2865
2818
|
};
|
|
2866
2819
|
}
|
|
2867
2820
|
// See if we're before the first position.
|
|
@@ -2869,8 +2822,7 @@ var CesiumAnimatedProperty;
|
|
|
2869
2822
|
return {
|
|
2870
2823
|
pos3d: posses[0].pos3d,
|
|
2871
2824
|
indexLast: 0,
|
|
2872
|
-
indexNext: 0
|
|
2873
|
-
applyOverTime: true
|
|
2825
|
+
indexNext: 0
|
|
2874
2826
|
};
|
|
2875
2827
|
}
|
|
2876
2828
|
// See if we're after the last position.
|
|
@@ -2879,8 +2831,7 @@ var CesiumAnimatedProperty;
|
|
|
2879
2831
|
return {
|
|
2880
2832
|
pos3d: posses[lastIndex].pos3d,
|
|
2881
2833
|
indexLast: lastIndex,
|
|
2882
|
-
indexNext: lastIndex
|
|
2883
|
-
applyOverTime: true
|
|
2834
|
+
indexNext: lastIndex
|
|
2884
2835
|
};
|
|
2885
2836
|
}
|
|
2886
2837
|
// Binary search to find the closest position.
|
|
@@ -2906,20 +2857,25 @@ var CesiumAnimatedProperty;
|
|
|
2906
2857
|
return {
|
|
2907
2858
|
pos3d: last.pos3d,
|
|
2908
2859
|
indexLast: lastIndex,
|
|
2909
|
-
indexNext: lastIndex
|
|
2910
|
-
applyOverTime: true
|
|
2860
|
+
indexNext: lastIndex
|
|
2911
2861
|
};
|
|
2912
2862
|
}
|
|
2913
2863
|
// Interpolate between the two closest positions.
|
|
2914
2864
|
const lastTime = last.dateTime.getTime();
|
|
2915
2865
|
const nextTime = next.dateTime.getTime();
|
|
2916
2866
|
const progress = (currentTimeMs - lastTime) / (nextTime - lastTime);
|
|
2917
|
-
|
|
2867
|
+
// A straight line between two points on a curved path cuts inside it, so it is lifted back out.
|
|
2868
|
+
const chord = Cartesian3.lerp(last.pos3d, next.pos3d, progress, new Cartesian3());
|
|
2869
|
+
const chordCarto = Cartographic.fromCartesian(chord);
|
|
2870
|
+
const lastHeight = (_a = Cartographic.fromCartesian(last.pos3d)) === null || _a === void 0 ? void 0 : _a.height;
|
|
2871
|
+
const nextHeight = (_b = Cartographic.fromCartesian(next.pos3d)) === null || _b === void 0 ? void 0 : _b.height;
|
|
2872
|
+
const interpolatedPos = chordCarto && lastHeight != null && nextHeight != null
|
|
2873
|
+
? Cartesian3.fromRadians(chordCarto.longitude, chordCarto.latitude, Math$1.lerp(lastHeight, nextHeight, progress))
|
|
2874
|
+
: chord;
|
|
2918
2875
|
return {
|
|
2919
2876
|
pos3d: interpolatedPos,
|
|
2920
2877
|
indexLast: lastIndex,
|
|
2921
|
-
indexNext: nextIndex
|
|
2922
|
-
applyOverTime: false
|
|
2878
|
+
indexNext: nextIndex
|
|
2923
2879
|
};
|
|
2924
2880
|
}
|
|
2925
2881
|
/**
|
|
@@ -5493,6 +5449,485 @@ function ClusterItems(params) {
|
|
|
5493
5449
|
return result;
|
|
5494
5450
|
}
|
|
5495
5451
|
|
|
5452
|
+
/**
|
|
5453
|
+
* Entity data a caller asserts instead of what the API says, held for every menu item until it is cleared.
|
|
5454
|
+
*/
|
|
5455
|
+
var EntitySimulation;
|
|
5456
|
+
(function (EntitySimulation) {
|
|
5457
|
+
const VIEWER_KEY = "_nextspaceSimulation";
|
|
5458
|
+
/**
|
|
5459
|
+
* The set used when a caller does not name one.
|
|
5460
|
+
*/
|
|
5461
|
+
EntitySimulation.DEFAULT_SET = "default";
|
|
5462
|
+
// Record parts replaced whole rather than merged field by field, eg. a matrix or a geometry.
|
|
5463
|
+
const WHOLE_RECORD_PARTS = new Set(["geometry", "boundaries", "assemblyPosition"]);
|
|
5464
|
+
// Record parts that carry Entity data, in the order they are laid over an Entity.
|
|
5465
|
+
const RECORD_PARTS = ["location", "transform", "geometry", "boundaries", "assemblyPosition", "data"];
|
|
5466
|
+
/**
|
|
5467
|
+
* The store for a viewer, made on first use and shared by everything drawing into that scene.
|
|
5468
|
+
*/
|
|
5469
|
+
function Get(viewer) {
|
|
5470
|
+
if (!viewer) {
|
|
5471
|
+
return null;
|
|
5472
|
+
}
|
|
5473
|
+
if (!viewer[VIEWER_KEY]) {
|
|
5474
|
+
viewer[VIEWER_KEY] = new Store();
|
|
5475
|
+
}
|
|
5476
|
+
return viewer[VIEWER_KEY];
|
|
5477
|
+
}
|
|
5478
|
+
EntitySimulation.Get = Get;
|
|
5479
|
+
function isPlainObject(value) {
|
|
5480
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
5481
|
+
}
|
|
5482
|
+
// Entity values replaced whole by a patch, since half of one geometry over another describes neither.
|
|
5483
|
+
const WHOLE_ENTITY_PARTS = new Set(["VectorGeometry", "Boundaries", "AssemblyPosition"]);
|
|
5484
|
+
/**
|
|
5485
|
+
* Returns base with patch laid over it: objects merge key by key, anything else replaces.
|
|
5486
|
+
* @param whole names keys at the top level, or under Bruce, whose value is replaced rather than merged.
|
|
5487
|
+
*/
|
|
5488
|
+
function Overlay(base, patch, whole = WHOLE_ENTITY_PARTS) {
|
|
5489
|
+
const lay = (into, over, depth, underBruce) => {
|
|
5490
|
+
if (over === undefined) {
|
|
5491
|
+
return into;
|
|
5492
|
+
}
|
|
5493
|
+
if (!isPlainObject(over) || !isPlainObject(into)) {
|
|
5494
|
+
return over;
|
|
5495
|
+
}
|
|
5496
|
+
const merged = { ...into };
|
|
5497
|
+
for (const key of Object.keys(over)) {
|
|
5498
|
+
const replace = (depth === 0 || underBruce) && whole.has(key);
|
|
5499
|
+
merged[key] = replace ? over[key] : lay(merged[key], over[key], depth + 1, depth === 0 && key === "Bruce");
|
|
5500
|
+
}
|
|
5501
|
+
return merged;
|
|
5502
|
+
};
|
|
5503
|
+
return lay(base, patch, 0, false);
|
|
5504
|
+
}
|
|
5505
|
+
EntitySimulation.Overlay = Overlay;
|
|
5506
|
+
/*
|
|
5507
|
+
* Lays one record's parts over another's, each part replaced whole where a part is one value.
|
|
5508
|
+
*/
|
|
5509
|
+
function overlayRecord(base, over) {
|
|
5510
|
+
return Overlay(base, over, WHOLE_RECORD_PARTS);
|
|
5511
|
+
}
|
|
5512
|
+
/**
|
|
5513
|
+
* Each value a record names, as a path into the record. A part replaced whole is one value.
|
|
5514
|
+
*/
|
|
5515
|
+
function recordPaths(record) {
|
|
5516
|
+
const paths = [];
|
|
5517
|
+
const walk = (value, path) => {
|
|
5518
|
+
if (isPlainObject(value) && !(path.length === 1 && WHOLE_RECORD_PARTS.has(path[0]))) {
|
|
5519
|
+
for (const key of Object.keys(value)) {
|
|
5520
|
+
walk(value[key], [...path, key]);
|
|
5521
|
+
}
|
|
5522
|
+
return;
|
|
5523
|
+
}
|
|
5524
|
+
if (value !== undefined) {
|
|
5525
|
+
paths.push(path);
|
|
5526
|
+
}
|
|
5527
|
+
};
|
|
5528
|
+
for (const part of RECORD_PARTS) {
|
|
5529
|
+
if ((record === null || record === void 0 ? void 0 : record[part]) != null) {
|
|
5530
|
+
walk(record[part], [part]);
|
|
5531
|
+
}
|
|
5532
|
+
}
|
|
5533
|
+
return paths;
|
|
5534
|
+
}
|
|
5535
|
+
/*
|
|
5536
|
+
* A copy of the record without the values at these paths, dropping objects left empty.
|
|
5537
|
+
*/
|
|
5538
|
+
function withoutPaths(record, paths) {
|
|
5539
|
+
const strip = (value, path) => {
|
|
5540
|
+
if (!isPlainObject(value) || !(path[0] in value)) {
|
|
5541
|
+
return value;
|
|
5542
|
+
}
|
|
5543
|
+
const copy = { ...value };
|
|
5544
|
+
if (path.length === 1) {
|
|
5545
|
+
delete copy[path[0]];
|
|
5546
|
+
}
|
|
5547
|
+
else {
|
|
5548
|
+
const inner = strip(copy[path[0]], path.slice(1));
|
|
5549
|
+
if (isPlainObject(inner) && !Object.keys(inner).length) {
|
|
5550
|
+
delete copy[path[0]];
|
|
5551
|
+
}
|
|
5552
|
+
else {
|
|
5553
|
+
copy[path[0]] = inner;
|
|
5554
|
+
}
|
|
5555
|
+
}
|
|
5556
|
+
return copy;
|
|
5557
|
+
};
|
|
5558
|
+
let stripped = record;
|
|
5559
|
+
for (const path of paths) {
|
|
5560
|
+
stripped = strip(stripped, path);
|
|
5561
|
+
}
|
|
5562
|
+
return stripped;
|
|
5563
|
+
}
|
|
5564
|
+
/*
|
|
5565
|
+
* Whether a record still says anything about its Entity.
|
|
5566
|
+
*/
|
|
5567
|
+
function hasContent(record) {
|
|
5568
|
+
return RECORD_PARTS.some(part => {
|
|
5569
|
+
const value = record === null || record === void 0 ? void 0 : record[part];
|
|
5570
|
+
return value != null && !(isPlainObject(value) && !Object.keys(value).length);
|
|
5571
|
+
});
|
|
5572
|
+
}
|
|
5573
|
+
function timeOf(record) {
|
|
5574
|
+
return (record === null || record === void 0 ? void 0 : record.dateTime) ? new Date(record.dateTime).getTime() : NaN;
|
|
5575
|
+
}
|
|
5576
|
+
class Store {
|
|
5577
|
+
constructor() {
|
|
5578
|
+
// Insertion order is precedence: a later set wins.
|
|
5579
|
+
this.sets = new Map();
|
|
5580
|
+
this.onChanged = new BruceEvent();
|
|
5581
|
+
}
|
|
5582
|
+
/**
|
|
5583
|
+
* Triggered after anything is simulated or cleared, naming the Entities affected.
|
|
5584
|
+
*/
|
|
5585
|
+
get OnChanged() {
|
|
5586
|
+
return this.onChanged;
|
|
5587
|
+
}
|
|
5588
|
+
/**
|
|
5589
|
+
* Whether anything at all is simulated, so a caller can skip the work when nothing is.
|
|
5590
|
+
*/
|
|
5591
|
+
get IsEmpty() {
|
|
5592
|
+
for (const set of this.sets.values()) {
|
|
5593
|
+
if (set.entities.size || set.patches.size || set.records.size) {
|
|
5594
|
+
return false;
|
|
5595
|
+
}
|
|
5596
|
+
}
|
|
5597
|
+
return true;
|
|
5598
|
+
}
|
|
5599
|
+
/**
|
|
5600
|
+
* The names of the sets holding anything, oldest first.
|
|
5601
|
+
*/
|
|
5602
|
+
GetSets() {
|
|
5603
|
+
return Array.from(this.sets.keys());
|
|
5604
|
+
}
|
|
5605
|
+
/**
|
|
5606
|
+
* The time each set's records span, oldest set first, for sets holding any records.
|
|
5607
|
+
*/
|
|
5608
|
+
GetSetRanges() {
|
|
5609
|
+
const ranges = [];
|
|
5610
|
+
for (const [name, set] of this.sets) {
|
|
5611
|
+
let startMs = Infinity;
|
|
5612
|
+
let endMs = -Infinity;
|
|
5613
|
+
for (const byTime of set.records.values()) {
|
|
5614
|
+
for (const ms of byTime.keys()) {
|
|
5615
|
+
startMs = Math.min(startMs, ms);
|
|
5616
|
+
endMs = Math.max(endMs, ms);
|
|
5617
|
+
}
|
|
5618
|
+
}
|
|
5619
|
+
if (set.records.size) {
|
|
5620
|
+
ranges.push({ set: name, startMs, endMs, entityIds: Array.from(set.records.keys()) });
|
|
5621
|
+
}
|
|
5622
|
+
}
|
|
5623
|
+
return ranges;
|
|
5624
|
+
}
|
|
5625
|
+
setFor(name) {
|
|
5626
|
+
const key = name || EntitySimulation.DEFAULT_SET;
|
|
5627
|
+
let set = this.sets.get(key);
|
|
5628
|
+
if (!set) {
|
|
5629
|
+
set = { entities: new Map(), patches: new Map(), records: new Map() };
|
|
5630
|
+
this.sets.set(key, set);
|
|
5631
|
+
}
|
|
5632
|
+
return set;
|
|
5633
|
+
}
|
|
5634
|
+
/**
|
|
5635
|
+
* Replaces the stand-in for each Entity given, within a set.
|
|
5636
|
+
*/
|
|
5637
|
+
SetEntities(entities, set) {
|
|
5638
|
+
this.setBlobs(entities, set, false);
|
|
5639
|
+
}
|
|
5640
|
+
/**
|
|
5641
|
+
* Replaces the patch for each Entity given, within a set. A patch names only the data it changes.
|
|
5642
|
+
*/
|
|
5643
|
+
SetPatches(patches, set) {
|
|
5644
|
+
this.setBlobs(patches, set, true);
|
|
5645
|
+
}
|
|
5646
|
+
setBlobs(blobs, set, patch) {
|
|
5647
|
+
var _a;
|
|
5648
|
+
const ids = [];
|
|
5649
|
+
for (const blob of blobs || []) {
|
|
5650
|
+
const id = (_a = blob === null || blob === void 0 ? void 0 : blob.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
5651
|
+
if (!id) {
|
|
5652
|
+
continue;
|
|
5653
|
+
}
|
|
5654
|
+
const held = this.setFor(set);
|
|
5655
|
+
(patch ? held.patches : held.entities).set(id, blob);
|
|
5656
|
+
ids.push(id);
|
|
5657
|
+
}
|
|
5658
|
+
if (ids.length) {
|
|
5659
|
+
this.onChanged.Trigger({ entityIds: ids, entities: true, records: false, set: set || EntitySimulation.DEFAULT_SET });
|
|
5660
|
+
}
|
|
5661
|
+
}
|
|
5662
|
+
/**
|
|
5663
|
+
* Adds records to each Entity's simulated history within a set, replacing any at the same instant.
|
|
5664
|
+
*/
|
|
5665
|
+
SetRecords(records, set) {
|
|
5666
|
+
const ids = new Set();
|
|
5667
|
+
for (const record of records || []) {
|
|
5668
|
+
const id = record === null || record === void 0 ? void 0 : record.entityId;
|
|
5669
|
+
const timeMs = timeOf(record);
|
|
5670
|
+
if (!id || isNaN(timeMs)) {
|
|
5671
|
+
continue;
|
|
5672
|
+
}
|
|
5673
|
+
const held = this.setFor(set);
|
|
5674
|
+
let byTime = held.records.get(id);
|
|
5675
|
+
if (!byTime) {
|
|
5676
|
+
byTime = new Map();
|
|
5677
|
+
held.records.set(id, byTime);
|
|
5678
|
+
}
|
|
5679
|
+
byTime.set(timeMs, record);
|
|
5680
|
+
ids.add(id);
|
|
5681
|
+
}
|
|
5682
|
+
if (ids.size) {
|
|
5683
|
+
this.onChanged.Trigger({ entityIds: Array.from(ids), entities: false, records: true, set: set || EntitySimulation.DEFAULT_SET });
|
|
5684
|
+
}
|
|
5685
|
+
}
|
|
5686
|
+
/**
|
|
5687
|
+
* Forgets what is simulated for these Entities, or for every Entity when none are named.
|
|
5688
|
+
* @param params.set the set to clear. By default every set.
|
|
5689
|
+
* @param params.entities clear the stand-ins and patches. Default true.
|
|
5690
|
+
* @param params.records clear the historic records. Default true.
|
|
5691
|
+
*/
|
|
5692
|
+
Clear(params) {
|
|
5693
|
+
var _a, _b;
|
|
5694
|
+
const entities = (params === null || params === void 0 ? void 0 : params.entities) !== false;
|
|
5695
|
+
const records = (params === null || params === void 0 ? void 0 : params.records) !== false;
|
|
5696
|
+
const names = (params === null || params === void 0 ? void 0 : params.set) ? [params.set] : Array.from(this.sets.keys());
|
|
5697
|
+
const cleared = new Set();
|
|
5698
|
+
for (const name of names) {
|
|
5699
|
+
const set = this.sets.get(name);
|
|
5700
|
+
if (!set) {
|
|
5701
|
+
continue;
|
|
5702
|
+
}
|
|
5703
|
+
const ids = (_a = params === null || params === void 0 ? void 0 : params.entityIds) !== null && _a !== void 0 ? _a : [...set.entities.keys(), ...set.patches.keys(), ...set.records.keys()];
|
|
5704
|
+
for (const id of ids) {
|
|
5705
|
+
const hadEntity = entities && set.entities.delete(id);
|
|
5706
|
+
const hadPatch = entities && set.patches.delete(id);
|
|
5707
|
+
const hadRecords = records && set.records.delete(id);
|
|
5708
|
+
if (hadEntity || hadPatch || hadRecords) {
|
|
5709
|
+
cleared.add(id);
|
|
5710
|
+
}
|
|
5711
|
+
}
|
|
5712
|
+
if (!set.entities.size && !set.patches.size && !set.records.size) {
|
|
5713
|
+
this.sets.delete(name);
|
|
5714
|
+
}
|
|
5715
|
+
}
|
|
5716
|
+
if (cleared.size) {
|
|
5717
|
+
this.onChanged.Trigger({ entityIds: Array.from(cleared), entities, records, set: (_b = params === null || params === void 0 ? void 0 : params.set) !== null && _b !== void 0 ? _b : null });
|
|
5718
|
+
}
|
|
5719
|
+
}
|
|
5720
|
+
/**
|
|
5721
|
+
* The Entity's stand-in, with any patches laid over it, or null when nothing stands in for it.
|
|
5722
|
+
*/
|
|
5723
|
+
GetEntity(entityId) {
|
|
5724
|
+
var _a;
|
|
5725
|
+
let standIn = null;
|
|
5726
|
+
for (const set of this.sets.values()) {
|
|
5727
|
+
standIn = (_a = set.entities.get(entityId)) !== null && _a !== void 0 ? _a : standIn;
|
|
5728
|
+
}
|
|
5729
|
+
return standIn ? this.Overlay(standIn) : null;
|
|
5730
|
+
}
|
|
5731
|
+
/**
|
|
5732
|
+
* Whether a stand-in replaces this Entity, so the API need not be asked for it.
|
|
5733
|
+
*/
|
|
5734
|
+
HasEntity(entityId) {
|
|
5735
|
+
for (const set of this.sets.values()) {
|
|
5736
|
+
if (set.entities.has(entityId)) {
|
|
5737
|
+
return true;
|
|
5738
|
+
}
|
|
5739
|
+
}
|
|
5740
|
+
return false;
|
|
5741
|
+
}
|
|
5742
|
+
/**
|
|
5743
|
+
* Whether a stand-in or a patch changes this Entity.
|
|
5744
|
+
*/
|
|
5745
|
+
HasBlob(entityId) {
|
|
5746
|
+
for (const set of this.sets.values()) {
|
|
5747
|
+
if (set.entities.has(entityId) || set.patches.has(entityId)) {
|
|
5748
|
+
return true;
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
return false;
|
|
5752
|
+
}
|
|
5753
|
+
/**
|
|
5754
|
+
* Returns an Entity with its simulated patches laid over it. The input is never changed.
|
|
5755
|
+
*/
|
|
5756
|
+
Overlay(entity) {
|
|
5757
|
+
var _a;
|
|
5758
|
+
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
5759
|
+
if (!id) {
|
|
5760
|
+
return entity;
|
|
5761
|
+
}
|
|
5762
|
+
let result = entity;
|
|
5763
|
+
for (const set of this.sets.values()) {
|
|
5764
|
+
const patch = set.patches.get(id);
|
|
5765
|
+
if (patch) {
|
|
5766
|
+
result = Overlay(result, patch);
|
|
5767
|
+
}
|
|
5768
|
+
}
|
|
5769
|
+
return result;
|
|
5770
|
+
}
|
|
5771
|
+
/**
|
|
5772
|
+
* The Entity as simulated: its stand-in if there is one, otherwise what was read with patches laid over it.
|
|
5773
|
+
* @param entityId the Entity.
|
|
5774
|
+
* @param read what the API gave for it, if it was asked.
|
|
5775
|
+
*/
|
|
5776
|
+
Resolve(entityId, read) {
|
|
5777
|
+
var _a;
|
|
5778
|
+
return (_a = this.GetEntity(entityId)) !== null && _a !== void 0 ? _a : (read ? this.Overlay(read) : null);
|
|
5779
|
+
}
|
|
5780
|
+
/**
|
|
5781
|
+
* Every Entity with a simulated stand-in or patch.
|
|
5782
|
+
*/
|
|
5783
|
+
GetEntityIds() {
|
|
5784
|
+
const ids = new Set();
|
|
5785
|
+
for (const set of this.sets.values()) {
|
|
5786
|
+
set.entities.forEach((_, id) => ids.add(id));
|
|
5787
|
+
set.patches.forEach((_, id) => ids.add(id));
|
|
5788
|
+
}
|
|
5789
|
+
return Array.from(ids);
|
|
5790
|
+
}
|
|
5791
|
+
/**
|
|
5792
|
+
* Every Entity with simulated history.
|
|
5793
|
+
*/
|
|
5794
|
+
GetRecordEntityIds() {
|
|
5795
|
+
const ids = new Set();
|
|
5796
|
+
for (const set of this.sets.values()) {
|
|
5797
|
+
set.records.forEach((_, id) => ids.add(id));
|
|
5798
|
+
}
|
|
5799
|
+
return Array.from(ids);
|
|
5800
|
+
}
|
|
5801
|
+
/**
|
|
5802
|
+
* An Entity's simulated history for a historic key, oldest first, every set's record at an instant merged.
|
|
5803
|
+
*/
|
|
5804
|
+
GetRecords(entityId, attrKey) {
|
|
5805
|
+
const byTime = new Map();
|
|
5806
|
+
for (const set of this.sets.values()) {
|
|
5807
|
+
for (const [ms, record] of set.records.get(entityId) || []) {
|
|
5808
|
+
if (attrKey && record.attrKey && record.attrKey !== attrKey) {
|
|
5809
|
+
continue;
|
|
5810
|
+
}
|
|
5811
|
+
const held = byTime.get(ms);
|
|
5812
|
+
byTime.set(ms, held ? overlayRecord(held, record) : record);
|
|
5813
|
+
}
|
|
5814
|
+
}
|
|
5815
|
+
return Array.from(byTime.entries()).sort(([a], [b]) => a - b).map(([, record]) => record);
|
|
5816
|
+
}
|
|
5817
|
+
/**
|
|
5818
|
+
* Each value an Entity's simulated history names, with the instant from which it is the simulation's.
|
|
5819
|
+
*/
|
|
5820
|
+
ownedFrom(records) {
|
|
5821
|
+
const owned = new Map();
|
|
5822
|
+
for (const record of records) {
|
|
5823
|
+
const ms = timeOf(record);
|
|
5824
|
+
for (const path of recordPaths(record)) {
|
|
5825
|
+
const key = path.join("\u0000");
|
|
5826
|
+
if (!owned.has(key)) {
|
|
5827
|
+
owned.set(key, { path, fromMs: ms });
|
|
5828
|
+
}
|
|
5829
|
+
}
|
|
5830
|
+
}
|
|
5831
|
+
return Array.from(owned.values());
|
|
5832
|
+
}
|
|
5833
|
+
/**
|
|
5834
|
+
* An Entity as it stands at an instant, with each value its simulated records have named by then laid over it.
|
|
5835
|
+
* @param entity the Entity as read for that instant, from the API or a simulated stand-in.
|
|
5836
|
+
* @param timeMs the instant in milliseconds.
|
|
5837
|
+
* @param attrKey the historic attribute key being followed, or null for any.
|
|
5838
|
+
*/
|
|
5839
|
+
ApplyAt(entity, timeMs, attrKey) {
|
|
5840
|
+
var _a, _b, _c;
|
|
5841
|
+
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
5842
|
+
if (!id || timeMs == null || isNaN(timeMs)) {
|
|
5843
|
+
return entity;
|
|
5844
|
+
}
|
|
5845
|
+
// Laid oldest first, each record replacing only what it names, which leaves every value at its newest.
|
|
5846
|
+
let state = null;
|
|
5847
|
+
let stateMs = -Infinity;
|
|
5848
|
+
for (const record of this.GetRecords(id, attrKey)) {
|
|
5849
|
+
const ms = timeOf(record);
|
|
5850
|
+
if (ms > timeMs) {
|
|
5851
|
+
break;
|
|
5852
|
+
}
|
|
5853
|
+
const parts = {};
|
|
5854
|
+
for (const part of RECORD_PARTS) {
|
|
5855
|
+
if (record[part] != null) {
|
|
5856
|
+
parts[part] = record[part];
|
|
5857
|
+
}
|
|
5858
|
+
}
|
|
5859
|
+
state = state ? overlayRecord(state, parts) : parts;
|
|
5860
|
+
stateMs = ms;
|
|
5861
|
+
}
|
|
5862
|
+
if (!state) {
|
|
5863
|
+
return entity;
|
|
5864
|
+
}
|
|
5865
|
+
const bruce = { ...entity.Bruce };
|
|
5866
|
+
if (state.location) {
|
|
5867
|
+
bruce.Location = Overlay(bruce.Location, state.location);
|
|
5868
|
+
}
|
|
5869
|
+
if (state.transform) {
|
|
5870
|
+
bruce.Transform = Overlay(bruce.Transform, state.transform);
|
|
5871
|
+
}
|
|
5872
|
+
if (state.geometry) {
|
|
5873
|
+
bruce.VectorGeometry = state.geometry;
|
|
5874
|
+
}
|
|
5875
|
+
if (state.boundaries) {
|
|
5876
|
+
bruce.Boundaries = state.boundaries;
|
|
5877
|
+
}
|
|
5878
|
+
if (state.assemblyPosition) {
|
|
5879
|
+
bruce.AssemblyPosition = state.assemblyPosition;
|
|
5880
|
+
}
|
|
5881
|
+
// Says the newest record the Entity now reflects, the way a read at a point does.
|
|
5882
|
+
const outline = entity.Bruce.Outline || [];
|
|
5883
|
+
const readAt = outline.find(x => !!x.DateTime);
|
|
5884
|
+
const readMs = readAt ? new Date(readAt.DateTime).getTime() : -Infinity;
|
|
5885
|
+
const dated = {
|
|
5886
|
+
...(readAt || { "Source.Name": "Simulation", Editable: false, Kind: Entity$1.EOutlineKind.Attribute }),
|
|
5887
|
+
DateTime: new Date(Math.max(readMs, stateMs)).toISOString(),
|
|
5888
|
+
ForeignKey: (_b = readAt === null || readAt === void 0 ? void 0 : readAt.ForeignKey) !== null && _b !== void 0 ? _b : attrKey
|
|
5889
|
+
};
|
|
5890
|
+
bruce.Outline = [dated, ...outline.filter(x => x !== readAt)];
|
|
5891
|
+
const data = state.data ? Overlay({ ...entity, Bruce: undefined }, state.data) : entity;
|
|
5892
|
+
return { ...data, Bruce: Overlay(bruce, (_c = state.data) === null || _c === void 0 ? void 0 : _c.Bruce) };
|
|
5893
|
+
}
|
|
5894
|
+
/**
|
|
5895
|
+
* API records with the simulated ones joined in, for the named Entities or every simulated one.
|
|
5896
|
+
*/
|
|
5897
|
+
MergeRecords(recordsByIds, attrKey, entityIds) {
|
|
5898
|
+
if (this.IsEmpty) {
|
|
5899
|
+
return recordsByIds;
|
|
5900
|
+
}
|
|
5901
|
+
const ids = entityIds !== null && entityIds !== void 0 ? entityIds : this.GetRecordEntityIds();
|
|
5902
|
+
let merged = null;
|
|
5903
|
+
for (const id of ids) {
|
|
5904
|
+
const simulated = this.GetRecords(id, attrKey);
|
|
5905
|
+
if (!simulated.length) {
|
|
5906
|
+
continue;
|
|
5907
|
+
}
|
|
5908
|
+
const owned = this.ownedFrom(simulated);
|
|
5909
|
+
const byTime = new Map();
|
|
5910
|
+
for (const record of (recordsByIds === null || recordsByIds === void 0 ? void 0 : recordsByIds[id]) || []) {
|
|
5911
|
+
const ms = timeOf(record);
|
|
5912
|
+
const kept = withoutPaths(record, owned.filter(x => x.fromMs <= ms).map(x => x.path));
|
|
5913
|
+
if (hasContent(kept)) {
|
|
5914
|
+
byTime.set(ms, kept);
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
for (const record of simulated) {
|
|
5918
|
+
const ms = timeOf(record);
|
|
5919
|
+
const held = byTime.get(ms);
|
|
5920
|
+
byTime.set(ms, held ? overlayRecord(held, record) : record);
|
|
5921
|
+
}
|
|
5922
|
+
merged = merged !== null && merged !== void 0 ? merged : { ...(recordsByIds || {}) };
|
|
5923
|
+
merged[id] = Array.from(byTime.entries()).sort(([a], [b]) => a - b).map(([, record]) => record);
|
|
5924
|
+
}
|
|
5925
|
+
return merged !== null && merged !== void 0 ? merged : recordsByIds;
|
|
5926
|
+
}
|
|
5927
|
+
}
|
|
5928
|
+
EntitySimulation.Store = Store;
|
|
5929
|
+
})(EntitySimulation || (EntitySimulation = {}));
|
|
5930
|
+
|
|
5496
5931
|
/**
|
|
5497
5932
|
* Returns cesium property's value.
|
|
5498
5933
|
* This will check if it's one that changes over time, or just a fixed value.
|
|
@@ -5548,6 +5983,8 @@ var EntityLabel;
|
|
|
5548
5983
|
const PHOTO_CACHE_KEY = "_nextspaceLabelPhotos";
|
|
5549
5984
|
// Clearance around a model's box, as a share of its half-extent on each axis.
|
|
5550
5985
|
const MODEL_BOX_PADDING = 0.02;
|
|
5986
|
+
// How far a moving model's box may drift before it is moved, in metres.
|
|
5987
|
+
const MODEL_BOX_FOLLOW_TOLERANCE = 0.001;
|
|
5551
5988
|
// Share of each edge drawn out from its corners while the box is idle. Hovering draws the edges whole.
|
|
5552
5989
|
const MODEL_BOX_BRACKET = 0.2;
|
|
5553
5990
|
// Under this many pixels across, a box reads as a smudge and the ring takes over.
|
|
@@ -6764,6 +7201,7 @@ var EntityLabel;
|
|
|
6764
7201
|
constructor() {
|
|
6765
7202
|
// Whether a box competes for space comes only from inputs (camera distance, hover, the pointer), never from
|
|
6766
7203
|
// how its label was laid out, so an animation moving a label cannot feed back into which boxes show.
|
|
7204
|
+
// corners is where the box is drawn this frame: stored, moved by the entry's motion.
|
|
6767
7205
|
this.entries = new Map();
|
|
6768
7206
|
this.groups = null;
|
|
6769
7207
|
// The hovered Entity. Its box is drawn on its own and whole, ahead of every other box.
|
|
@@ -6781,7 +7219,7 @@ var EntityLabel;
|
|
|
6781
7219
|
Set(id, corners, entityId, inputs) {
|
|
6782
7220
|
const current = this.entries.get(id);
|
|
6783
7221
|
// A label rebuilt over the same box keeps its place and how far it has animated.
|
|
6784
|
-
if (corners && (current === null || current === void 0 ? void 0 : current.
|
|
7222
|
+
if (corners && (current === null || current === void 0 ? void 0 : current.stored) === corners && current.entityId === entityId) {
|
|
6785
7223
|
Object.assign(current, inputs);
|
|
6786
7224
|
return;
|
|
6787
7225
|
}
|
|
@@ -6789,17 +7227,41 @@ var EntityLabel;
|
|
|
6789
7227
|
return;
|
|
6790
7228
|
}
|
|
6791
7229
|
if (corners) {
|
|
6792
|
-
this.entries.set(id, { ...inputs, corners, entityId, active: false, wanted: false });
|
|
7230
|
+
this.entries.set(id, { ...inputs, corners, stored: corners, entityId, active: false, wanted: false });
|
|
6793
7231
|
}
|
|
6794
7232
|
else
|
|
6795
7233
|
this.entries.delete(id);
|
|
6796
7234
|
this.since.delete(id);
|
|
7235
|
+
this.forget(id);
|
|
7236
|
+
}
|
|
7237
|
+
/*
|
|
7238
|
+
* Drops the groups and outlines a box was in, so they are worked out again from where it is now.
|
|
7239
|
+
*/
|
|
7240
|
+
forget(id) {
|
|
6797
7241
|
this.groups = null;
|
|
6798
7242
|
for (const [key, group] of this.outlines) {
|
|
6799
7243
|
if (group.members.includes(id))
|
|
6800
7244
|
this.outlines.delete(key);
|
|
6801
7245
|
}
|
|
6802
7246
|
}
|
|
7247
|
+
/*
|
|
7248
|
+
* Moves each box whose model moved since the last frame, keeping where it has got to in showing.
|
|
7249
|
+
*/
|
|
7250
|
+
follow() {
|
|
7251
|
+
var _a;
|
|
7252
|
+
for (const [id, entry] of this.entries) {
|
|
7253
|
+
const motion = (_a = entry.motion) === null || _a === void 0 ? void 0 : _a.call(entry);
|
|
7254
|
+
if (!motion) {
|
|
7255
|
+
continue;
|
|
7256
|
+
}
|
|
7257
|
+
const moved = entry.stored.map(corner => Matrix4.multiplyByPoint(motion, corner, new Cartesian3()));
|
|
7258
|
+
if (moved.every((corner, i) => Cartesian3.equalsEpsilon(corner, entry.corners[i], 0, MODEL_BOX_FOLLOW_TOLERANCE))) {
|
|
7259
|
+
continue;
|
|
7260
|
+
}
|
|
7261
|
+
entry.corners = moved;
|
|
7262
|
+
this.forget(id);
|
|
7263
|
+
}
|
|
7264
|
+
}
|
|
6803
7265
|
/*
|
|
6804
7266
|
* The box drawn for a label this frame, or undefined when it has none or lost its place.
|
|
6805
7267
|
*/
|
|
@@ -6867,6 +7329,7 @@ var EntityLabel;
|
|
|
6867
7329
|
*/
|
|
6868
7330
|
Resolve(viewer, pointer) {
|
|
6869
7331
|
var _a, _b, _c, _d;
|
|
7332
|
+
this.follow();
|
|
6870
7333
|
this.frames.clear();
|
|
6871
7334
|
this.hulls.clear();
|
|
6872
7335
|
this.drawn = [];
|
|
@@ -7289,9 +7752,16 @@ var EntityLabel;
|
|
|
7289
7752
|
}
|
|
7290
7753
|
if (this.api) {
|
|
7291
7754
|
const rego = this.rego;
|
|
7755
|
+
const simulation = EntitySimulation.Get(this.viewer);
|
|
7756
|
+
let simulated = null;
|
|
7757
|
+
if (simulation === null || simulation === void 0 ? void 0 : simulation.HasBlob(rego.entityId)) {
|
|
7758
|
+
// A stand-in is named as is; a patch is laid over the API's record first.
|
|
7759
|
+
const read = simulation.HasEntity(rego.entityId) ? null : (await Entity$1.Get({ api: this.api, entityId: rego.entityId, migrated: true })).entity;
|
|
7760
|
+
simulated = simulation.Resolve(rego.entityId, read);
|
|
7761
|
+
}
|
|
7292
7762
|
this.rego.name = await Entity$1.CalculateNameAsync({
|
|
7293
7763
|
api: this.api,
|
|
7294
|
-
entity:
|
|
7764
|
+
entity: simulated,
|
|
7295
7765
|
entityId: rego.entityId,
|
|
7296
7766
|
defaultToId: false
|
|
7297
7767
|
});
|
|
@@ -7320,6 +7790,21 @@ var EntityLabel;
|
|
|
7320
7790
|
clearTimeout(this.loadTimeout);
|
|
7321
7791
|
this.loadTimeout = null;
|
|
7322
7792
|
}
|
|
7793
|
+
/*
|
|
7794
|
+
* Reads the label's Entity again and redraws it, eg. after what is simulated for it changed.
|
|
7795
|
+
*/
|
|
7796
|
+
Reload() {
|
|
7797
|
+
if (this.disposed) {
|
|
7798
|
+
return;
|
|
7799
|
+
}
|
|
7800
|
+
this.additionalTexts = this.options.text != null ? [] : null;
|
|
7801
|
+
this.loadedName = false;
|
|
7802
|
+
// The name came from whatever record the visual was drawn from, so it is worked out again too.
|
|
7803
|
+
if (this.rego) {
|
|
7804
|
+
this.rego.name = null;
|
|
7805
|
+
}
|
|
7806
|
+
this.createLabel();
|
|
7807
|
+
}
|
|
7323
7808
|
/*
|
|
7324
7809
|
* Rebuilds only when configuration changes; state refreshes must not recreate DOM every frame.
|
|
7325
7810
|
*/
|
|
@@ -7550,7 +8035,7 @@ var EntityLabel;
|
|
|
7550
8035
|
}
|
|
7551
8036
|
clearTimeout(this.loadTimeout);
|
|
7552
8037
|
this.loadTimeout = setTimeout(async () => {
|
|
7553
|
-
var _a, _b, _c, _d, _e;
|
|
8038
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7554
8039
|
if (this.disposed || this.counter != counter) {
|
|
7555
8040
|
return;
|
|
7556
8041
|
}
|
|
@@ -7577,16 +8062,19 @@ var EntityLabel;
|
|
|
7577
8062
|
const attributes = (_a = this.options.attributes) !== null && _a !== void 0 ? _a : (_c = (_b = entityType === null || entityType === void 0 ? void 0 : entityType.VisualSettings) === null || _b === void 0 ? void 0 : _b.label) === null || _c === void 0 ? void 0 : _c.attributes;
|
|
7578
8063
|
// Read for its attributes, and for a photo when the label has no icon of its own.
|
|
7579
8064
|
if (attributes || !HasIcon(this.options)) {
|
|
7580
|
-
|
|
8065
|
+
// A simulated stand-in is labelled as is, and a patch is laid over the API's.
|
|
8066
|
+
const simulation = EntitySimulation.Get(this.viewer);
|
|
8067
|
+
let entity = (_d = simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(this.rego.entityId)) !== null && _d !== void 0 ? _d : null;
|
|
7581
8068
|
try {
|
|
7582
|
-
entity = (await Entity$1.Get({
|
|
8069
|
+
entity = entity !== null && entity !== void 0 ? entity : (await Entity$1.Get({
|
|
7583
8070
|
api: this.api,
|
|
7584
8071
|
entityId: this.rego.entityId,
|
|
7585
|
-
scenario: ((
|
|
8072
|
+
scenario: ((_e = this.rego.outline) === null || _e === void 0 ? void 0 : _e.length) ? (_f = this.rego.outline.find(x => !!x.Scenario)) === null || _f === void 0 ? void 0 : _f.Scenario : null,
|
|
7586
8073
|
schemaId: this.rego.schema,
|
|
7587
8074
|
migrated: true,
|
|
7588
8075
|
expandAttachments: !HasIcon(this.options)
|
|
7589
8076
|
})).entity;
|
|
8077
|
+
entity = entity && simulation ? simulation.Resolve(this.rego.entityId, entity) : entity;
|
|
7590
8078
|
}
|
|
7591
8079
|
// Entity doesn't exist.
|
|
7592
8080
|
// Likely a graphic with an ID that points to no record.
|
|
@@ -7970,11 +8458,17 @@ var EntityLabel;
|
|
|
7970
8458
|
// Past the wait a slow record no longer holds the label back; a box that comes later eases in.
|
|
7971
8459
|
setTimeout(settle, MODEL_BOX_WAIT);
|
|
7972
8460
|
this.modelBox.load.then(corners => {
|
|
8461
|
+
var _a, _b;
|
|
7973
8462
|
if (!corners || this.disposed || this.counter !== counter) {
|
|
7974
8463
|
return;
|
|
7975
8464
|
}
|
|
7976
8465
|
// A record that disagrees with where the model was found describes another placement, such as a moved tileset.
|
|
8466
|
+
// A part known to have moved from its record, eg. a joint turning, is judged where it has moved to.
|
|
8467
|
+
const motion = (_b = (_a = this.rego) === null || _a === void 0 ? void 0 : _a.motion) === null || _b === void 0 ? void 0 : _b.call(_a, this.viewer.clock.currentTime);
|
|
7977
8468
|
const centre = Cartesian3.midpoint(corners[0], corners[7], new Cartesian3());
|
|
8469
|
+
if (motion) {
|
|
8470
|
+
Matrix4.multiplyByPoint(motion, centre, centre);
|
|
8471
|
+
}
|
|
7978
8472
|
if (Cartesian3.distance(centre, found) > Cartesian3.distance(corners[0], corners[7]) * 0.75 + 2) {
|
|
7979
8473
|
return;
|
|
7980
8474
|
}
|
|
@@ -7982,6 +8476,7 @@ var EntityLabel;
|
|
|
7982
8476
|
// Let go a little further out than it is taken, so a camera resting at the limit does not flip it.
|
|
7983
8477
|
let near = false;
|
|
7984
8478
|
layer.modelBoxes.Set(this.id, corners, rego.entityId, {
|
|
8479
|
+
motion: rego.motion ? () => rego.motion(this.viewer.clock.currentTime) : undefined,
|
|
7985
8480
|
selected: () => { var _a, _b; return Boolean((_b = (_a = this.visualRegister) === null || _a === void 0 ? void 0 : _a.GetState({ entityId: rego.entityId, menuItemId: rego.menuItemId })) === null || _b === void 0 ? void 0 : _b.selected); },
|
|
7986
8481
|
hovered: () => { var _a, _b; return Boolean((_b = (_a = this.visualRegister) === null || _a === void 0 ? void 0 : _a.IsLabelHovered) === null || _b === void 0 ? void 0 : _b.call(_a, rego.entityId, rego.menuItemId)); },
|
|
7987
8482
|
near: () => {
|
|
@@ -8963,9 +9458,9 @@ var EntityLabelGroup;
|
|
|
8963
9458
|
* Reads the entities behind items that name one without carrying it, attachments included,
|
|
8964
9459
|
* so a label's default image needs no second request.
|
|
8965
9460
|
*/
|
|
8966
|
-
async function Hydrate(items, api, signal) {
|
|
9461
|
+
async function Hydrate(items, api, signal, simulation) {
|
|
8967
9462
|
var _a, _b;
|
|
8968
|
-
if (!api) {
|
|
9463
|
+
if (!api && !simulation) {
|
|
8969
9464
|
return items;
|
|
8970
9465
|
}
|
|
8971
9466
|
const hydrated = items.slice();
|
|
@@ -8976,12 +9471,15 @@ var EntityLabelGroup;
|
|
|
8976
9471
|
}
|
|
8977
9472
|
const chunk = missing.slice(start, start + HYDRATE_AT_ONCE);
|
|
8978
9473
|
try {
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
}
|
|
9474
|
+
// A simulated stand-in is labelled as is, never from the API, and a patch is laid over the API's.
|
|
9475
|
+
const asked = chunk.filter(at => !(simulation === null || simulation === void 0 ? void 0 : simulation.HasEntity(hydrated[at].entityId)));
|
|
9476
|
+
const { entities } = api && asked.length ? await Entity$1.GetListByIds({
|
|
9477
|
+
api, entityIds: asked.map(at => hydrated[at].entityId), expandAttachments: true, migrated: true
|
|
9478
|
+
}) : { entities: [] };
|
|
8982
9479
|
const found = new Map((entities !== null && entities !== void 0 ? entities : []).map(entity => { var _a; return [(_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID, entity]; }));
|
|
8983
9480
|
for (const at of chunk) {
|
|
8984
|
-
const
|
|
9481
|
+
const id = hydrated[at].entityId;
|
|
9482
|
+
const entity = simulation ? simulation.Resolve(id, found.get(id)) : found.get(id);
|
|
8985
9483
|
if (entity) {
|
|
8986
9484
|
// The API leaves Attachment out when there are none; an empty list records that they were read.
|
|
8987
9485
|
hydrated[at] = { ...hydrated[at], entity: { ...entity, Bruce: { ...entity.Bruce, Attachment: (_b = (_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.Attachment) !== null && _b !== void 0 ? _b : [] } } };
|
|
@@ -8998,7 +9496,7 @@ var EntityLabelGroup;
|
|
|
8998
9496
|
/*
|
|
8999
9497
|
* Uses the existing DataLab grammar, discarding actions and projections that cannot return Entities.
|
|
9000
9498
|
*/
|
|
9001
|
-
async function Loader(source, api, signal, hydrate) {
|
|
9499
|
+
async function Loader(source, api, signal, hydrate, simulation) {
|
|
9002
9500
|
var _a;
|
|
9003
9501
|
var _b;
|
|
9004
9502
|
if (source.type === "provider") {
|
|
@@ -9013,7 +9511,7 @@ var EntityLabelGroup;
|
|
|
9013
9511
|
return async (offset, limit, signal) => {
|
|
9014
9512
|
const page = items.slice(offset, offset + limit);
|
|
9015
9513
|
return {
|
|
9016
|
-
items: hydrate ? await Hydrate(page, api, signal) : page,
|
|
9514
|
+
items: hydrate ? await Hydrate(page, api, signal, simulation) : page,
|
|
9017
9515
|
hasMore: offset + limit < items.length
|
|
9018
9516
|
};
|
|
9019
9517
|
};
|
|
@@ -9155,7 +9653,7 @@ var EntityLabelGroup;
|
|
|
9155
9653
|
const items = new Map();
|
|
9156
9654
|
let truncated = false;
|
|
9157
9655
|
try {
|
|
9158
|
-
const load = await Loader(definition.source, (_g = this.register.ApiGetters) === null || _g === void 0 ? void 0 : _g.GetBruceApi(), controller.signal, NeedsEntityData(definition.options));
|
|
9656
|
+
const load = await Loader(definition.source, (_g = this.register.ApiGetters) === null || _g === void 0 ? void 0 : _g.GetBruceApi(), controller.signal, NeedsEntityData(definition.options), EntitySimulation.Get(this.register.Viewer));
|
|
9159
9657
|
let offset = 0;
|
|
9160
9658
|
for (let pageNumber = 0;; pageNumber++) {
|
|
9161
9659
|
if (controller.signal.aborted || this.register.Disposed) {
|
|
@@ -9977,8 +10475,25 @@ var RelationRenderEngine;
|
|
|
9977
10475
|
return `${relation["Related.Entity.ID"]}-${relation["Principal.Entity.ID"]}-${relation["Relation.Type.ID"]}`;
|
|
9978
10476
|
}
|
|
9979
10477
|
RelationRenderEngine.GetRenderGroupId = GetRenderGroupId;
|
|
10478
|
+
/**
|
|
10479
|
+
* Removes and returns a menu item's drawn relations that end at, or carry data from, any of these Entities.
|
|
10480
|
+
*/
|
|
10481
|
+
function TakeRelationsTouching(params) {
|
|
10482
|
+
const { visualRegister, menuItemId } = params;
|
|
10483
|
+
const ids = new Set(params.entityIds);
|
|
10484
|
+
const touched = visualRegister.GetRegos({ menuItemId }).filter((rego) => {
|
|
10485
|
+
const relation = rego.relation;
|
|
10486
|
+
return relation && [relation["Principal.Entity.ID"], relation["Related.Entity.ID"], relation["Data.Entity.ID"]]
|
|
10487
|
+
.some(id => id && ids.has(id));
|
|
10488
|
+
});
|
|
10489
|
+
for (const rego of touched) {
|
|
10490
|
+
visualRegister.RemoveRegos({ relation: rego.relation, entityId: rego.entityId, menuItemId, requestRender: false });
|
|
10491
|
+
}
|
|
10492
|
+
return touched.map(rego => rego.relation);
|
|
10493
|
+
}
|
|
10494
|
+
RelationRenderEngine.TakeRelationsTouching = TakeRelationsTouching;
|
|
9980
10495
|
async function Render(params) {
|
|
9981
|
-
const { apiGetter, viewer, visualRegister, menuItemId, relations } = params;
|
|
10496
|
+
const { apiGetter, viewer, visualRegister, menuItemId, relations, simulation } = params;
|
|
9982
10497
|
const api = apiGetter.getApi(apiGetter.accountId);
|
|
9983
10498
|
const rendered = {};
|
|
9984
10499
|
let neededEntityIdsIds = [];
|
|
@@ -9996,13 +10511,15 @@ var RelationRenderEngine;
|
|
|
9996
10511
|
}
|
|
9997
10512
|
// Turn the set unique.
|
|
9998
10513
|
neededEntityIdsIds = neededEntityIdsIds.filter((v, i, a) => a.indexOf(v) === i);
|
|
9999
|
-
// Get all entities in one go.
|
|
10000
|
-
|
|
10001
|
-
|
|
10514
|
+
// Get all entities in one go, other than the simulated ones.
|
|
10515
|
+
const simulated = neededEntityIdsIds.map(id => simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(id)).filter(x => !!x);
|
|
10516
|
+
const apiIds = neededEntityIdsIds.filter(id => !(simulation === null || simulation === void 0 ? void 0 : simulation.HasEntity(id)));
|
|
10517
|
+
let entities = (apiIds.length ? (await Entity$1.GetListByIds({
|
|
10518
|
+
entityIds: apiIds,
|
|
10002
10519
|
api: apiGetter.getApi(),
|
|
10003
10520
|
migrated: true,
|
|
10004
10521
|
maxSearchTimeSec: 60 * 2
|
|
10005
|
-
})).entities;
|
|
10522
|
+
})).entities.map(entity => simulation ? simulation.Overlay(entity) : entity) : []).concat(simulated);
|
|
10006
10523
|
// Create a map for quick reference.
|
|
10007
10524
|
const entitiesMap = {};
|
|
10008
10525
|
for (let i = 0; i < entities.length; i++) {
|
|
@@ -10496,6 +11013,8 @@ function isCullingIgnored(viewer, rego) {
|
|
|
10496
11013
|
rego.overrideShow != null ||
|
|
10497
11014
|
// Being dragged around right now, so its extent is changing faster than we could measure it.
|
|
10498
11015
|
rego.editing == true ||
|
|
11016
|
+
// Placed by the clock every frame, so no measurement of where it is stays true.
|
|
11017
|
+
rego.moving == true ||
|
|
10499
11018
|
// Part of a collection we did not create, eg. a geojson data source, which may have its own rules for
|
|
10500
11019
|
// what is in the scene. Our own per-menu-item data sources are fair game.
|
|
10501
11020
|
VisualsRegister.IsForeignCollection(rego) ||
|
|
@@ -11335,6 +11854,7 @@ var VisualsRegister;
|
|
|
11335
11854
|
}
|
|
11336
11855
|
get OnLabelGroupsChanged() { return this.labelGroupsChanged; }
|
|
11337
11856
|
constructor(params) {
|
|
11857
|
+
var _a, _b;
|
|
11338
11858
|
this.id = ObjectUtils.UId();
|
|
11339
11859
|
this.disposed = false;
|
|
11340
11860
|
this.rego = {};
|
|
@@ -11374,6 +11894,8 @@ var VisualsRegister;
|
|
|
11374
11894
|
this.menuItemSources = new Map();
|
|
11375
11895
|
// Set when the data source order no longer matches the zIndexes seen, so it is re-applied once.
|
|
11376
11896
|
this.sourceOrderDirty = false;
|
|
11897
|
+
// Stops following what is simulated, so labels can read it again when it changes.
|
|
11898
|
+
this.simulationRemoval = null;
|
|
11377
11899
|
this.labelGroupsChanged = new BruceEvent();
|
|
11378
11900
|
this.hoverRingState = {};
|
|
11379
11901
|
this.retiringHoverLabels = new Map();
|
|
@@ -11408,6 +11930,33 @@ var VisualsRegister;
|
|
|
11408
11930
|
this.cameraCullerDispose = VisualRegisterCuller.Monitor({
|
|
11409
11931
|
register: this
|
|
11410
11932
|
});
|
|
11933
|
+
this.simulationRemoval = (_b = (_a = EntitySimulation.Get(this.viewer)) === null || _a === void 0 ? void 0 : _a.OnChanged.Subscribe((change) => this.reloadLabels(change.entityIds))) !== null && _b !== void 0 ? _b : null;
|
|
11934
|
+
}
|
|
11935
|
+
/*
|
|
11936
|
+
* Tells labels to read their Entity again, since they keep what they read when drawn.
|
|
11937
|
+
*/
|
|
11938
|
+
reloadLabels(entityIds) {
|
|
11939
|
+
var _a, _b, _c, _d;
|
|
11940
|
+
if (this.disposed) {
|
|
11941
|
+
return;
|
|
11942
|
+
}
|
|
11943
|
+
const groupIds = new Set();
|
|
11944
|
+
for (const entityId of entityIds) {
|
|
11945
|
+
for (const rego of this.GetRegos({ entityId })) {
|
|
11946
|
+
(_a = EntityLabel.GetLabel({ rego })) === null || _a === void 0 ? void 0 : _a.Reload();
|
|
11947
|
+
}
|
|
11948
|
+
if (((_b = this.labelHover) === null || _b === void 0 ? void 0 : _b.entityId) === entityId) {
|
|
11949
|
+
(_c = this.hoverLabel) === null || _c === void 0 ? void 0 : _c.Reload();
|
|
11950
|
+
}
|
|
11951
|
+
const groupId = (_d = this.GetLabelGroupFor(entityId)) === null || _d === void 0 ? void 0 : _d.groupId;
|
|
11952
|
+
if (groupId) {
|
|
11953
|
+
groupIds.add(groupId);
|
|
11954
|
+
}
|
|
11955
|
+
}
|
|
11956
|
+
// A group may have read the Entity in with its items, so the group is read again as a whole.
|
|
11957
|
+
for (const groupId of groupIds) {
|
|
11958
|
+
this.RefreshLabelGroup(groupId).catch((e) => console.error(e));
|
|
11959
|
+
}
|
|
11411
11960
|
}
|
|
11412
11961
|
/**
|
|
11413
11962
|
* Returns the collection a menu item's visuals belong in, creating its data source on first use.
|
|
@@ -12310,7 +12859,9 @@ var VisualsRegister;
|
|
|
12310
12859
|
(_b = this.viewer.scene) === null || _b === void 0 ? void 0 : _b.requestRender();
|
|
12311
12860
|
}
|
|
12312
12861
|
Dispose() {
|
|
12313
|
-
var _a, _b, _c, _d, _e;
|
|
12862
|
+
var _a, _b, _c, _d, _e, _f;
|
|
12863
|
+
(_a = this.simulationRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
12864
|
+
this.simulationRemoval = null;
|
|
12314
12865
|
CesiumEntityStyler.SetDimming(this.viewer, this.id, false);
|
|
12315
12866
|
this.ClearLabelHover();
|
|
12316
12867
|
clearTimeout(this.hoverRingReset);
|
|
@@ -12320,14 +12871,14 @@ var VisualsRegister;
|
|
|
12320
12871
|
EntityLabel.Detatch({ label });
|
|
12321
12872
|
}
|
|
12322
12873
|
this.retiringHoverLabels.clear();
|
|
12323
|
-
(
|
|
12874
|
+
(_b = this.labelGroups) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
12324
12875
|
this.labelGroupsChanged.Clear();
|
|
12325
12876
|
for (const regos of Object.values(this.rego)) {
|
|
12326
12877
|
for (const rego of regos)
|
|
12327
12878
|
EntityLabel.Detatch({ rego, force: true });
|
|
12328
12879
|
}
|
|
12329
12880
|
EntityLabel.SetContainer(this.viewer);
|
|
12330
|
-
(
|
|
12881
|
+
(_c = this.cameraCullerDispose) === null || _c === void 0 ? void 0 : _c.call(this, {
|
|
12331
12882
|
uncull: false
|
|
12332
12883
|
});
|
|
12333
12884
|
this.cameraCullerDispose = null;
|
|
@@ -12343,7 +12894,7 @@ var VisualsRegister;
|
|
|
12343
12894
|
this.disposed = true;
|
|
12344
12895
|
for (const record of Array.from(this.menuItemSources.values())) {
|
|
12345
12896
|
try {
|
|
12346
|
-
(
|
|
12897
|
+
(_e = (_d = this.viewer) === null || _d === void 0 ? void 0 : _d.dataSources) === null || _e === void 0 ? void 0 : _e.remove(record.source, true);
|
|
12347
12898
|
}
|
|
12348
12899
|
catch (e) {
|
|
12349
12900
|
console.error(e);
|
|
@@ -12352,7 +12903,7 @@ var VisualsRegister;
|
|
|
12352
12903
|
this.menuItemSources.clear();
|
|
12353
12904
|
// Hand every tileset's show flag back to its owner, holding whatever the owner last asked for.
|
|
12354
12905
|
for (const rego of Array.from(this.tilesets.values())) {
|
|
12355
|
-
(
|
|
12906
|
+
(_f = rego.gate) === null || _f === void 0 ? void 0 : _f.Release();
|
|
12356
12907
|
}
|
|
12357
12908
|
this.tilesets.clear();
|
|
12358
12909
|
}
|
|
@@ -12526,21 +13077,7 @@ var VisualsRegister;
|
|
|
12526
13077
|
changed = true;
|
|
12527
13078
|
}
|
|
12528
13079
|
if (editing) {
|
|
12529
|
-
|
|
12530
|
-
entity: rego.visual
|
|
12531
|
-
});
|
|
12532
|
-
for (let k = 0; k < parts.length; k++) {
|
|
12533
|
-
const part = parts[k];
|
|
12534
|
-
if (!(part instanceof Entity)) {
|
|
12535
|
-
continue;
|
|
12536
|
-
}
|
|
12537
|
-
const removalPending = VisualRegisterCuller.CancelQueuedSceneChange(part);
|
|
12538
|
-
const wasCulled = part[VisualRegisterCuller.VISUAL_CULL_KEY] == true || removalPending;
|
|
12539
|
-
delete part[VisualRegisterCuller.VISUAL_CULL_KEY];
|
|
12540
|
-
if (wasCulled && !IsCEntityInScene(this.viewer, part)) {
|
|
12541
|
-
AddCEntityToScene(this.viewer, part, rego.collection);
|
|
12542
|
-
}
|
|
12543
|
-
}
|
|
13080
|
+
this.restoreCulled(rego);
|
|
12544
13081
|
}
|
|
12545
13082
|
else {
|
|
12546
13083
|
VisualRegisterCuller.InvalidateBounds(rego.visual);
|
|
@@ -12552,6 +13089,56 @@ var VisualsRegister;
|
|
|
12552
13089
|
(_b = (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.scene) === null || _b === void 0 ? void 0 : _b.requestRender();
|
|
12553
13090
|
}
|
|
12554
13091
|
}
|
|
13092
|
+
/**
|
|
13093
|
+
* Marks visuals as placed by the clock, exempting them from culling until it is turned back off.
|
|
13094
|
+
*/
|
|
13095
|
+
SetMoving(params) {
|
|
13096
|
+
const { entityIds, moving, menuItemId } = params;
|
|
13097
|
+
if (!(entityIds === null || entityIds === void 0 ? void 0 : entityIds.length)) {
|
|
13098
|
+
return;
|
|
13099
|
+
}
|
|
13100
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
13101
|
+
const regos = this.rego[entityIds[i]];
|
|
13102
|
+
if (!regos) {
|
|
13103
|
+
continue;
|
|
13104
|
+
}
|
|
13105
|
+
for (let j = 0; j < regos.length; j++) {
|
|
13106
|
+
const rego = regos[j];
|
|
13107
|
+
if ((menuItemId && rego.menuItemId !== menuItemId) || Boolean(rego.moving) == Boolean(moving)) {
|
|
13108
|
+
continue;
|
|
13109
|
+
}
|
|
13110
|
+
// Null rather than false, so the rego does not carry a key for every visual that ever moved.
|
|
13111
|
+
rego.moving = moving ? true : null;
|
|
13112
|
+
if (moving) {
|
|
13113
|
+
this.restoreCulled(rego);
|
|
13114
|
+
}
|
|
13115
|
+
else {
|
|
13116
|
+
VisualRegisterCuller.InvalidateBounds(rego.visual);
|
|
13117
|
+
VisualRegisterCuller.MarkShouldRecheck(this.viewer);
|
|
13118
|
+
}
|
|
13119
|
+
}
|
|
13120
|
+
}
|
|
13121
|
+
}
|
|
13122
|
+
/*
|
|
13123
|
+
* Puts back whatever the culler took out of a visual that is now exempt from it.
|
|
13124
|
+
*/
|
|
13125
|
+
restoreCulled(rego) {
|
|
13126
|
+
const parts = EntityUtils.GatherEntity({
|
|
13127
|
+
entity: rego.visual
|
|
13128
|
+
});
|
|
13129
|
+
for (let k = 0; k < parts.length; k++) {
|
|
13130
|
+
const part = parts[k];
|
|
13131
|
+
if (!(part instanceof Entity)) {
|
|
13132
|
+
continue;
|
|
13133
|
+
}
|
|
13134
|
+
const removalPending = VisualRegisterCuller.CancelQueuedSceneChange(part);
|
|
13135
|
+
const wasCulled = part[VisualRegisterCuller.VISUAL_CULL_KEY] == true || removalPending;
|
|
13136
|
+
delete part[VisualRegisterCuller.VISUAL_CULL_KEY];
|
|
13137
|
+
if (wasCulled && !IsCEntityInScene(this.viewer, part)) {
|
|
13138
|
+
AddCEntityToScene(this.viewer, part, rego.collection);
|
|
13139
|
+
}
|
|
13140
|
+
}
|
|
13141
|
+
}
|
|
12555
13142
|
SetSelected(params) {
|
|
12556
13143
|
var _a;
|
|
12557
13144
|
let { entityIds, selected, refreshIfSelected, requestRender, menuItemId, source } = params;
|
|
@@ -14044,12 +14631,41 @@ var VisualsRegister;
|
|
|
14044
14631
|
* Tracks per-entity rerender state for unsaved blob maintenance and stale API response suppression.
|
|
14045
14632
|
*/
|
|
14046
14633
|
class EntityReRenderMaintainState {
|
|
14047
|
-
constructor() {
|
|
14634
|
+
constructor(simulation, pointInTime) {
|
|
14635
|
+
this.simulation = simulation;
|
|
14636
|
+
this.pointInTime = pointInTime;
|
|
14048
14637
|
this.maintainedEntitiesById = {};
|
|
14049
14638
|
this.apiRevisionByEntityId = {};
|
|
14050
14639
|
this.skipApiRunByEntityId = {};
|
|
14051
14640
|
this.checkRunId = 0;
|
|
14052
14641
|
}
|
|
14642
|
+
/*
|
|
14643
|
+
* Lays each Entity's simulated record for the current point over it, when the manager reads at one.
|
|
14644
|
+
*/
|
|
14645
|
+
atPoint(entities) {
|
|
14646
|
+
var _a;
|
|
14647
|
+
const point = (_a = this.pointInTime) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
14648
|
+
if (!point || !this.simulation || this.simulation.IsEmpty || !(entities === null || entities === void 0 ? void 0 : entities.length)) {
|
|
14649
|
+
return entities;
|
|
14650
|
+
}
|
|
14651
|
+
return entities.map((entity) => this.simulation.ApplyAt(entity, point.timeMs, point.attrKey));
|
|
14652
|
+
}
|
|
14653
|
+
/**
|
|
14654
|
+
* Whether a simulated stand-in replaces this Entity, so nothing from the API may replace what is drawn.
|
|
14655
|
+
*/
|
|
14656
|
+
isSimulated(entityId) {
|
|
14657
|
+
var _a;
|
|
14658
|
+
return Boolean(entityId && ((_a = this.simulation) === null || _a === void 0 ? void 0 : _a.HasEntity(entityId)));
|
|
14659
|
+
}
|
|
14660
|
+
/**
|
|
14661
|
+
* Swaps any simulated Entity in a set the API returned for its stand-in, or lays its patch over it.
|
|
14662
|
+
*/
|
|
14663
|
+
withSimulated(entities) {
|
|
14664
|
+
if (!this.simulation || this.simulation.IsEmpty || !(entities === null || entities === void 0 ? void 0 : entities.length)) {
|
|
14665
|
+
return entities;
|
|
14666
|
+
}
|
|
14667
|
+
return this.atPoint(entities.map((entity) => { var _a, _b; return (_b = this.simulation.Resolve((_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID, entity)) !== null && _b !== void 0 ? _b : entity; }));
|
|
14668
|
+
}
|
|
14053
14669
|
setMaintainedEntities(entities) {
|
|
14054
14670
|
var _a;
|
|
14055
14671
|
for (let i = 0; i < entities.length; i++) {
|
|
@@ -14071,15 +14687,21 @@ class EntityReRenderMaintainState {
|
|
|
14071
14687
|
}
|
|
14072
14688
|
}
|
|
14073
14689
|
getMaintainedEntities(entityIds) {
|
|
14690
|
+
var _a;
|
|
14074
14691
|
const entities = [];
|
|
14075
14692
|
for (let i = 0; i < entityIds.length; i++) {
|
|
14076
14693
|
const id = entityIds[i];
|
|
14077
14694
|
if (!id) {
|
|
14078
14695
|
continue;
|
|
14079
14696
|
}
|
|
14080
|
-
|
|
14081
|
-
|
|
14082
|
-
|
|
14697
|
+
// A maintained blob is this manager's own unsaved edit, newer than a simulation, so it is drawn as is.
|
|
14698
|
+
const maintained = this.maintainedEntitiesById[id];
|
|
14699
|
+
const simulated = maintained ? null : (_a = this.simulation) === null || _a === void 0 ? void 0 : _a.GetEntity(id);
|
|
14700
|
+
if (maintained) {
|
|
14701
|
+
entities.push(maintained);
|
|
14702
|
+
}
|
|
14703
|
+
else if (simulated) {
|
|
14704
|
+
entities.push(this.atPoint([simulated])[0]);
|
|
14083
14705
|
}
|
|
14084
14706
|
}
|
|
14085
14707
|
return entities;
|
|
@@ -14136,7 +14758,7 @@ class EntityReRenderMaintainState {
|
|
|
14136
14758
|
}
|
|
14137
14759
|
filterCurrentApiEntities(params) {
|
|
14138
14760
|
const { entities, revisions, runId } = params;
|
|
14139
|
-
|
|
14761
|
+
const current = entities.filter((entity) => {
|
|
14140
14762
|
var _a, _b, _c;
|
|
14141
14763
|
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
14142
14764
|
if (!id) {
|
|
@@ -14145,8 +14767,12 @@ class EntityReRenderMaintainState {
|
|
|
14145
14767
|
if (runId != null && this.shouldSkipInRun(id, runId)) {
|
|
14146
14768
|
return false;
|
|
14147
14769
|
}
|
|
14770
|
+
if (this.isSimulated(id)) {
|
|
14771
|
+
return false;
|
|
14772
|
+
}
|
|
14148
14773
|
return ((_b = this.apiRevisionByEntityId[id]) !== null && _b !== void 0 ? _b : 0) === ((_c = revisions[id]) !== null && _c !== void 0 ? _c : 0);
|
|
14149
14774
|
});
|
|
14775
|
+
return this.atPoint(this.simulation && !this.simulation.IsEmpty ? current.map((entity) => this.simulation.Overlay(entity)) : current);
|
|
14150
14776
|
}
|
|
14151
14777
|
}
|
|
14152
14778
|
|
|
@@ -15582,7 +16208,7 @@ class HistoricGatherer {
|
|
|
15582
16208
|
this.cache = new HistoricRangeCache();
|
|
15583
16209
|
}
|
|
15584
16210
|
get Records() {
|
|
15585
|
-
return this.cache.GetRecords();
|
|
16211
|
+
return this.withSimulated(this.cache.GetRecords());
|
|
15586
16212
|
}
|
|
15587
16213
|
Clear() {
|
|
15588
16214
|
this.cache.Clear();
|
|
@@ -15606,8 +16232,9 @@ class HistoricGatherer {
|
|
|
15606
16232
|
*/
|
|
15607
16233
|
async Gather(entities) {
|
|
15608
16234
|
var _a;
|
|
15609
|
-
|
|
15610
|
-
|
|
16235
|
+
const entityIds = entities === null || entities === void 0 ? void 0 : entities.map(x => { var _a; return (_a = x.Bruce) === null || _a === void 0 ? void 0 : _a.ID; }).filter(x => !!x);
|
|
16236
|
+
if (this.disposed || !(entities === null || entities === void 0 ? void 0 : entities.length) || this.params.simulatedOnly) {
|
|
16237
|
+
return { fetched: false, recordsByIds: this.withSimulated(this.cache.GetRecords(), entityIds) };
|
|
15611
16238
|
}
|
|
15612
16239
|
const { viewer } = this.params;
|
|
15613
16240
|
const windowStart = new Date(viewer.clock.startTime.toString()).getTime();
|
|
@@ -15627,7 +16254,7 @@ class HistoricGatherer {
|
|
|
15627
16254
|
if (plan.coarse && !this.cache.CoversCoarse(plan.coarse.start, plan.coarse.stop)) {
|
|
15628
16255
|
const records = await this.request(plan.coarse.start, plan.coarse.stop, entities, plan.coarse.sample);
|
|
15629
16256
|
if (this.disposed) {
|
|
15630
|
-
return { fetched, recordsByIds: this.cache.GetRecords() };
|
|
16257
|
+
return { fetched, recordsByIds: this.withSimulated(this.cache.GetRecords(), entityIds) };
|
|
15631
16258
|
}
|
|
15632
16259
|
this.cache.Absorb(plan.coarse.start, this.holdTo(plan.coarse.stop, liveEdge, liveTail), records, true);
|
|
15633
16260
|
fetched = true;
|
|
@@ -15662,7 +16289,17 @@ class HistoricGatherer {
|
|
|
15662
16289
|
}
|
|
15663
16290
|
}
|
|
15664
16291
|
}
|
|
15665
|
-
return { fetched, recordsByIds: this.cache.GetRecords() };
|
|
16292
|
+
return { fetched, recordsByIds: this.withSimulated(this.cache.GetRecords(), entityIds) };
|
|
16293
|
+
}
|
|
16294
|
+
/*
|
|
16295
|
+
* Joins the simulated records for these Entities, or every simulated Entity, into an answer.
|
|
16296
|
+
*/
|
|
16297
|
+
withSimulated(recordsByIds, entityIds) {
|
|
16298
|
+
const simulation = this.params.simulation;
|
|
16299
|
+
if (!simulation || simulation.IsEmpty) {
|
|
16300
|
+
return recordsByIds;
|
|
16301
|
+
}
|
|
16302
|
+
return simulation.MergeRecords(recordsByIds, this.params.getAttrKey(), entityIds);
|
|
15666
16303
|
}
|
|
15667
16304
|
/*
|
|
15668
16305
|
* Returns how much of a range that was just read may be marked as held.
|
|
@@ -15697,7 +16334,7 @@ class HistoricGatherer {
|
|
|
15697
16334
|
}).then((res) => {
|
|
15698
16335
|
const records = res.recordsByIds || {};
|
|
15699
16336
|
if (!this.disposed && this.params.onRecords) {
|
|
15700
|
-
this.params.onRecords(records);
|
|
16337
|
+
this.params.onRecords(this.withSimulated(records, entityIds));
|
|
15701
16338
|
}
|
|
15702
16339
|
return records;
|
|
15703
16340
|
}).finally(() => {
|
|
@@ -15774,7 +16411,6 @@ var EntitiesRenderManager;
|
|
|
15774
16411
|
this.renderQueue = [];
|
|
15775
16412
|
this.renderQueueInterval = null;
|
|
15776
16413
|
this.sources = [];
|
|
15777
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
15778
16414
|
// Highly experimental flag to try improve rendering large sets of polygons and polylines.
|
|
15779
16415
|
// Many things are not supported when this is enabled.
|
|
15780
16416
|
this.useGeojson = false;
|
|
@@ -15782,6 +16418,10 @@ var EntitiesRenderManager;
|
|
|
15782
16418
|
this.zoomControl = [];
|
|
15783
16419
|
// Scenario for retrieving Entities.
|
|
15784
16420
|
this.scenario = null;
|
|
16421
|
+
// Hand-off key of the data currently drawn, or null when it is unknown or nothing is drawn.
|
|
16422
|
+
this.drawnKey = null;
|
|
16423
|
+
// How the drawn entities were last told to look, see getDrawnSettingsSignature.
|
|
16424
|
+
this.drawnSettings = null;
|
|
15785
16425
|
// Type IDs that we'll allow to be rendered when receiving Entities.
|
|
15786
16426
|
// This might be exactly the Menu Item Type ID because of local data sources.
|
|
15787
16427
|
this.allowedTypeIDs = [];
|
|
@@ -15794,6 +16434,14 @@ var EntitiesRenderManager;
|
|
|
15794
16434
|
*/
|
|
15795
16435
|
this.renderAsIndividualsChain = Promise.resolve();
|
|
15796
16436
|
const { viewer, apiGetter, monitor, item, register: visualsManager, sharedGetters, onSeriesDiscovered } = params;
|
|
16437
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation, () => {
|
|
16438
|
+
// Read at the scene's time only when the item follows history, the same choice its reads make.
|
|
16439
|
+
const bruceEntity = this.item.BruceEntity;
|
|
16440
|
+
if (!(bruceEntity === null || bruceEntity === void 0 ? void 0 : bruceEntity.historic) && !(bruceEntity === null || bruceEntity === void 0 ? void 0 : bruceEntity.historicAttrKey)) {
|
|
16441
|
+
return null;
|
|
16442
|
+
}
|
|
16443
|
+
return { timeMs: JulianDate.toDate(this.viewer.clock.currentTime).getTime(), attrKey: bruceEntity.historicAttrKey };
|
|
16444
|
+
});
|
|
15797
16445
|
this.viewer = viewer;
|
|
15798
16446
|
this.sharedGetters = sharedGetters;
|
|
15799
16447
|
this.monitor = monitor;
|
|
@@ -15807,7 +16455,8 @@ var EntitiesRenderManager;
|
|
|
15807
16455
|
getApi: () => this.apiGetter.getApi(),
|
|
15808
16456
|
getAttrKey: () => { var _a; return (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey; },
|
|
15809
16457
|
// A second either side, to take in records sitting exactly on the boundary.
|
|
15810
|
-
paddingMs: 1000
|
|
16458
|
+
paddingMs: 1000,
|
|
16459
|
+
simulation: params.simulation
|
|
15811
16460
|
});
|
|
15812
16461
|
this.useGeojson = item.renderAsGeojson == true;
|
|
15813
16462
|
if (item.enableClustering) {
|
|
@@ -15831,9 +16480,26 @@ var EntitiesRenderManager;
|
|
|
15831
16480
|
if (this.disposed) {
|
|
15832
16481
|
return;
|
|
15833
16482
|
}
|
|
16483
|
+
// Landing on the data already drawn re-applies settings instead of removing and re-fetching it.
|
|
16484
|
+
const nextKey = shouldRender ? Manager.GetHandoffKey(this.item) : null;
|
|
16485
|
+
const keepDrawn = nextKey != null && nextKey === this.drawnKey;
|
|
16486
|
+
const restyle = keepDrawn && this.drawnSettings !== this.getDrawnSettingsSignature();
|
|
16487
|
+
this.drawnKey = nextKey;
|
|
16488
|
+
this.drawnSettings = this.getDrawnSettingsSignature();
|
|
15834
16489
|
this.unsetGetter();
|
|
15835
16490
|
(_a = this.viewMonitorRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
15836
16491
|
this.viewMonitorRemoval = null;
|
|
16492
|
+
if (keepDrawn) {
|
|
16493
|
+
this.setGetter();
|
|
16494
|
+
this.viewMonitorRemoval = this.monitor.Updated().Subscribe(() => {
|
|
16495
|
+
var _a;
|
|
16496
|
+
(_a = this.entityCheckQueue) === null || _a === void 0 ? void 0 : _a.Call();
|
|
16497
|
+
});
|
|
16498
|
+
if (restyle) {
|
|
16499
|
+
this.ReRender({ entityIds: Object.keys(this.renderedEntities), force: true });
|
|
16500
|
+
}
|
|
16501
|
+
return;
|
|
16502
|
+
}
|
|
15837
16503
|
clearInterval(this.renderQueueInterval);
|
|
15838
16504
|
this.renderQueueInterval = null;
|
|
15839
16505
|
this.renderQueue = [];
|
|
@@ -15867,6 +16533,18 @@ var EntitiesRenderManager;
|
|
|
15867
16533
|
}
|
|
15868
16534
|
})();
|
|
15869
16535
|
}
|
|
16536
|
+
/*
|
|
16537
|
+
* Everything about how drawn entities look that applying the item's settings can change.
|
|
16538
|
+
*/
|
|
16539
|
+
getDrawnSettingsSignature() {
|
|
16540
|
+
var _a;
|
|
16541
|
+
return JSON.stringify({
|
|
16542
|
+
zoomControl: RenderManager.GetZoomControlSignature(this.zoomControl),
|
|
16543
|
+
renderPriority: (_a = this.renderPriority) !== null && _a !== void 0 ? _a : null,
|
|
16544
|
+
historicDrawTrack: Boolean(this.item.historicDrawTrack),
|
|
16545
|
+
historicInterpolation: Boolean(this.item.historicInterpolation)
|
|
16546
|
+
});
|
|
16547
|
+
}
|
|
15870
16548
|
applyItemSettings() {
|
|
15871
16549
|
var _a, _b, _c, _d, _e, _f;
|
|
15872
16550
|
// Reset allowed list if there's change.
|
|
@@ -15988,8 +16666,9 @@ var EntitiesRenderManager;
|
|
|
15988
16666
|
return;
|
|
15989
16667
|
}
|
|
15990
16668
|
this.updateAllowedTypeIDs(data.entityTypeSources, data.entities);
|
|
16669
|
+
// The getter answers from the API, so a simulated Entity in its answer is swapped for its blob.
|
|
15991
16670
|
if (isTagItem) {
|
|
15992
|
-
this.distributeForRender(data.entities.filter((entity) => {
|
|
16671
|
+
this.distributeForRender(this.reRenderState.withSimulated(data.entities.filter((entity) => {
|
|
15993
16672
|
let entityTags = entity.Bruce["Layer.ID"];
|
|
15994
16673
|
if (!entityTags) {
|
|
15995
16674
|
entityTags = [];
|
|
@@ -15997,10 +16676,10 @@ var EntitiesRenderManager;
|
|
|
15997
16676
|
return entityTags.some((tag) => {
|
|
15998
16677
|
return tagsToRender.indexOf(tag) !== -1;
|
|
15999
16678
|
});
|
|
16000
|
-
}));
|
|
16679
|
+
})));
|
|
16001
16680
|
}
|
|
16002
16681
|
else {
|
|
16003
|
-
this.distributeForRender(data.entities);
|
|
16682
|
+
this.distributeForRender(this.reRenderState.withSimulated(data.entities));
|
|
16004
16683
|
}
|
|
16005
16684
|
});
|
|
16006
16685
|
// Cesium itself handles single-visibility ranges very well.
|
|
@@ -16040,6 +16719,10 @@ var EntitiesRenderManager;
|
|
|
16040
16719
|
// Remove regos directly.
|
|
16041
16720
|
if (event.action === "D") {
|
|
16042
16721
|
for (const entityId of affectedIds) {
|
|
16722
|
+
// Deleted in the API, but drawn from its simulation until that is cleared.
|
|
16723
|
+
if (this.reRenderState.isSimulated(entityId)) {
|
|
16724
|
+
continue;
|
|
16725
|
+
}
|
|
16043
16726
|
this.visualsManager.RemoveRegos({
|
|
16044
16727
|
entityId,
|
|
16045
16728
|
menuItemId: this.item.id,
|
|
@@ -16237,10 +16920,13 @@ var EntitiesRenderManager;
|
|
|
16237
16920
|
console.warn("Geojson rendering does not support multiple zoom controls. Only the first one will be used.");
|
|
16238
16921
|
this.zoomControl = [this.zoomControl[0]];
|
|
16239
16922
|
}
|
|
16923
|
+
this.drawnSettings = this.getDrawnSettingsSignature();
|
|
16240
16924
|
changed = true;
|
|
16241
16925
|
}
|
|
16242
16926
|
if (scenario != null) {
|
|
16243
16927
|
this.scenario = scenario;
|
|
16928
|
+
// The drawn records now belong to a scenario the item does not name.
|
|
16929
|
+
this.drawnKey = null;
|
|
16244
16930
|
changed = true;
|
|
16245
16931
|
}
|
|
16246
16932
|
if (changed) {
|
|
@@ -16255,6 +16941,16 @@ var EntitiesRenderManager;
|
|
|
16255
16941
|
this.doEntityCheck(entityIds);
|
|
16256
16942
|
}
|
|
16257
16943
|
}
|
|
16944
|
+
/**
|
|
16945
|
+
* Switches to another of the item's own styles, restyling what is drawn without re-creating it.
|
|
16946
|
+
*/
|
|
16947
|
+
SwapStyle(item) {
|
|
16948
|
+
if (this.disposed) {
|
|
16949
|
+
return;
|
|
16950
|
+
}
|
|
16951
|
+
this.item = item;
|
|
16952
|
+
this.UpdateSettings({ zoomControl: item.CameraZoomSettings });
|
|
16953
|
+
}
|
|
16258
16954
|
/**
|
|
16259
16955
|
* Narrows a camera-driven check to the entities whose zoom band could actually have changed.
|
|
16260
16956
|
* @param ids
|
|
@@ -17008,6 +17704,8 @@ var EntitiesRenderManager;
|
|
|
17008
17704
|
AdoptHandoff(payload) {
|
|
17009
17705
|
var _a;
|
|
17010
17706
|
const { shouldRender } = this.applyItemSettings();
|
|
17707
|
+
this.drawnKey = shouldRender ? Manager.GetHandoffKey(this.item) : null;
|
|
17708
|
+
this.drawnSettings = this.getDrawnSettingsSignature();
|
|
17011
17709
|
this.visualsManager.ReassignMenuItem({
|
|
17012
17710
|
fromMenuItemId: payload.sourceMenuItemId,
|
|
17013
17711
|
toMenuItemId: this.item.id,
|
|
@@ -17169,7 +17867,6 @@ var EntitiesLoadedRenderManager;
|
|
|
17169
17867
|
// Highly experimental flag to try improve rendering large sets of polygons and polylines.
|
|
17170
17868
|
// Many things are not supported when this is enabled.
|
|
17171
17869
|
this.useGeojson = false;
|
|
17172
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
17173
17870
|
/**
|
|
17174
17871
|
* Our default path.
|
|
17175
17872
|
* We render each entity individually.
|
|
@@ -17179,6 +17876,7 @@ var EntitiesLoadedRenderManager;
|
|
|
17179
17876
|
*/
|
|
17180
17877
|
this.renderAsIndividualsChain = Promise.resolve();
|
|
17181
17878
|
const { viewer, apiGetter, monitor, item, register: visualsManager } = params;
|
|
17879
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation);
|
|
17182
17880
|
this.viewer = viewer;
|
|
17183
17881
|
this.apiGetter = apiGetter;
|
|
17184
17882
|
this.monitor = monitor;
|
|
@@ -17301,7 +17999,8 @@ var EntitiesLoadedRenderManager;
|
|
|
17301
17999
|
continue;
|
|
17302
18000
|
}
|
|
17303
18001
|
}
|
|
17304
|
-
|
|
18002
|
+
// The item carries its own Entities, so a simulated one among them is swapped for its blob.
|
|
18003
|
+
this.onGetterUpdate(this.reRenderState.withSimulated(entities));
|
|
17305
18004
|
});
|
|
17306
18005
|
this.getter.Start();
|
|
17307
18006
|
}
|
|
@@ -17388,6 +18087,16 @@ var EntitiesLoadedRenderManager;
|
|
|
17388
18087
|
this.doEntityCheck(entityIds);
|
|
17389
18088
|
}
|
|
17390
18089
|
}
|
|
18090
|
+
/**
|
|
18091
|
+
* Switches to another of the item's own styles, restyling what is drawn without re-creating it.
|
|
18092
|
+
*/
|
|
18093
|
+
SwapStyle(item) {
|
|
18094
|
+
if (this.disposed) {
|
|
18095
|
+
return;
|
|
18096
|
+
}
|
|
18097
|
+
this.item = item;
|
|
18098
|
+
this.UpdateSettings({ zoomControl: item.CameraZoomSettings });
|
|
18099
|
+
}
|
|
17391
18100
|
async doEntityCheck(ids, force = false) {
|
|
17392
18101
|
var _a, _b;
|
|
17393
18102
|
const api = this.apiGetter.getApi();
|
|
@@ -17948,8 +18657,15 @@ var EntitiesIdsRenderManager;
|
|
|
17948
18657
|
this.renderQueueActive = false;
|
|
17949
18658
|
this.renderQueue = [];
|
|
17950
18659
|
this.renderQueueForceFlags = [];
|
|
17951
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
17952
18660
|
const { viewer, apiGetter, monitor, item, register: visualsManager } = params;
|
|
18661
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation, () => {
|
|
18662
|
+
// Read at the scene's time only when the item follows history, the same choice its reads make.
|
|
18663
|
+
const bruceEntity = this.item.BruceEntity;
|
|
18664
|
+
if (!(bruceEntity === null || bruceEntity === void 0 ? void 0 : bruceEntity.historic) && !(bruceEntity === null || bruceEntity === void 0 ? void 0 : bruceEntity.historicAttrKey)) {
|
|
18665
|
+
return null;
|
|
18666
|
+
}
|
|
18667
|
+
return { timeMs: JulianDate.toDate(this.viewer.clock.currentTime).getTime(), attrKey: bruceEntity.historicAttrKey };
|
|
18668
|
+
});
|
|
17953
18669
|
this.sharedHistoric = params.sharedHistoric;
|
|
17954
18670
|
this.viewer = viewer;
|
|
17955
18671
|
this.apiGetter = apiGetter;
|
|
@@ -17962,7 +18678,8 @@ var EntitiesIdsRenderManager;
|
|
|
17962
18678
|
getApi: () => this.apiGetter.getApi(),
|
|
17963
18679
|
getAttrKey: () => { var _a; return (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey; },
|
|
17964
18680
|
// Padding either side of a requested range, for clock desync between us and the server.
|
|
17965
|
-
paddingMs: 15000
|
|
18681
|
+
paddingMs: 15000,
|
|
18682
|
+
simulation: params.simulation
|
|
17966
18683
|
});
|
|
17967
18684
|
if (this.item.enableClustering) {
|
|
17968
18685
|
this.clustering = new PointClustering(visualsManager, this.item.id, (_a = this.item) === null || _a === void 0 ? void 0 : _a.clustering);
|
|
@@ -18085,6 +18802,16 @@ var EntitiesIdsRenderManager;
|
|
|
18085
18802
|
this.onGetterUpdate(entityIds);
|
|
18086
18803
|
}
|
|
18087
18804
|
}
|
|
18805
|
+
/**
|
|
18806
|
+
* Switches to another of the item's own styles, restyling what is drawn without re-creating it.
|
|
18807
|
+
*/
|
|
18808
|
+
SwapStyle(item) {
|
|
18809
|
+
if (this.disposed) {
|
|
18810
|
+
return;
|
|
18811
|
+
}
|
|
18812
|
+
this.item = item;
|
|
18813
|
+
this.UpdateSettings({ zoomControl: item.CameraZoomSettings });
|
|
18814
|
+
}
|
|
18088
18815
|
/*
|
|
18089
18816
|
* The lane this item reads through, or null when it does not follow the clock.
|
|
18090
18817
|
*/
|
|
@@ -18424,9 +19151,9 @@ var EntityRenderManager;
|
|
|
18424
19151
|
this.getter = null;
|
|
18425
19152
|
this.getterSub = null;
|
|
18426
19153
|
this.disposed = false;
|
|
18427
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
18428
19154
|
this.renderEntityChain = Promise.resolve();
|
|
18429
19155
|
const { viewer, apiGetter, monitor, item, register: visualsManager } = params;
|
|
19156
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation);
|
|
18430
19157
|
this.viewer = viewer;
|
|
18431
19158
|
this.apiGetter = apiGetter;
|
|
18432
19159
|
this.monitor = monitor;
|
|
@@ -18548,6 +19275,16 @@ var EntityRenderManager;
|
|
|
18548
19275
|
this.onGetterUpdate(entityId, true);
|
|
18549
19276
|
}
|
|
18550
19277
|
}
|
|
19278
|
+
/**
|
|
19279
|
+
* Switches to another of the item's own styles, restyling what is drawn without re-creating it.
|
|
19280
|
+
*/
|
|
19281
|
+
SwapStyle(item) {
|
|
19282
|
+
if (this.disposed) {
|
|
19283
|
+
return;
|
|
19284
|
+
}
|
|
19285
|
+
this.item = item;
|
|
19286
|
+
this.UpdateSettings({ zoomControl: item.CameraZoomSettings });
|
|
19287
|
+
}
|
|
18551
19288
|
renderEntity(entity, force = false) {
|
|
18552
19289
|
// Waiting for prior call to finish resolving.
|
|
18553
19290
|
// This avoids race conditions against two sets of overlapping Entities.
|
|
@@ -18700,6 +19437,122 @@ var CodeLogicExceptions;
|
|
|
18700
19437
|
];
|
|
18701
19438
|
})(CodeLogicExceptions || (CodeLogicExceptions = {}));
|
|
18702
19439
|
|
|
19440
|
+
/**
|
|
19441
|
+
* The line drawn through where a moving thing has been, from its history, as a whole path or a fading trail.
|
|
19442
|
+
*/
|
|
19443
|
+
var HistoricTrail;
|
|
19444
|
+
(function (HistoricTrail) {
|
|
19445
|
+
const BANDS = 12;
|
|
19446
|
+
const SAMPLES = 96;
|
|
19447
|
+
const WIDTH_FAR = 1;
|
|
19448
|
+
const ALPHA_FAR = 0.05;
|
|
19449
|
+
// Above 1, so width and alpha hold near the head and give way further back.
|
|
19450
|
+
const WIDTH_CURVE = 1.4;
|
|
19451
|
+
const ALPHA_CURVE = 1.25;
|
|
19452
|
+
// How strongly a line is drawn where it passes behind the globe, against its own alpha.
|
|
19453
|
+
const BEHIND_ALPHA = 0.35;
|
|
19454
|
+
/**
|
|
19455
|
+
* The trail length a menu item asks for in its historicTrackSeconds, or null for the whole path.
|
|
19456
|
+
*/
|
|
19457
|
+
function GetTrailSeconds(item) {
|
|
19458
|
+
const seconds = Number(item === null || item === void 0 ? void 0 : item.historicTrackSeconds);
|
|
19459
|
+
return seconds > 0 ? seconds : null;
|
|
19460
|
+
}
|
|
19461
|
+
HistoricTrail.GetTrailSeconds = GetTrailSeconds;
|
|
19462
|
+
class Trail {
|
|
19463
|
+
constructor(params) {
|
|
19464
|
+
this.entities = [];
|
|
19465
|
+
this.memoTime = null;
|
|
19466
|
+
this.memo = [];
|
|
19467
|
+
this.viewer = params.viewer;
|
|
19468
|
+
const trailing = params.trailSeconds > 0 && Boolean(params.positionAt);
|
|
19469
|
+
if (!trailing) {
|
|
19470
|
+
this.add(params, params.color, params.width, () => { var _a; return (_a = params.getSeries()) !== null && _a !== void 0 ? _a : []; });
|
|
19471
|
+
return;
|
|
19472
|
+
}
|
|
19473
|
+
for (let band = 0; band < BANDS; band++) {
|
|
19474
|
+
// 0 at the head, 1 at the far end.
|
|
19475
|
+
const age = band / (BANDS - 1);
|
|
19476
|
+
const width = params.width - (params.width - WIDTH_FAR) * Math.pow(age, WIDTH_CURVE);
|
|
19477
|
+
const alpha = params.color.alpha - (params.color.alpha - ALPHA_FAR) * Math.pow(age, ALPHA_CURVE);
|
|
19478
|
+
this.add(params, params.color.withAlpha(alpha), Math.max(WIDTH_FAR, width), (time) => {
|
|
19479
|
+
return this.slice(this.sample(params, time), band);
|
|
19480
|
+
});
|
|
19481
|
+
}
|
|
19482
|
+
}
|
|
19483
|
+
/*
|
|
19484
|
+
* One polyline of the trail, its positions read from the scene's time.
|
|
19485
|
+
*/
|
|
19486
|
+
add(params, color, width, positions) {
|
|
19487
|
+
const entity = this.viewer.entities.add({
|
|
19488
|
+
id: ObjectUtils.UId(15),
|
|
19489
|
+
polyline: {
|
|
19490
|
+
positions: new CallbackProperty((time) => positions(time), false),
|
|
19491
|
+
width: width,
|
|
19492
|
+
material: color,
|
|
19493
|
+
clampToGround: params.clampToGround,
|
|
19494
|
+
// A path through the air follows no ellipsoid, so it is drawn as the straight runs it holds.
|
|
19495
|
+
arcType: params.clampToGround ? ArcType.GEODESIC : ArcType.NONE,
|
|
19496
|
+
// Drawn dimmer behind the globe rather than winking in and out against the terrain along the limb.
|
|
19497
|
+
depthFailMaterial: params.clampToGround ? undefined : color.withAlpha(color.alpha * BEHIND_ALPHA),
|
|
19498
|
+
zIndex: 0,
|
|
19499
|
+
classificationType: params.clampToGround ? ClassificationType.BOTH : undefined
|
|
19500
|
+
}
|
|
19501
|
+
});
|
|
19502
|
+
entity._noEdit = true;
|
|
19503
|
+
entity._noSelect = true;
|
|
19504
|
+
CesiumEntityStyler.SetDefaultColor({
|
|
19505
|
+
color: color,
|
|
19506
|
+
entity: entity,
|
|
19507
|
+
viewer: this.viewer,
|
|
19508
|
+
override: true,
|
|
19509
|
+
requestRender: false
|
|
19510
|
+
});
|
|
19511
|
+
this.entities.push(entity);
|
|
19512
|
+
}
|
|
19513
|
+
/*
|
|
19514
|
+
* The trail's positions at a time, newest last, kept for that time so every band reads the same set.
|
|
19515
|
+
*/
|
|
19516
|
+
sample(params, time) {
|
|
19517
|
+
var _a;
|
|
19518
|
+
if (this.memoTime && JulianDate.equals(this.memoTime, time)) {
|
|
19519
|
+
return this.memo;
|
|
19520
|
+
}
|
|
19521
|
+
this.memoTime = JulianDate.clone(time, (_a = this.memoTime) !== null && _a !== void 0 ? _a : new JulianDate());
|
|
19522
|
+
const nowMs = JulianDate.toDate(time).getTime();
|
|
19523
|
+
const spanMs = params.trailSeconds * 1000;
|
|
19524
|
+
const points = [];
|
|
19525
|
+
for (let i = 0; i <= SAMPLES; i++) {
|
|
19526
|
+
const pos3d = params.positionAt(nowMs - spanMs + spanMs * i / SAMPLES);
|
|
19527
|
+
if (pos3d) {
|
|
19528
|
+
points.push(pos3d);
|
|
19529
|
+
}
|
|
19530
|
+
}
|
|
19531
|
+
this.memo = points;
|
|
19532
|
+
return points;
|
|
19533
|
+
}
|
|
19534
|
+
/*
|
|
19535
|
+
* A band's run of the samples, counted back from the head, sharing its end point with the next band.
|
|
19536
|
+
*/
|
|
19537
|
+
slice(points, band) {
|
|
19538
|
+
if (points.length < 2) {
|
|
19539
|
+
return [];
|
|
19540
|
+
}
|
|
19541
|
+
const per = (points.length - 1) / BANDS;
|
|
19542
|
+
const end = points.length - 1 - Math.round(band * per);
|
|
19543
|
+
const start = points.length - 1 - Math.round((band + 1) * per);
|
|
19544
|
+
return start < end ? points.slice(Math.max(0, start), end + 1) : [];
|
|
19545
|
+
}
|
|
19546
|
+
Dispose() {
|
|
19547
|
+
for (const entity of this.entities) {
|
|
19548
|
+
RemoveCEntityFromScene(this.viewer, entity);
|
|
19549
|
+
}
|
|
19550
|
+
this.entities = [];
|
|
19551
|
+
}
|
|
19552
|
+
}
|
|
19553
|
+
HistoricTrail.Trail = Trail;
|
|
19554
|
+
})(HistoricTrail || (HistoricTrail = {}));
|
|
19555
|
+
|
|
18703
19556
|
class EntityGatherer {
|
|
18704
19557
|
get OnQueueProgress() {
|
|
18705
19558
|
if (!this._onQueueProgress) {
|
|
@@ -18707,7 +19560,11 @@ class EntityGatherer {
|
|
|
18707
19560
|
}
|
|
18708
19561
|
return this._onQueueProgress;
|
|
18709
19562
|
}
|
|
18710
|
-
|
|
19563
|
+
/**
|
|
19564
|
+
* @param simulation what callers simulate in place of API data, used where this gatherer has no override.
|
|
19565
|
+
*/
|
|
19566
|
+
constructor(api, viewer, emitEntities, simulation) {
|
|
19567
|
+
this.simulation = simulation;
|
|
18711
19568
|
this.disposed = false;
|
|
18712
19569
|
this.expandSources = false;
|
|
18713
19570
|
this.historic = null;
|
|
@@ -19284,15 +20141,19 @@ class EntityGatherer {
|
|
|
19284
20141
|
}
|
|
19285
20142
|
}
|
|
19286
20143
|
}
|
|
20144
|
+
// A historic read is as at the scene's time, and so is any simulated record laid over it.
|
|
20145
|
+
const rTimeMs = new Date(rTime).getTime();
|
|
20146
|
+
const atPoint = (entity) => this.historic && this.simulation ? this.simulation.ApplyAt(entity, rTimeMs) : entity;
|
|
19287
20147
|
for (const entityId of requestedBatch || []) {
|
|
20148
|
+
// A caller's own override is an unsaved edit, newer than any simulation, so it is used as is.
|
|
19288
20149
|
const override = this.entityDataOverrides.get(entityId);
|
|
19289
20150
|
if (override) {
|
|
19290
20151
|
resolvedEntities.push(override);
|
|
19291
20152
|
continue;
|
|
19292
20153
|
}
|
|
19293
|
-
const found = foundById.get(entityId);
|
|
20154
|
+
const found = this.simulation ? this.simulation.Resolve(entityId, foundById.get(entityId)) : foundById.get(entityId);
|
|
19294
20155
|
if (found) {
|
|
19295
|
-
resolvedEntities.push(found);
|
|
20156
|
+
resolvedEntities.push(atPoint(found));
|
|
19296
20157
|
continue;
|
|
19297
20158
|
}
|
|
19298
20159
|
resolvedEntities.push(this.createFallbackEntity(entityId));
|
|
@@ -19656,7 +20517,7 @@ class TilesetStyler {
|
|
|
19656
20517
|
this.styleTilesetFeatureFullData(feature, entity, eTags);
|
|
19657
20518
|
}
|
|
19658
20519
|
}
|
|
19659
|
-
});
|
|
20520
|
+
}, params.simulation);
|
|
19660
20521
|
// Only Entities Sets bake coordinates into their features, so for any other source this
|
|
19661
20522
|
// resolves nothing and the gather stays in insertion order.
|
|
19662
20523
|
this.entityGatherer.SetViewMonitor(this.monitor);
|
|
@@ -21186,6 +22047,9 @@ var TilesetCadRenderManager;
|
|
|
21186
22047
|
return this.modelTreeUpdate;
|
|
21187
22048
|
}
|
|
21188
22049
|
constructor(params) {
|
|
22050
|
+
this.simulationRemoval = null;
|
|
22051
|
+
// Where the tileset stands by its own record, so a cleared simulation puts it back without a refetch.
|
|
22052
|
+
this.restCoords = null;
|
|
21189
22053
|
this.disposed = false;
|
|
21190
22054
|
this.modelSpace = false;
|
|
21191
22055
|
this.cTileset = null;
|
|
@@ -21223,7 +22087,7 @@ var TilesetCadRenderManager;
|
|
|
21223
22087
|
this.historicAnimation = null;
|
|
21224
22088
|
this.historicGatherer = null;
|
|
21225
22089
|
// The trail through the root's own movement, which describes the whole assembly.
|
|
21226
|
-
this.
|
|
22090
|
+
this.trail = null;
|
|
21227
22091
|
this.historicPossesLoadingProm = null;
|
|
21228
22092
|
// Queue of loaded in features that we haven't processed yet.
|
|
21229
22093
|
this.featureQueue = [];
|
|
@@ -21237,6 +22101,7 @@ var TilesetCadRenderManager;
|
|
|
21237
22101
|
this.featurePropCache = new Map();
|
|
21238
22102
|
this.featurePropsChecked = 0;
|
|
21239
22103
|
const { viewer, register: visualsManager, getters, item, modelSpace, initQueue } = params;
|
|
22104
|
+
this.simulation = params.simulation;
|
|
21240
22105
|
this.viewer = viewer;
|
|
21241
22106
|
this.getters = getters;
|
|
21242
22107
|
this.item = item;
|
|
@@ -21401,7 +22266,7 @@ var TilesetCadRenderManager;
|
|
|
21401
22266
|
historicPoint: this.viewer.clock.currentTime.toString(),
|
|
21402
22267
|
api: api
|
|
21403
22268
|
});
|
|
21404
|
-
coords = coordsFromHistoricEntity(root);
|
|
22269
|
+
coords = coordsFromHistoricEntity(this.atClock(root));
|
|
21405
22270
|
}
|
|
21406
22271
|
catch (e) {
|
|
21407
22272
|
console.error(e);
|
|
@@ -21442,6 +22307,10 @@ var TilesetCadRenderManager;
|
|
|
21442
22307
|
this.doDispose();
|
|
21443
22308
|
return;
|
|
21444
22309
|
}
|
|
22310
|
+
this.restCoords = coords;
|
|
22311
|
+
if (this.simulatedRootCoords()) {
|
|
22312
|
+
this.applyCoords(tileset, this.simulatedRootCoords());
|
|
22313
|
+
}
|
|
21445
22314
|
this.viewer.scene.requestRender();
|
|
21446
22315
|
TilesetRenderEngine.OnTilesetReady(this.cTileset).then(() => {
|
|
21447
22316
|
var _a, _b, _c;
|
|
@@ -21461,6 +22330,7 @@ var TilesetCadRenderManager;
|
|
|
21461
22330
|
}
|
|
21462
22331
|
this.onCTilesetLoad();
|
|
21463
22332
|
this.styler.Init({
|
|
22333
|
+
simulation: this.simulation,
|
|
21464
22334
|
viewer: this.viewer,
|
|
21465
22335
|
// Default API instead of the account one.
|
|
21466
22336
|
// Records are driven by the account loading it instead of the source account.
|
|
@@ -21476,6 +22346,7 @@ var TilesetCadRenderManager;
|
|
|
21476
22346
|
});
|
|
21477
22347
|
this.viewer.scene.requestRender();
|
|
21478
22348
|
// Monitor scene time changes and update the root Entity.
|
|
22349
|
+
this.followSimulation(tileset);
|
|
21479
22350
|
this.viewerDateTimeSub(tileset);
|
|
21480
22351
|
}
|
|
21481
22352
|
catch (e) {
|
|
@@ -21531,7 +22402,7 @@ var TilesetCadRenderManager;
|
|
|
21531
22402
|
*/
|
|
21532
22403
|
applyRootTrack() {
|
|
21533
22404
|
var _a;
|
|
21534
|
-
if (!this.item.historicDrawTrack || !this.historicAnimation || this.
|
|
22405
|
+
if (!this.item.historicDrawTrack || !this.historicAnimation || this.trail) {
|
|
21535
22406
|
return;
|
|
21536
22407
|
}
|
|
21537
22408
|
const trackStyle = EntityRenderEngine.GetTrackStyle({
|
|
@@ -21541,26 +22412,14 @@ var TilesetCadRenderManager;
|
|
|
21541
22412
|
if (!trackStyle) {
|
|
21542
22413
|
return;
|
|
21543
22414
|
}
|
|
21544
|
-
this
|
|
21545
|
-
|
|
21546
|
-
polyline: {
|
|
21547
|
-
positions: new CallbackProperty(() => { var _a, _b; return (_b = (_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.GetSeries()) !== null && _b !== void 0 ? _b : []; }, false),
|
|
21548
|
-
width: trackStyle.width,
|
|
21549
|
-
material: trackStyle.color,
|
|
21550
|
-
clampToGround: EntityRenderEngine.GetHeightRefPolyline(Manager.GetRecordHeightRef(this.item))
|
|
21551
|
-
== HeightReference.CLAMP_TO_GROUND,
|
|
21552
|
-
zIndex: 0,
|
|
21553
|
-
classificationType: ClassificationType.BOTH
|
|
21554
|
-
}
|
|
21555
|
-
});
|
|
21556
|
-
this.trackEntity._noEdit = true;
|
|
21557
|
-
this.trackEntity._noSelect = true;
|
|
21558
|
-
CesiumEntityStyler.SetDefaultColor({
|
|
21559
|
-
color: trackStyle.color,
|
|
21560
|
-
entity: this.trackEntity,
|
|
22415
|
+
// The series has no position at an arbitrary time, so this draws the whole path rather than a trail.
|
|
22416
|
+
this.trail = new HistoricTrail.Trail({
|
|
21561
22417
|
viewer: this.viewer,
|
|
21562
|
-
|
|
21563
|
-
|
|
22418
|
+
color: trackStyle.color,
|
|
22419
|
+
width: trackStyle.width,
|
|
22420
|
+
clampToGround: EntityRenderEngine.GetHeightRefPolyline(Manager.GetRecordHeightRef(this.item))
|
|
22421
|
+
== HeightReference.CLAMP_TO_GROUND,
|
|
22422
|
+
getSeries: () => { var _a, _b; return (_b = (_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.GetSeries()) !== null && _b !== void 0 ? _b : []; }
|
|
21564
22423
|
});
|
|
21565
22424
|
}
|
|
21566
22425
|
/**
|
|
@@ -21613,7 +22472,7 @@ var TilesetCadRenderManager;
|
|
|
21613
22472
|
}
|
|
21614
22473
|
// Returns null (fall back to a normal Dispose()) if the tileset hasn't finished loading yet.
|
|
21615
22474
|
PrepareHandoff() {
|
|
21616
|
-
var _a, _b, _c, _d;
|
|
22475
|
+
var _a, _b, _c, _d, _e;
|
|
21617
22476
|
if (this.disposed || !this.cTileset || this.cTileset.isDestroyed()) {
|
|
21618
22477
|
return null;
|
|
21619
22478
|
}
|
|
@@ -21631,9 +22490,11 @@ var TilesetCadRenderManager;
|
|
|
21631
22490
|
this.handoffSourceMenuItemId = null;
|
|
21632
22491
|
// Not transferred, the receiving manager sets up its own fresh copy if needed.
|
|
21633
22492
|
this.viewerDateTimeDispose();
|
|
21634
|
-
(_b = this.
|
|
21635
|
-
|
|
21636
|
-
(
|
|
22493
|
+
(_b = this.simulationRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
22494
|
+
this.simulationRemoval = null;
|
|
22495
|
+
(_c = this.styler) === null || _c === void 0 ? void 0 : _c.Dispose();
|
|
22496
|
+
(_d = this.tileLoadRemoval) === null || _d === void 0 ? void 0 : _d.call(this);
|
|
22497
|
+
(_e = this.tileUnloadRemoval) === null || _e === void 0 ? void 0 : _e.call(this);
|
|
21637
22498
|
this.tileLoadRemoval = null;
|
|
21638
22499
|
this.tileUnloadRemoval = null;
|
|
21639
22500
|
const payload = {
|
|
@@ -21654,7 +22515,7 @@ var TilesetCadRenderManager;
|
|
|
21654
22515
|
// Takes ownership of a PrepareHandoff() payload instead of loading via Init().
|
|
21655
22516
|
// Then re-parents every already-registered rego to this menu item and re-runs styling.
|
|
21656
22517
|
AdoptHandoff(payload) {
|
|
21657
|
-
var _a, _b, _c, _d;
|
|
22518
|
+
var _a, _b, _c, _d, _e;
|
|
21658
22519
|
this.cTileset = payload.cTileset;
|
|
21659
22520
|
this.tileset = payload.tileset;
|
|
21660
22521
|
this.rootId = payload.rootId;
|
|
@@ -21685,6 +22546,7 @@ var TilesetCadRenderManager;
|
|
|
21685
22546
|
// Same visuals, same registrations so just re-keyed onto this menu item.
|
|
21686
22547
|
this.onCTilesetLoad();
|
|
21687
22548
|
this.styler.Init({
|
|
22549
|
+
simulation: this.simulation,
|
|
21688
22550
|
viewer: this.viewer,
|
|
21689
22551
|
api: this.getters.GetBruceApi(),
|
|
21690
22552
|
cTileset: this.cTileset,
|
|
@@ -21718,7 +22580,9 @@ var TilesetCadRenderManager;
|
|
|
21718
22580
|
}
|
|
21719
22581
|
});
|
|
21720
22582
|
this.viewer.scene.requestRender();
|
|
21721
|
-
if (
|
|
22583
|
+
if (this.tileset) {
|
|
22584
|
+
this.restCoords = (_d = this.restCoords) !== null && _d !== void 0 ? _d : (_e = this.cTileset) === null || _e === void 0 ? void 0 : _e._bruceCoords;
|
|
22585
|
+
this.followSimulation(this.tileset);
|
|
21722
22586
|
this.viewerDateTimeSub(this.tileset);
|
|
21723
22587
|
}
|
|
21724
22588
|
}
|
|
@@ -22296,6 +23160,21 @@ var TilesetCadRenderManager;
|
|
|
22296
23160
|
}
|
|
22297
23161
|
return children;
|
|
22298
23162
|
}
|
|
23163
|
+
/**
|
|
23164
|
+
* Switches to another of the item's own styles, restyling the loaded tileset without reloading it.
|
|
23165
|
+
*/
|
|
23166
|
+
SwapStyle(item) {
|
|
23167
|
+
var _a;
|
|
23168
|
+
if (this.disposed) {
|
|
23169
|
+
return;
|
|
23170
|
+
}
|
|
23171
|
+
this.item = item;
|
|
23172
|
+
// Before the tileset loads this only stores the pick, and the styler's Init reads the new item.
|
|
23173
|
+
this.styler.UpdateStyleMapping({
|
|
23174
|
+
styleMapping: (_a = item.StyleMapping) !== null && _a !== void 0 ? _a : [],
|
|
23175
|
+
fallbackStyleId: item.styleId
|
|
23176
|
+
});
|
|
23177
|
+
}
|
|
22299
23178
|
Dispose() {
|
|
22300
23179
|
var _a;
|
|
22301
23180
|
if (this.disposed) {
|
|
@@ -22306,7 +23185,7 @@ var TilesetCadRenderManager;
|
|
|
22306
23185
|
this.doDispose();
|
|
22307
23186
|
}
|
|
22308
23187
|
doDispose() {
|
|
22309
|
-
var _a, _b, _c;
|
|
23188
|
+
var _a, _b, _c, _d;
|
|
22310
23189
|
if (this.featureQueueInterval) {
|
|
22311
23190
|
clearInterval(this.featureQueueInterval);
|
|
22312
23191
|
this.featureQueueInterval = null;
|
|
@@ -22341,6 +23220,8 @@ var TilesetCadRenderManager;
|
|
|
22341
23220
|
this.handoffSourceMenuItemId = null;
|
|
22342
23221
|
}
|
|
22343
23222
|
this.viewerDateTimeDispose();
|
|
23223
|
+
(_d = this.simulationRemoval) === null || _d === void 0 ? void 0 : _d.call(this);
|
|
23224
|
+
this.simulationRemoval = null;
|
|
22344
23225
|
}
|
|
22345
23226
|
async ReRender(params) {
|
|
22346
23227
|
let { entityIds, force, entities, maintain } = params;
|
|
@@ -22366,8 +23247,11 @@ var TilesetCadRenderManager;
|
|
|
22366
23247
|
* @param tileset
|
|
22367
23248
|
*/
|
|
22368
23249
|
viewerDateTimeSub(tileset) {
|
|
22369
|
-
var _a;
|
|
22370
|
-
|
|
23250
|
+
var _a, _b;
|
|
23251
|
+
// An item that is not historic still follows the root's simulated records, once there are some.
|
|
23252
|
+
const historic = Boolean((_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historic);
|
|
23253
|
+
const simulated = Boolean(this.rootId && ((_b = this.simulation) === null || _b === void 0 ? void 0 : _b.GetRecords(this.rootId).length));
|
|
23254
|
+
if ((!historic && !simulated) || this.historicGatherer || this.viewerDateTimeChangeRemoval) {
|
|
22371
23255
|
return;
|
|
22372
23256
|
}
|
|
22373
23257
|
const accountId = this.accountIdForRecords();
|
|
@@ -22396,6 +23280,8 @@ var TilesetCadRenderManager;
|
|
|
22396
23280
|
// Time padding in milliseconds (15 seconds).
|
|
22397
23281
|
// Helps account for desync between client and server.
|
|
22398
23282
|
paddingMs: 15000,
|
|
23283
|
+
simulation: this.simulation,
|
|
23284
|
+
simulatedOnly: !historic,
|
|
22399
23285
|
onRecords: (recordsByIds) => {
|
|
22400
23286
|
var _a;
|
|
22401
23287
|
const records = recordsByIds[this.rootId];
|
|
@@ -22423,6 +23309,7 @@ var TilesetCadRenderManager;
|
|
|
22423
23309
|
*/
|
|
22424
23310
|
const getInitialPosses = async () => {
|
|
22425
23311
|
this.historicPossesLoadingProm = new Promise(async (res) => {
|
|
23312
|
+
var _a;
|
|
22426
23313
|
try {
|
|
22427
23314
|
if (this.disposed) {
|
|
22428
23315
|
res(false);
|
|
@@ -22435,11 +23322,16 @@ var TilesetCadRenderManager;
|
|
|
22435
23322
|
return;
|
|
22436
23323
|
}
|
|
22437
23324
|
// Also request the current position in case its not in the range.
|
|
22438
|
-
|
|
23325
|
+
// A simulated root, or an item that is not historic, has no current record to ask the API for.
|
|
23326
|
+
if (!historic || ((_a = this.simulation) === null || _a === void 0 ? void 0 : _a.HasEntity(this.rootId))) {
|
|
23327
|
+
res(positions);
|
|
23328
|
+
return;
|
|
23329
|
+
}
|
|
23330
|
+
const entity = this.atClock((await Entity$1.Get({
|
|
22439
23331
|
entityId: this.rootId,
|
|
22440
23332
|
historicPoint: this.viewer.clock.currentTime.toString(),
|
|
22441
23333
|
api: api
|
|
22442
|
-
});
|
|
23334
|
+
})).entity);
|
|
22443
23335
|
if (this.disposed || !entity) {
|
|
22444
23336
|
res(false);
|
|
22445
23337
|
return;
|
|
@@ -22519,14 +23411,15 @@ var TilesetCadRenderManager;
|
|
|
22519
23411
|
}
|
|
22520
23412
|
});
|
|
22521
23413
|
this.viewerDateTimeChangeRemoval = () => {
|
|
23414
|
+
var _a, _b;
|
|
22522
23415
|
if (this.historicAnimation) {
|
|
22523
23416
|
this.historicAnimation.stop();
|
|
22524
23417
|
this.historicAnimation = null;
|
|
22525
23418
|
}
|
|
22526
|
-
|
|
22527
|
-
|
|
22528
|
-
|
|
22529
|
-
|
|
23419
|
+
(_a = this.historicGatherer) === null || _a === void 0 ? void 0 : _a.Dispose();
|
|
23420
|
+
this.historicGatherer = null;
|
|
23421
|
+
(_b = this.trail) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
23422
|
+
this.trail = null;
|
|
22530
23423
|
if (clockTickRemoval) {
|
|
22531
23424
|
clockTickRemoval();
|
|
22532
23425
|
clockTickRemoval = null;
|
|
@@ -22534,10 +23427,84 @@ var TilesetCadRenderManager;
|
|
|
22534
23427
|
};
|
|
22535
23428
|
});
|
|
22536
23429
|
}
|
|
22537
|
-
|
|
23430
|
+
/*
|
|
23431
|
+
* Keeps the tileset in line with what is simulated for its root Entity.
|
|
23432
|
+
*/
|
|
23433
|
+
followSimulation(tileset) {
|
|
23434
|
+
if (this.simulationRemoval || !this.simulation) {
|
|
23435
|
+
return;
|
|
23436
|
+
}
|
|
23437
|
+
this.simulationRemoval = this.simulation.OnChanged.Subscribe((change) => {
|
|
23438
|
+
var _a;
|
|
23439
|
+
if (this.disposed || !this.rootId || !change.entityIds.includes(this.rootId)) {
|
|
23440
|
+
return;
|
|
23441
|
+
}
|
|
23442
|
+
if (change.records) {
|
|
23443
|
+
this.regatherRoot(tileset);
|
|
23444
|
+
}
|
|
23445
|
+
// A simulated root is where the tileset stands outside its history; recorded positions still win.
|
|
23446
|
+
if (change.entities && !((_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.getDateRange().minDate)) {
|
|
23447
|
+
this.applyRootRest(tileset);
|
|
23448
|
+
}
|
|
23449
|
+
});
|
|
23450
|
+
}
|
|
23451
|
+
/*
|
|
23452
|
+
* Re-reads the root's history after its simulated records changed, following the clock if it was not.
|
|
23453
|
+
*/
|
|
23454
|
+
async regatherRoot(tileset) {
|
|
22538
23455
|
var _a;
|
|
23456
|
+
if (!this.historicGatherer) {
|
|
23457
|
+
this.viewerDateTimeSub(tileset);
|
|
23458
|
+
return;
|
|
23459
|
+
}
|
|
23460
|
+
await this.historicPossesLoadingProm;
|
|
23461
|
+
const { recordsByIds } = await this.historicGatherer.Gather([{ Bruce: { ID: this.rootId } }]);
|
|
23462
|
+
if (this.disposed) {
|
|
23463
|
+
return;
|
|
23464
|
+
}
|
|
23465
|
+
const posses = Manager.HistoricPossesFor({ viewer: this.viewer, item: this.item, records: recordsByIds[this.rootId] || [] });
|
|
23466
|
+
(_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.replacePositions(posses);
|
|
23467
|
+
if (!posses.length) {
|
|
23468
|
+
this.applyRootRest(tileset);
|
|
23469
|
+
}
|
|
23470
|
+
}
|
|
23471
|
+
/*
|
|
23472
|
+
* The root as read at the scene's time, with any simulated record at that time laid over it.
|
|
23473
|
+
*/
|
|
23474
|
+
atClock(root) {
|
|
23475
|
+
return this.simulation && root
|
|
23476
|
+
? this.simulation.ApplyAt(root, JulianDate.toDate(this.viewer.clock.currentTime).getTime())
|
|
23477
|
+
: root;
|
|
23478
|
+
}
|
|
23479
|
+
/*
|
|
23480
|
+
* Stands the tileset where its root is outside history: the simulated root, else the root's own record.
|
|
23481
|
+
*/
|
|
23482
|
+
applyRootRest(tileset) {
|
|
23483
|
+
var _a;
|
|
23484
|
+
this.applyCoords(tileset, (_a = this.simulatedRootCoords()) !== null && _a !== void 0 ? _a : this.restCoords);
|
|
23485
|
+
}
|
|
23486
|
+
/*
|
|
23487
|
+
* Where a simulated root puts the tileset, or null; a patch only places it when it names a whole location.
|
|
23488
|
+
*/
|
|
23489
|
+
simulatedRootCoords() {
|
|
23490
|
+
var _a, _b;
|
|
23491
|
+
const simulation = this.rootId ? this.simulation : null;
|
|
23492
|
+
const root = (_a = simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(this.rootId)) !== null && _a !== void 0 ? _a : ((simulation === null || simulation === void 0 ? void 0 : simulation.HasBlob(this.rootId)) ? simulation.Overlay({ Bruce: { ID: this.rootId } }) : null);
|
|
23493
|
+
const location = (_b = root === null || root === void 0 ? void 0 : root.Bruce) === null || _b === void 0 ? void 0 : _b.Location;
|
|
23494
|
+
if ((location === null || location === void 0 ? void 0 : location.latitude) == null || (location === null || location === void 0 ? void 0 : location.longitude) == null) {
|
|
23495
|
+
return null;
|
|
23496
|
+
}
|
|
23497
|
+
const pos3d = Cartesian3.fromDegrees(+location.longitude, +location.latitude, EnsureNumber(location.altitude, 0));
|
|
23498
|
+
const transform = root.Bruce.Transform;
|
|
23499
|
+
return coordsFromHistoricPos3d(this.cTileset, this.rootId, pos3d, EnsureNumber(transform === null || transform === void 0 ? void 0 : transform.heading, 0), transform === null || transform === void 0 ? void 0 : transform.pitch, transform === null || transform === void 0 ? void 0 : transform.roll);
|
|
23500
|
+
}
|
|
23501
|
+
viewerDateTimeDispose() {
|
|
23502
|
+
var _a, _b;
|
|
22539
23503
|
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
22540
23504
|
this.viewerDateTimeChangeRemoval = null;
|
|
23505
|
+
// Made before the first positions land, so it can outlive a removal that was never set.
|
|
23506
|
+
(_b = this.historicGatherer) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
23507
|
+
this.historicGatherer = null;
|
|
22541
23508
|
}
|
|
22542
23509
|
/**
|
|
22543
23510
|
* Updates the Tileset with latest coordinates.
|
|
@@ -23680,11 +24647,11 @@ var DataLabRenderManager;
|
|
|
23680
24647
|
this.viewMonitorRemoval = null;
|
|
23681
24648
|
this.renderQueue = [];
|
|
23682
24649
|
this.renderQueueInterval = null;
|
|
23683
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
23684
24650
|
this.zoomControl = [];
|
|
23685
24651
|
this.queryLoadId = 0;
|
|
23686
24652
|
this.renderDataLabEntitiesChain = Promise.resolve();
|
|
23687
24653
|
const { viewer, item, apiGetter, monitor, visualsRegister } = params;
|
|
24654
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation);
|
|
23688
24655
|
this.viewer = viewer;
|
|
23689
24656
|
this.item = item;
|
|
23690
24657
|
this.apiGetter = apiGetter;
|
|
@@ -23781,7 +24748,8 @@ var DataLabRenderManager;
|
|
|
23781
24748
|
if (!((_a = data === null || data === void 0 ? void 0 : data.entities) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
23782
24749
|
return;
|
|
23783
24750
|
}
|
|
23784
|
-
|
|
24751
|
+
// The getter answers from the API, so a simulated Entity in its answer is swapped for its blob.
|
|
24752
|
+
this.distributeForRender(this.reRenderState.withSimulated(data.entities));
|
|
23785
24753
|
});
|
|
23786
24754
|
}
|
|
23787
24755
|
unsetGetter() {
|
|
@@ -23936,6 +24904,16 @@ var DataLabRenderManager;
|
|
|
23936
24904
|
this.doEntityCheck(entityIds);
|
|
23937
24905
|
}
|
|
23938
24906
|
}
|
|
24907
|
+
/**
|
|
24908
|
+
* Switches to another of the item's own styles, restyling what is drawn without re-creating it.
|
|
24909
|
+
*/
|
|
24910
|
+
SwapStyle(item) {
|
|
24911
|
+
if (this.disposed) {
|
|
24912
|
+
return;
|
|
24913
|
+
}
|
|
24914
|
+
this.item = item;
|
|
24915
|
+
this.UpdateSettings({ zoomControl: item.CameraZoomSettings });
|
|
24916
|
+
}
|
|
23939
24917
|
async doEntityCheck(ids, force = false) {
|
|
23940
24918
|
var _a, _b, _c, _d;
|
|
23941
24919
|
if (this.isRunningCheck) {
|
|
@@ -25532,6 +26510,7 @@ var TilesetEntitiesRenderManager;
|
|
|
25532
26510
|
this.featurePropCache = new Map();
|
|
25533
26511
|
this.featurePropsChecked = 0;
|
|
25534
26512
|
const { viewer, register: visualsManager, getters: apiGetter, item, initQueue, monitor } = params;
|
|
26513
|
+
this.simulation = params.simulation;
|
|
25535
26514
|
this.monitor = monitor;
|
|
25536
26515
|
this.viewer = viewer;
|
|
25537
26516
|
this.getters = apiGetter;
|
|
@@ -25632,6 +26611,7 @@ var TilesetEntitiesRenderManager;
|
|
|
25632
26611
|
if (Manager.NeedsStyler(this.item)) {
|
|
25633
26612
|
const api = this.getters.GetBruceApi();
|
|
25634
26613
|
this.styler.Init({
|
|
26614
|
+
simulation: this.simulation,
|
|
25635
26615
|
viewer: this.viewer,
|
|
25636
26616
|
api: api,
|
|
25637
26617
|
cTileset: this.cTileset,
|
|
@@ -25847,6 +26827,21 @@ var TilesetEntitiesRenderManager;
|
|
|
25847
26827
|
}
|
|
25848
26828
|
}
|
|
25849
26829
|
}
|
|
26830
|
+
/**
|
|
26831
|
+
* Switches to another of the item's own styles, restyling the loaded tileset without reloading it.
|
|
26832
|
+
*/
|
|
26833
|
+
SwapStyle(item) {
|
|
26834
|
+
if (this.disposed) {
|
|
26835
|
+
return;
|
|
26836
|
+
}
|
|
26837
|
+
this.item = item;
|
|
26838
|
+
if (Manager.NeedsStyler(item)) {
|
|
26839
|
+
this.styler.UpdateStyleMapping({
|
|
26840
|
+
styleMapping: [],
|
|
26841
|
+
fallbackStyleId: item.styleId
|
|
26842
|
+
});
|
|
26843
|
+
}
|
|
26844
|
+
}
|
|
25850
26845
|
Dispose() {
|
|
25851
26846
|
var _a;
|
|
25852
26847
|
if (this.disposed) {
|
|
@@ -25989,6 +26984,7 @@ var TilesetEntitiesRenderManager;
|
|
|
25989
26984
|
const needsStyler = Manager.NeedsStyler(this.item);
|
|
25990
26985
|
if (needsStyler) {
|
|
25991
26986
|
this.styler.Init({
|
|
26987
|
+
simulation: this.simulation,
|
|
25992
26988
|
viewer: this.viewer,
|
|
25993
26989
|
api: this.getters.GetBruceApi(),
|
|
25994
26990
|
cTileset: this.cTileset,
|
|
@@ -26680,6 +27676,7 @@ var TilesetArbRenderManager;
|
|
|
26680
27676
|
// LCC object if we're using XGrids to render LCC data.
|
|
26681
27677
|
this.lccObject = null;
|
|
26682
27678
|
this.viewer = params.viewer;
|
|
27679
|
+
this.simulation = params.simulation;
|
|
26683
27680
|
this.getters = params.getters;
|
|
26684
27681
|
this.visualsManager = params.register;
|
|
26685
27682
|
// We modify the object due to a lot of backwards compatibility.
|
|
@@ -26914,6 +27911,7 @@ var TilesetArbRenderManager;
|
|
|
26914
27911
|
this.item.Type == MenuItem.EType.IonTileset) {
|
|
26915
27912
|
const api = this.getters.GetBruceApi();
|
|
26916
27913
|
this.styler.Init({
|
|
27914
|
+
simulation: this.simulation,
|
|
26917
27915
|
viewer: this.viewer,
|
|
26918
27916
|
api: api,
|
|
26919
27917
|
cTileset: this.cTileset,
|
|
@@ -27100,6 +28098,23 @@ var TilesetArbRenderManager;
|
|
|
27100
28098
|
this.viewer.zoomTo(this.cTileset, new HeadingPitchRange(0.0, -0.5, this.cTileset.boundingSphere.radius / 4.0));
|
|
27101
28099
|
}
|
|
27102
28100
|
}
|
|
28101
|
+
/**
|
|
28102
|
+
* Switches to another of the item's own styles, restyling the loaded tileset without reloading it.
|
|
28103
|
+
*/
|
|
28104
|
+
SwapStyle(item) {
|
|
28105
|
+
var _a;
|
|
28106
|
+
if (this.disposed) {
|
|
28107
|
+
return;
|
|
28108
|
+
}
|
|
28109
|
+
// Copied for the same reason the constructor copies it.
|
|
28110
|
+
this.item = JSON.parse(JSON.stringify(item));
|
|
28111
|
+
if (this.item.ApplyStyles || this.item.Type == MenuItem.EType.IonTileset) {
|
|
28112
|
+
this.styler.UpdateStyleMapping({
|
|
28113
|
+
styleMapping: (_a = this.item.StyleMapping) !== null && _a !== void 0 ? _a : [],
|
|
28114
|
+
fallbackStyleId: this.item.styleId
|
|
28115
|
+
});
|
|
28116
|
+
}
|
|
28117
|
+
}
|
|
27103
28118
|
Dispose() {
|
|
27104
28119
|
if (this.disposed) {
|
|
27105
28120
|
return;
|
|
@@ -27255,14 +28270,32 @@ var RelationsRenderManager;
|
|
|
27255
28270
|
}
|
|
27256
28271
|
;
|
|
27257
28272
|
constructor(params) {
|
|
28273
|
+
var _a, _b;
|
|
27258
28274
|
// If true, this menu item is disposed and should not be used.
|
|
27259
28275
|
// Any rendering will be ignored.
|
|
27260
28276
|
this.disposed = false;
|
|
28277
|
+
this.simulationRemoval = null;
|
|
28278
|
+
this.FollowsSimulation = true;
|
|
27261
28279
|
const { apiGetter, item, register, viewer } = params;
|
|
27262
28280
|
this.apiGetter = apiGetter;
|
|
27263
28281
|
this.item = item;
|
|
27264
28282
|
this.register = register;
|
|
27265
28283
|
this.viewer = viewer;
|
|
28284
|
+
this.simulation = params.simulation;
|
|
28285
|
+
// Ends are not this item's own Entities, so it watches the store itself rather than wait to be asked.
|
|
28286
|
+
this.simulationRemoval = (_b = (_a = this.simulation) === null || _a === void 0 ? void 0 : _a.OnChanged.Subscribe((change) => {
|
|
28287
|
+
if (this.disposed) {
|
|
28288
|
+
return;
|
|
28289
|
+
}
|
|
28290
|
+
const relations = RelationRenderEngine.TakeRelationsTouching({
|
|
28291
|
+
visualRegister: this.register,
|
|
28292
|
+
menuItemId: this.item.id,
|
|
28293
|
+
entityIds: change.entityIds
|
|
28294
|
+
});
|
|
28295
|
+
if (relations.length) {
|
|
28296
|
+
this.onGetterUpdate(relations);
|
|
28297
|
+
}
|
|
28298
|
+
})) !== null && _b !== void 0 ? _b : null;
|
|
27266
28299
|
}
|
|
27267
28300
|
/**
|
|
27268
28301
|
* Starts rendering the menu item.
|
|
@@ -27331,10 +28364,13 @@ var RelationsRenderManager;
|
|
|
27331
28364
|
return items;
|
|
27332
28365
|
}
|
|
27333
28366
|
Dispose() {
|
|
28367
|
+
var _a;
|
|
27334
28368
|
if (this.disposed) {
|
|
27335
28369
|
return;
|
|
27336
28370
|
}
|
|
27337
28371
|
this.disposed = true;
|
|
28372
|
+
(_a = this.simulationRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
28373
|
+
this.simulationRemoval = null;
|
|
27338
28374
|
this.register.RemoveRegos({
|
|
27339
28375
|
menuItemId: this.item.id
|
|
27340
28376
|
});
|
|
@@ -27573,7 +28609,8 @@ var RelationsRenderManager;
|
|
|
27573
28609
|
menuItemId: this.item.id,
|
|
27574
28610
|
relations: relations,
|
|
27575
28611
|
viewer: this.viewer,
|
|
27576
|
-
visualRegister: this.register
|
|
28612
|
+
visualRegister: this.register,
|
|
28613
|
+
simulation: this.simulation
|
|
27577
28614
|
});
|
|
27578
28615
|
if (this.disposed) {
|
|
27579
28616
|
this.register.RemoveRegos({
|
|
@@ -27856,9 +28893,12 @@ var LegacyRelationsRenderManager;
|
|
|
27856
28893
|
}
|
|
27857
28894
|
;
|
|
27858
28895
|
constructor(params) {
|
|
28896
|
+
var _a, _b;
|
|
27859
28897
|
// If true, this menu item is disposed and should not be used.
|
|
27860
28898
|
// Any rendering will be ignored.
|
|
27861
28899
|
this.disposed = false;
|
|
28900
|
+
this.simulationRemoval = null;
|
|
28901
|
+
this.FollowsSimulation = true;
|
|
27862
28902
|
// Record of the currently drawn entity IDs.
|
|
27863
28903
|
// This is to avoid re-queueing already drawn entities when Init is called multiple times.
|
|
27864
28904
|
this.drawnIds = [];
|
|
@@ -27867,6 +28907,21 @@ var LegacyRelationsRenderManager;
|
|
|
27867
28907
|
this.item = item;
|
|
27868
28908
|
this.register = register;
|
|
27869
28909
|
this.viewer = viewer;
|
|
28910
|
+
this.simulation = params.simulation;
|
|
28911
|
+
// Ends are not this item's own Entities, so it watches the store itself rather than wait to be asked.
|
|
28912
|
+
this.simulationRemoval = (_b = (_a = this.simulation) === null || _a === void 0 ? void 0 : _a.OnChanged.Subscribe((change) => {
|
|
28913
|
+
if (this.disposed) {
|
|
28914
|
+
return;
|
|
28915
|
+
}
|
|
28916
|
+
const relations = RelationRenderEngine.TakeRelationsTouching({
|
|
28917
|
+
visualRegister: this.register,
|
|
28918
|
+
menuItemId: this.item.id,
|
|
28919
|
+
entityIds: change.entityIds
|
|
28920
|
+
});
|
|
28921
|
+
if (relations.length) {
|
|
28922
|
+
this.onGetterUpdate(relations);
|
|
28923
|
+
}
|
|
28924
|
+
})) !== null && _b !== void 0 ? _b : null;
|
|
27870
28925
|
}
|
|
27871
28926
|
/**
|
|
27872
28927
|
* Starts rendering the menu item.
|
|
@@ -27909,10 +28964,13 @@ var LegacyRelationsRenderManager;
|
|
|
27909
28964
|
this.drawnIds = [].concat(entityIds);
|
|
27910
28965
|
}
|
|
27911
28966
|
Dispose() {
|
|
28967
|
+
var _a;
|
|
27912
28968
|
if (this.disposed) {
|
|
27913
28969
|
return;
|
|
27914
28970
|
}
|
|
27915
28971
|
this.disposed = true;
|
|
28972
|
+
(_a = this.simulationRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
28973
|
+
this.simulationRemoval = null;
|
|
27916
28974
|
this.register.RemoveRegos({
|
|
27917
28975
|
menuItemId: this.item.id
|
|
27918
28976
|
});
|
|
@@ -28073,7 +29131,8 @@ var LegacyRelationsRenderManager;
|
|
|
28073
29131
|
menuItemId: this.item.id,
|
|
28074
29132
|
relations: relations,
|
|
28075
29133
|
viewer: this.viewer,
|
|
28076
|
-
visualRegister: this.register
|
|
29134
|
+
visualRegister: this.register,
|
|
29135
|
+
simulation: this.simulation
|
|
28077
29136
|
});
|
|
28078
29137
|
if (this.disposed) {
|
|
28079
29138
|
this.register.RemoveRegos({
|
|
@@ -29306,6 +30365,55 @@ var AssemblyRenderManager;
|
|
|
29306
30365
|
get ModelSpace() {
|
|
29307
30366
|
return this.modelSpace;
|
|
29308
30367
|
}
|
|
30368
|
+
/**
|
|
30369
|
+
* Every node of the Assembly read so far, so a caller can work out motion in the Assembly's own terms.
|
|
30370
|
+
* @param timeMs the scene time for each node's current pose. Default: the clock's.
|
|
30371
|
+
* @returns per node its pose within its parent from the API (local) and as drawn at the time (current).
|
|
30372
|
+
*/
|
|
30373
|
+
GetNodes(timeMs) {
|
|
30374
|
+
const at = timeMs !== null && timeMs !== void 0 ? timeMs : JulianDate.toDate(this.viewer.clock.currentTime).getTime();
|
|
30375
|
+
const rowsOf = (m) => m ? [0, 1, 2, 3].map(row => [0, 1, 2, 3].map(column => m[(column * 4) + row])) : null;
|
|
30376
|
+
return Object.values(this.hierarchyNodeByEntityId || {}).map(node => {
|
|
30377
|
+
var _a, _b, _c;
|
|
30378
|
+
const entity = (_a = this.apiEntities.get(node.entityId)) !== null && _a !== void 0 ? _a : null;
|
|
30379
|
+
const rows = (_b = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _b === void 0 ? void 0 : _b.AssemblyPosition;
|
|
30380
|
+
return {
|
|
30381
|
+
entityId: node.entityId,
|
|
30382
|
+
name: node.name,
|
|
30383
|
+
parentId: (_c = node.parentId) !== null && _c !== void 0 ? _c : null,
|
|
30384
|
+
local: Manager.MatrixFromRows(rows) ? rows : null,
|
|
30385
|
+
current: rowsOf(this.localAt(node.entityId, at)),
|
|
30386
|
+
entity
|
|
30387
|
+
};
|
|
30388
|
+
});
|
|
30389
|
+
}
|
|
30390
|
+
/**
|
|
30391
|
+
* The root's world frame at a time, history and simulation included, eg. to follow or frame the Assembly.
|
|
30392
|
+
* @param timeMs the scene time. Default: the clock's.
|
|
30393
|
+
* @returns null until the root has been read.
|
|
30394
|
+
*/
|
|
30395
|
+
GetRootFrame(timeMs) {
|
|
30396
|
+
const root = this.rootAt(timeMs !== null && timeMs !== void 0 ? timeMs : JulianDate.toDate(this.viewer.clock.currentTime).getTime());
|
|
30397
|
+
return root ? Manager.rootFrame(root.pos3d, root.heading, root.pitch, root.roll) : null;
|
|
30398
|
+
}
|
|
30399
|
+
/**
|
|
30400
|
+
* A part's world frame at a time as its records and its parents place it, size included.
|
|
30401
|
+
* @param entityId the part.
|
|
30402
|
+
* @param timeMs the scene time. Default: the clock's.
|
|
30403
|
+
* @returns null until the root and the part have been read.
|
|
30404
|
+
*/
|
|
30405
|
+
GetPartFrame(entityId, timeMs) {
|
|
30406
|
+
const at = timeMs !== null && timeMs !== void 0 ? timeMs : JulianDate.toDate(this.viewer.clock.currentTime).getTime();
|
|
30407
|
+
const rootFrame = this.GetRootFrame(at);
|
|
30408
|
+
const world = entityId === this.rootId ? Matrix4.IDENTITY : this.composeWorld(entityId, at);
|
|
30409
|
+
if (!rootFrame || !world) {
|
|
30410
|
+
return null;
|
|
30411
|
+
}
|
|
30412
|
+
// Where the part is drawn, so its own ground offset is part of its frame.
|
|
30413
|
+
const ground = this.groundOffsets.get(entityId);
|
|
30414
|
+
const placed = ground ? Matrix4.multiply(Matrix4.fromTranslation(ground), world, new Matrix4()) : world;
|
|
30415
|
+
return Matrix4.multiply(rootFrame, placed, new Matrix4());
|
|
30416
|
+
}
|
|
29309
30417
|
constructor(params) {
|
|
29310
30418
|
this.disposed = false;
|
|
29311
30419
|
// Cache of the hierarchy so that our scene-tree can reference it.
|
|
@@ -29315,19 +30423,41 @@ var AssemblyRenderManager;
|
|
|
29315
30423
|
this.hierarchyNodeByEntityId = null;
|
|
29316
30424
|
this.modelSpace = false;
|
|
29317
30425
|
this.rootId = null;
|
|
29318
|
-
// Where the root sits
|
|
29319
|
-
// Every child is placed through this, so a root move is one value changing rather than a refetch of the whole Assembly.
|
|
30426
|
+
// Where the root sits outside its history, and which way it faces in degrees. Children are placed through it.
|
|
29320
30427
|
this.rootPos3d = null;
|
|
29321
30428
|
this.rootHeading = 0;
|
|
29322
|
-
|
|
30429
|
+
this.rootPitch = 0;
|
|
30430
|
+
this.rootRoll = 0;
|
|
30431
|
+
// The root's recorded positions and attitudes, oldest first, kept apart since a record may name only one.
|
|
30432
|
+
this.rootSeries = [];
|
|
30433
|
+
this.rootAttitude = [];
|
|
30434
|
+
// Every placement worked out for the scene time last asked about, shared by all parts drawn at it.
|
|
30435
|
+
this.pose = null;
|
|
30436
|
+
// Entity ID -> what was drawn for it.
|
|
29323
30437
|
this.children = new Map();
|
|
30438
|
+
// Entity ID -> its live position within its parent, for every node fetched including undrawn groups.
|
|
30439
|
+
this.localPositions = new Map();
|
|
30440
|
+
// Entity ID -> how much higher the ground under it is than under the root, along the root's up.
|
|
30441
|
+
this.groundOffsets = new Map();
|
|
30442
|
+
// Entity ID -> its recorded poses within its parent, oldest first.
|
|
30443
|
+
this.jointSeries = new Map();
|
|
30444
|
+
// Drawn children that can move with the clock, so a tick places only these and not the whole Assembly.
|
|
30445
|
+
this.animatedIds = new Set();
|
|
29324
30446
|
// The trail through the root's own movement, which describes the whole Assembly.
|
|
29325
|
-
this.
|
|
30447
|
+
this.trail = null;
|
|
30448
|
+
this.simulationRemoval = null;
|
|
30449
|
+
this.FollowsSimulation = true;
|
|
30450
|
+
// Entity ID -> the record the API gave, so a cleared simulation falls back to it without a refetch.
|
|
30451
|
+
this.apiEntities = new Map();
|
|
30452
|
+
// Re-reads history and re-applies it, eg. after simulated records change. Set while the clock is followed.
|
|
30453
|
+
this.regather = null;
|
|
30454
|
+
this.followingClock = false;
|
|
29326
30455
|
// Callback to dispose the link between scene time and the root's historic position.
|
|
29327
30456
|
this.viewerDateTimeChangeRemoval = null;
|
|
29328
30457
|
this.historicGatherer = null;
|
|
29329
30458
|
this.historicAnimation = null;
|
|
29330
30459
|
const { viewer, register: visualsManager, getters, item } = params;
|
|
30460
|
+
this.simulation = params.simulation;
|
|
29331
30461
|
this.viewer = viewer;
|
|
29332
30462
|
this.getters = getters;
|
|
29333
30463
|
this.item = item;
|
|
@@ -29351,10 +30481,10 @@ var AssemblyRenderManager;
|
|
|
29351
30481
|
return EntityRenderEngine.GetHeightRef((_b = (_a = item === null || item === void 0 ? void 0 : item.Style) === null || _a === void 0 ? void 0 : _a.Settings) === null || _b === void 0 ? void 0 : _b["modelStyle"]);
|
|
29352
30482
|
}
|
|
29353
30483
|
/*
|
|
29354
|
-
* The root's frame: east-north-up at its position, turned by its heading.
|
|
30484
|
+
* The root's frame: east-north-up at its position, turned by its heading, pitch and roll.
|
|
29355
30485
|
*/
|
|
29356
|
-
static rootFrame(rootPos3d, headingDegrees) {
|
|
29357
|
-
const hpr = new HeadingPitchRoll(Math$1.toRadians(headingDegrees || 0), 0, 0);
|
|
30486
|
+
static rootFrame(rootPos3d, headingDegrees, pitchDegrees = 0, rollDegrees = 0) {
|
|
30487
|
+
const hpr = new HeadingPitchRoll(Math$1.toRadians(headingDegrees || 0), Math$1.toRadians(pitchDegrees || 0), Math$1.toRadians(rollDegrees || 0));
|
|
29358
30488
|
return Transforms.headingPitchRollToFixedFrame(rootPos3d, hpr);
|
|
29359
30489
|
}
|
|
29360
30490
|
/**
|
|
@@ -29377,28 +30507,553 @@ var AssemblyRenderManager;
|
|
|
29377
30507
|
return Matrix4.multiplyByPoint(Manager.rootFrame(rootPos3d, headingDegrees), offset, new Cartesian3());
|
|
29378
30508
|
}
|
|
29379
30509
|
/**
|
|
29380
|
-
* Moves the
|
|
30510
|
+
* Moves where the root sits outside its history, without refetching children; recorded poses still win.
|
|
29381
30511
|
* @param params
|
|
29382
30512
|
*/
|
|
29383
30513
|
ApplyRootPosition(params) {
|
|
29384
|
-
var _a, _b;
|
|
30514
|
+
var _a, _b, _c, _d, _e, _f;
|
|
29385
30515
|
if (this.disposed || !(params === null || params === void 0 ? void 0 : params.pos3d)) {
|
|
29386
30516
|
return;
|
|
29387
30517
|
}
|
|
29388
30518
|
this.rootPos3d = params.pos3d;
|
|
29389
30519
|
this.rootHeading = (_b = (_a = params.heading) !== null && _a !== void 0 ? _a : this.rootHeading) !== null && _b !== void 0 ? _b : 0;
|
|
30520
|
+
this.rootPitch = (_d = (_c = params.pitch) !== null && _c !== void 0 ? _c : this.rootPitch) !== null && _d !== void 0 ? _d : 0;
|
|
30521
|
+
this.rootRoll = (_f = (_e = params.roll) !== null && _e !== void 0 ? _e : this.rootRoll) !== null && _f !== void 0 ? _f : 0;
|
|
30522
|
+
this.repose(true);
|
|
30523
|
+
}
|
|
30524
|
+
/*
|
|
30525
|
+
* Drops every placement worked out so far, after the root or a joint's records change.
|
|
30526
|
+
* @param everyChild re-place the parts that cannot move as well, because where they rest has changed.
|
|
30527
|
+
*/
|
|
30528
|
+
repose(everyChild = false) {
|
|
30529
|
+
this.pose = null;
|
|
29390
30530
|
for (const child of this.children.values()) {
|
|
29391
|
-
|
|
29392
|
-
|
|
30531
|
+
if (everyChild || Boolean(child.moving) != this.canMove(child.entityId)) {
|
|
30532
|
+
this.bindPlacement(child);
|
|
30533
|
+
}
|
|
30534
|
+
}
|
|
30535
|
+
this.viewer.scene.requestRender();
|
|
30536
|
+
}
|
|
30537
|
+
/*
|
|
30538
|
+
* Takes a node's pose outside its history from its record, and for the root where it stands and faces.
|
|
30539
|
+
*/
|
|
30540
|
+
absorbNode(entity) {
|
|
30541
|
+
var _a, _b, _c, _d, _e;
|
|
30542
|
+
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
30543
|
+
const local = Manager.MatrixFromRows((_b = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _b === void 0 ? void 0 : _b.AssemblyPosition);
|
|
30544
|
+
if (local) {
|
|
30545
|
+
this.localPositions.set(id, local);
|
|
30546
|
+
}
|
|
30547
|
+
// Anchored on the root, which is usually never drawn; everything under it is placed from the hierarchy.
|
|
30548
|
+
if (id === this.rootId || (!this.rootId && !this.rootPos3d)) {
|
|
30549
|
+
const rootPos3d = EntityUtils.GetPos({
|
|
30550
|
+
viewer: this.viewer,
|
|
30551
|
+
entity,
|
|
30552
|
+
recordHeightRef: Manager.GetRecordHeightRef(this.item),
|
|
30553
|
+
returnHeightRef: HeightReference.NONE,
|
|
30554
|
+
allowRendered: false
|
|
30555
|
+
});
|
|
30556
|
+
if (rootPos3d) {
|
|
30557
|
+
this.rootPos3d = rootPos3d;
|
|
30558
|
+
this.rootHeading = EnsureNumber((_c = entity.Bruce.Transform) === null || _c === void 0 ? void 0 : _c.heading, 0);
|
|
30559
|
+
this.rootPitch = EnsureNumber((_d = entity.Bruce.Transform) === null || _d === void 0 ? void 0 : _d.pitch, 0);
|
|
30560
|
+
this.rootRoll = EnsureNumber((_e = entity.Bruce.Transform) === null || _e === void 0 ? void 0 : _e.roll, 0);
|
|
30561
|
+
}
|
|
30562
|
+
}
|
|
30563
|
+
}
|
|
30564
|
+
/*
|
|
30565
|
+
* A node's record with its simulation laid over it, keeping what a stand-in leaves out, eg. its model.
|
|
30566
|
+
*/
|
|
30567
|
+
withSimulation(entity) {
|
|
30568
|
+
var _a;
|
|
30569
|
+
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
30570
|
+
if (!this.simulation || !id) {
|
|
30571
|
+
return entity;
|
|
30572
|
+
}
|
|
30573
|
+
const standIn = this.simulation.GetEntity(id);
|
|
30574
|
+
if (!standIn) {
|
|
30575
|
+
return this.simulation.Overlay(entity);
|
|
30576
|
+
}
|
|
30577
|
+
return { ...entity, ...standIn, Bruce: { ...entity.Bruce, ...standIn.Bruce } };
|
|
30578
|
+
}
|
|
30579
|
+
/*
|
|
30580
|
+
* Brings the Assembly in line with a change to what is simulated.
|
|
30581
|
+
*/
|
|
30582
|
+
onSimulationChanged(change) {
|
|
30583
|
+
var _a;
|
|
30584
|
+
if (this.disposed || !this.hierarchyNodeByEntityId) {
|
|
30585
|
+
return;
|
|
30586
|
+
}
|
|
30587
|
+
const ids = change.entityIds.filter(id => this.hierarchyNodeByEntityId[id]);
|
|
30588
|
+
if (!ids.length) {
|
|
30589
|
+
return;
|
|
30590
|
+
}
|
|
30591
|
+
if (change.entities) {
|
|
30592
|
+
for (const id of ids) {
|
|
30593
|
+
const api = this.apiEntities.get(id);
|
|
30594
|
+
if (!api) {
|
|
30595
|
+
// Not loaded yet, and it will be drawn from its simulation when it is.
|
|
30596
|
+
continue;
|
|
30597
|
+
}
|
|
30598
|
+
const entity = this.withSimulation(api);
|
|
30599
|
+
// A cleared blob leaves the node's own matrix where the API has none, so it is reset.
|
|
30600
|
+
if (!((_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.AssemblyPosition)) {
|
|
30601
|
+
this.localPositions.delete(id);
|
|
30602
|
+
}
|
|
30603
|
+
this.absorbNode(entity);
|
|
30604
|
+
const child = this.children.get(id);
|
|
30605
|
+
if (child) {
|
|
30606
|
+
child.entity = entity;
|
|
30607
|
+
}
|
|
30608
|
+
}
|
|
30609
|
+
this.repose(true);
|
|
30610
|
+
}
|
|
30611
|
+
if (change.records) {
|
|
30612
|
+
if (this.regather) {
|
|
30613
|
+
this.regather(true);
|
|
30614
|
+
}
|
|
30615
|
+
else {
|
|
30616
|
+
this.viewerDateTimeSub();
|
|
30617
|
+
}
|
|
30618
|
+
}
|
|
30619
|
+
}
|
|
30620
|
+
/*
|
|
30621
|
+
* Nodes of this Assembly with simulated history.
|
|
30622
|
+
*/
|
|
30623
|
+
simulatedNodeIds() {
|
|
30624
|
+
if (!this.simulation || !this.hierarchyNodeByEntityId) {
|
|
30625
|
+
return [];
|
|
30626
|
+
}
|
|
30627
|
+
return this.simulation.GetRecordEntityIds().filter(id => this.hierarchyNodeByEntityId[id]);
|
|
30628
|
+
}
|
|
30629
|
+
/*
|
|
30630
|
+
* Whether a node can move with time: the root has history, or it or an ancestor does.
|
|
30631
|
+
*/
|
|
30632
|
+
canMove(entityId) {
|
|
30633
|
+
return this.rootSeries.length > 0 || this.rootAttitude.length > 0 || this.animatedIds.has(entityId);
|
|
30634
|
+
}
|
|
30635
|
+
/*
|
|
30636
|
+
* Gives a child its position and orientation, as functions of scene time only when it can move.
|
|
30637
|
+
*/
|
|
30638
|
+
bindPlacement(child) {
|
|
30639
|
+
const id = child.entityId;
|
|
30640
|
+
const moving = this.canMove(id);
|
|
30641
|
+
if (moving) {
|
|
30642
|
+
if (!child.moving) {
|
|
30643
|
+
child.cEntity.position = new CallbackProperty((time, result) => { var _a; return Manager.cloneOrUndefined((_a = this.placementAt(id, time)) === null || _a === void 0 ? void 0 : _a.pos3d, result); }, false);
|
|
30644
|
+
child.cEntity.orientation = new CallbackProperty((time, result) => {
|
|
30645
|
+
var _a;
|
|
30646
|
+
const orient = (_a = this.placementAt(id, time)) === null || _a === void 0 ? void 0 : _a.orient;
|
|
30647
|
+
return orient ? Quaternion.clone(orient, result) : undefined;
|
|
30648
|
+
}, false);
|
|
30649
|
+
child.cEntity.model.scale = new CallbackProperty((time) => { var _a, _b; return (_b = (_a = this.placementAt(id, time)) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : 1; }, false);
|
|
30650
|
+
}
|
|
30651
|
+
}
|
|
30652
|
+
else {
|
|
30653
|
+
const placed = this.placementAt(id, this.viewer.clock.currentTime);
|
|
30654
|
+
if (placed) {
|
|
30655
|
+
child.cEntity.position = new ConstantPositionProperty(placed.pos3d);
|
|
30656
|
+
if (placed.orient) {
|
|
30657
|
+
child.cEntity.orientation = new ConstantProperty(placed.orient);
|
|
30658
|
+
}
|
|
30659
|
+
child.cEntity.model.scale = new ConstantProperty(placed.scale);
|
|
30660
|
+
}
|
|
30661
|
+
}
|
|
30662
|
+
if (Boolean(child.moving) != moving) {
|
|
30663
|
+
child.moving = moving;
|
|
30664
|
+
this.visualsManager.SetMoving({ moving, entityIds: [id], menuItemId: this.item.id });
|
|
30665
|
+
}
|
|
30666
|
+
}
|
|
30667
|
+
/*
|
|
30668
|
+
* The one scale a model takes from its part's composed matrix, the largest when they are uneven.
|
|
30669
|
+
*/
|
|
30670
|
+
static uniformScale(world) {
|
|
30671
|
+
return Cartesian3.maximumComponent(Matrix4.getScale(world, new Cartesian3()));
|
|
30672
|
+
}
|
|
30673
|
+
static cloneOrUndefined(pos3d, result) {
|
|
30674
|
+
return pos3d ? Cartesian3.clone(pos3d, result) : undefined;
|
|
30675
|
+
}
|
|
30676
|
+
/*
|
|
30677
|
+
* Where a node draws at a scene time, from one composition shared by every part asked about at that time.
|
|
30678
|
+
*/
|
|
30679
|
+
placementAt(entityId, time) {
|
|
30680
|
+
if (this.disposed || !time) {
|
|
30681
|
+
return null;
|
|
30682
|
+
}
|
|
30683
|
+
const timeMs = JulianDate.toDate(time).getTime();
|
|
30684
|
+
if (!this.pose || this.pose.timeMs !== timeMs) {
|
|
30685
|
+
const root = this.rootAt(timeMs);
|
|
30686
|
+
this.pose = {
|
|
30687
|
+
timeMs,
|
|
30688
|
+
rootFrame: root ? Manager.rootFrame(root.pos3d, root.heading, root.pitch, root.roll) : null,
|
|
30689
|
+
worlds: new Map(),
|
|
30690
|
+
placements: new Map()
|
|
30691
|
+
};
|
|
30692
|
+
}
|
|
30693
|
+
const pose = this.pose;
|
|
30694
|
+
if (!pose.rootFrame) {
|
|
30695
|
+
return null;
|
|
30696
|
+
}
|
|
30697
|
+
let placed = pose.placements.get(entityId);
|
|
30698
|
+
if (!placed) {
|
|
30699
|
+
const world = this.composeWorld(entityId, timeMs, pose.worlds);
|
|
30700
|
+
const offset = world
|
|
30701
|
+
? Matrix4.getTranslation(world, new Cartesian3())
|
|
30702
|
+
: new Cartesian3(0, 0, 0);
|
|
30703
|
+
const ground = this.groundOffsets.get(entityId);
|
|
30704
|
+
if (ground) {
|
|
30705
|
+
Cartesian3.add(offset, ground, offset);
|
|
30706
|
+
}
|
|
30707
|
+
placed = {
|
|
30708
|
+
pos3d: Matrix4.multiplyByPoint(pose.rootFrame, offset, new Cartesian3()),
|
|
30709
|
+
// Without a matrix, eg. the root itself, there is no orientation of its own to apply.
|
|
30710
|
+
orient: world ? EntityUtils.GetAssemblyOrientationInFrame(pose.rootFrame, world) : null,
|
|
30711
|
+
scale: world ? Manager.uniformScale(world) : 1
|
|
30712
|
+
};
|
|
30713
|
+
pose.placements.set(entityId, placed);
|
|
30714
|
+
}
|
|
30715
|
+
return placed;
|
|
30716
|
+
}
|
|
30717
|
+
/*
|
|
30718
|
+
* The root's pose at a time, position and attitude each following their own records as a joint's do.
|
|
30719
|
+
*/
|
|
30720
|
+
rootAt(timeMs) {
|
|
30721
|
+
const pos3d = this.rootPositionAt(timeMs);
|
|
30722
|
+
if (!pos3d) {
|
|
30723
|
+
return null;
|
|
30724
|
+
}
|
|
30725
|
+
const live = { heading: this.rootHeading, pitch: this.rootPitch, roll: this.rootRoll };
|
|
30726
|
+
const series = this.rootAttitude;
|
|
30727
|
+
if (!series.length || timeMs < series[0].timeMs) {
|
|
30728
|
+
return { pos3d, ...live };
|
|
30729
|
+
}
|
|
30730
|
+
let i = 0;
|
|
30731
|
+
while (i < series.length - 1 && series[i + 1].timeMs <= timeMs) {
|
|
30732
|
+
i++;
|
|
30733
|
+
}
|
|
30734
|
+
const a = series[i];
|
|
30735
|
+
const b = series[i + 1];
|
|
30736
|
+
const t = b ? (timeMs - a.timeMs) / (b.timeMs - a.timeMs) : 0;
|
|
30737
|
+
const turn = (from, to, fallback) => {
|
|
30738
|
+
var _a, _b, _c;
|
|
30739
|
+
const x = (_a = from !== null && from !== void 0 ? from : fallback) !== null && _a !== void 0 ? _a : 0;
|
|
30740
|
+
const y = (_c = (_b = (b ? to : from)) !== null && _b !== void 0 ? _b : fallback) !== null && _c !== void 0 ? _c : 0;
|
|
30741
|
+
// The short way round, so 350 to 10 degrees turns through north rather than all the way back.
|
|
30742
|
+
return x + (Math$1.negativePiToPi(Math$1.toRadians(y - x)) * 180 / Math.PI) * t;
|
|
30743
|
+
};
|
|
30744
|
+
return {
|
|
30745
|
+
pos3d,
|
|
30746
|
+
heading: turn(a.heading, b === null || b === void 0 ? void 0 : b.heading, live.heading),
|
|
30747
|
+
pitch: turn(a.pitch, b === null || b === void 0 ? void 0 : b.pitch, live.pitch),
|
|
30748
|
+
roll: turn(a.roll, b === null || b === void 0 ? void 0 : b.roll, live.roll)
|
|
30749
|
+
};
|
|
30750
|
+
}
|
|
30751
|
+
/*
|
|
30752
|
+
* Where the root is at a time, from its recorded positions.
|
|
30753
|
+
*/
|
|
30754
|
+
rootPositionAt(timeMs) {
|
|
30755
|
+
const series = this.rootSeries;
|
|
30756
|
+
if (!series.length || timeMs < series[0].timeMs) {
|
|
30757
|
+
return this.rootPos3d;
|
|
30758
|
+
}
|
|
30759
|
+
let i = 0;
|
|
30760
|
+
while (i < series.length - 1 && series[i + 1].timeMs <= timeMs) {
|
|
30761
|
+
i++;
|
|
30762
|
+
}
|
|
30763
|
+
const a = series[i];
|
|
30764
|
+
const b = series[i + 1];
|
|
30765
|
+
if (!b) {
|
|
30766
|
+
return a.pos3d;
|
|
30767
|
+
}
|
|
30768
|
+
const t = (timeMs - a.timeMs) / (b.timeMs - a.timeMs);
|
|
30769
|
+
// A straight line between orbit samples cuts up to a kilometre inside the path, so it is lifted back out.
|
|
30770
|
+
const chord = Cartesian3.lerp(a.pos3d, b.pos3d, t, new Cartesian3());
|
|
30771
|
+
const carto = Cartographic.fromCartesian(chord);
|
|
30772
|
+
return carto
|
|
30773
|
+
? Cartesian3.fromRadians(carto.longitude, carto.latitude, Math$1.lerp(a.height, b.height, t))
|
|
30774
|
+
: chord;
|
|
30775
|
+
}
|
|
30776
|
+
/*
|
|
30777
|
+
* Takes the root's records into its series.
|
|
30778
|
+
* @param replace the records are everything held for the root, so the series becomes exactly them.
|
|
30779
|
+
* @returns whether the series changed.
|
|
30780
|
+
*/
|
|
30781
|
+
absorbRootRecords(posses, replace) {
|
|
30782
|
+
if (!(posses === null || posses === void 0 ? void 0 : posses.length) && !(replace && this.rootSeries.length)) {
|
|
30783
|
+
return false;
|
|
30784
|
+
}
|
|
30785
|
+
const byTime = new Map(replace ? [] : this.rootSeries.map(k => [k.timeMs, k]));
|
|
30786
|
+
for (const pos of posses) {
|
|
30787
|
+
const carto = Cartographic.fromCartesian(pos.pos3d);
|
|
30788
|
+
if (!carto) {
|
|
29393
30789
|
continue;
|
|
29394
30790
|
}
|
|
29395
|
-
|
|
29396
|
-
|
|
29397
|
-
|
|
29398
|
-
|
|
30791
|
+
byTime.set(pos.dateTime.getTime(), {
|
|
30792
|
+
timeMs: pos.dateTime.getTime(),
|
|
30793
|
+
pos3d: pos.pos3d,
|
|
30794
|
+
height: carto.height
|
|
30795
|
+
});
|
|
30796
|
+
}
|
|
30797
|
+
const series = Array.from(byTime.values()).sort((x, y) => x.timeMs - y.timeMs);
|
|
30798
|
+
const changed = (series.length !== this.rootSeries.length ||
|
|
30799
|
+
series.some((k, i) => !Cartesian3.equals(k.pos3d, this.rootSeries[i].pos3d)));
|
|
30800
|
+
this.rootSeries = series;
|
|
30801
|
+
return changed;
|
|
30802
|
+
}
|
|
30803
|
+
/*
|
|
30804
|
+
* Takes the angles the root's records name into its attitude series, apart from where it is.
|
|
30805
|
+
* @param replace the records are everything held for the root, as for absorbRootRecords.
|
|
30806
|
+
* @returns whether the series changed.
|
|
30807
|
+
*/
|
|
30808
|
+
absorbRootAttitude(records, replace) {
|
|
30809
|
+
const angle = (transform, key) => {
|
|
30810
|
+
var _a;
|
|
30811
|
+
const value = (_a = transform === null || transform === void 0 ? void 0 : transform[key]) !== null && _a !== void 0 ? _a : transform === null || transform === void 0 ? void 0 : transform[key[0].toUpperCase() + key.slice(1)];
|
|
30812
|
+
return value == null || isNaN(+value) ? null : +value;
|
|
30813
|
+
};
|
|
30814
|
+
const byTime = new Map(replace ? [] : this.rootAttitude.map(k => [k.timeMs, k]));
|
|
30815
|
+
for (const record of records || []) {
|
|
30816
|
+
const timeMs = (record === null || record === void 0 ? void 0 : record.dateTime) ? new Date(record.dateTime).getTime() : NaN;
|
|
30817
|
+
const key = {
|
|
30818
|
+
timeMs,
|
|
30819
|
+
heading: angle(record === null || record === void 0 ? void 0 : record.transform, "heading"),
|
|
30820
|
+
pitch: angle(record === null || record === void 0 ? void 0 : record.transform, "pitch"),
|
|
30821
|
+
roll: angle(record === null || record === void 0 ? void 0 : record.transform, "roll")
|
|
30822
|
+
};
|
|
30823
|
+
if (isNaN(timeMs) || (key.heading == null && key.pitch == null && key.roll == null)) {
|
|
30824
|
+
continue;
|
|
29399
30825
|
}
|
|
30826
|
+
byTime.set(timeMs, key);
|
|
29400
30827
|
}
|
|
29401
|
-
|
|
30828
|
+
const series = Array.from(byTime.values()).sort((x, y) => x.timeMs - y.timeMs);
|
|
30829
|
+
const held = this.rootAttitude;
|
|
30830
|
+
const differs = (k, i) => (k.timeMs !== held[i].timeMs ||
|
|
30831
|
+
k.heading !== held[i].heading ||
|
|
30832
|
+
k.pitch !== held[i].pitch ||
|
|
30833
|
+
k.roll !== held[i].roll);
|
|
30834
|
+
const changed = series.length !== held.length || series.some(differs);
|
|
30835
|
+
this.rootAttitude = series;
|
|
30836
|
+
return changed;
|
|
30837
|
+
}
|
|
30838
|
+
/*
|
|
30839
|
+
* A node's matrix in the root's frame at a time, from each ancestor's pose within its parent.
|
|
30840
|
+
*/
|
|
30841
|
+
composeWorld(entityId, timeMs, memo, localOf = (id) => this.localAt(id, timeMs)) {
|
|
30842
|
+
var _a, _b, _c, _d;
|
|
30843
|
+
if (memo === null || memo === void 0 ? void 0 : memo.has(entityId)) {
|
|
30844
|
+
return memo.get(entityId);
|
|
30845
|
+
}
|
|
30846
|
+
let world = null;
|
|
30847
|
+
const local = localOf(entityId);
|
|
30848
|
+
if (local) {
|
|
30849
|
+
const parentId = (_b = (_a = this.hierarchyNodeByEntityId) === null || _a === void 0 ? void 0 : _a[entityId]) === null || _b === void 0 ? void 0 : _b.parentId;
|
|
30850
|
+
const parent = parentId ? this.composeWorld(parentId, timeMs, memo, localOf) : null;
|
|
30851
|
+
world = parent ? Matrix4.multiply(parent, local, new Matrix4()) : Matrix4.clone(local);
|
|
30852
|
+
}
|
|
30853
|
+
else if (entityId !== this.rootId) {
|
|
30854
|
+
// A node whose own position was not fetched falls back to the API's composed matrix.
|
|
30855
|
+
const child = this.children.get(entityId);
|
|
30856
|
+
world = Manager.MatrixFromRows((_d = (_c = child === null || child === void 0 ? void 0 : child.entity) === null || _c === void 0 ? void 0 : _c.Bruce) === null || _d === void 0 ? void 0 : _d.AssemblyWorldPosition);
|
|
30857
|
+
}
|
|
30858
|
+
memo === null || memo === void 0 ? void 0 : memo.set(entityId, world);
|
|
30859
|
+
return world;
|
|
30860
|
+
}
|
|
30861
|
+
/*
|
|
30862
|
+
* Under a clamped or relative style, lifts a part by how much higher its ground is than the root's.
|
|
30863
|
+
*/
|
|
30864
|
+
measureGroundOffset(entity) {
|
|
30865
|
+
var _a;
|
|
30866
|
+
const entityId = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
30867
|
+
this.groundOffsets.delete(entityId);
|
|
30868
|
+
const root = this.apiEntities.get(this.rootId);
|
|
30869
|
+
if (!entityId ||
|
|
30870
|
+
entityId === this.rootId ||
|
|
30871
|
+
!root ||
|
|
30872
|
+
!this.rootPos3d ||
|
|
30873
|
+
Manager.GetRecordHeightRef(this.item) === HeightReference.NONE) {
|
|
30874
|
+
return;
|
|
30875
|
+
}
|
|
30876
|
+
const rootFrame = Manager.rootFrame(this.rootPos3d, this.rootHeading, this.rootPitch, this.rootRoll);
|
|
30877
|
+
const toRoot = Matrix4.inverse(rootFrame, new Matrix4());
|
|
30878
|
+
const groundUp = (record) => {
|
|
30879
|
+
const pos3d = EntityUtils.GetPos({
|
|
30880
|
+
viewer: this.viewer,
|
|
30881
|
+
entity: record,
|
|
30882
|
+
recordHeightRef: HeightReference.CLAMP_TO_GROUND,
|
|
30883
|
+
returnHeightRef: HeightReference.NONE,
|
|
30884
|
+
allowRendered: false
|
|
30885
|
+
});
|
|
30886
|
+
return pos3d ? Matrix4.multiplyByPoint(toRoot, pos3d, new Cartesian3()).z : null;
|
|
30887
|
+
};
|
|
30888
|
+
const part = groundUp(entity);
|
|
30889
|
+
const under = groundUp(root);
|
|
30890
|
+
if (part == null || under == null || Math.abs(part - under) < 1e-6) {
|
|
30891
|
+
return;
|
|
30892
|
+
}
|
|
30893
|
+
this.groundOffsets.set(entityId, new Cartesian3(0, 0, part - under));
|
|
30894
|
+
}
|
|
30895
|
+
/*
|
|
30896
|
+
* The rigid Earth-fixed motion from where a part's record places it to where it is drawn at a time.
|
|
30897
|
+
*/
|
|
30898
|
+
motionAt(entityId, time) {
|
|
30899
|
+
if (this.disposed || !time || !this.rootPos3d) {
|
|
30900
|
+
return null;
|
|
30901
|
+
}
|
|
30902
|
+
const timeMs = JulianDate.toDate(time).getTime();
|
|
30903
|
+
const root = this.rootAt(timeMs);
|
|
30904
|
+
const drawn = this.composeWorld(entityId, timeMs, new Map());
|
|
30905
|
+
const stored = this.composeWorld(entityId, timeMs, new Map(), (id) => {
|
|
30906
|
+
var _a, _b, _c, _d;
|
|
30907
|
+
return ((_d = (_c = Manager.MatrixFromRows((_b = (_a = this.apiEntities.get(id)) === null || _a === void 0 ? void 0 : _a.Bruce) === null || _b === void 0 ? void 0 : _b.AssemblyPosition)) !== null && _c !== void 0 ? _c : this.localPositions.get(id)) !== null && _d !== void 0 ? _d : null);
|
|
30908
|
+
});
|
|
30909
|
+
if (!root || !drawn || !stored) {
|
|
30910
|
+
return null;
|
|
30911
|
+
}
|
|
30912
|
+
const drawnFixed = Matrix4.multiply(Manager.rootFrame(root.pos3d, root.heading, root.pitch, root.roll), drawn, new Matrix4());
|
|
30913
|
+
const storedFixed = Matrix4.multiply(Manager.rootFrame(this.rootPos3d, this.rootHeading, this.rootPitch, this.rootRoll), stored, new Matrix4());
|
|
30914
|
+
return Matrix4.multiply(drawnFixed, Matrix4.inverse(storedFixed, new Matrix4()), new Matrix4());
|
|
30915
|
+
}
|
|
30916
|
+
/*
|
|
30917
|
+
* A node's pose within its parent at a time, interpolated between the records either side.
|
|
30918
|
+
*/
|
|
30919
|
+
localAt(entityId, timeMs) {
|
|
30920
|
+
var _a;
|
|
30921
|
+
// The live pose stands before the first record and the last record holds after it, as in an API read.
|
|
30922
|
+
const live = (_a = this.localPositions.get(entityId)) !== null && _a !== void 0 ? _a : null;
|
|
30923
|
+
const series = this.jointSeries.get(entityId);
|
|
30924
|
+
if (!(series === null || series === void 0 ? void 0 : series.length) || timeMs == null || timeMs < series[0].timeMs) {
|
|
30925
|
+
return live;
|
|
30926
|
+
}
|
|
30927
|
+
let i = 0;
|
|
30928
|
+
while (i < series.length - 1 && series[i + 1].timeMs <= timeMs) {
|
|
30929
|
+
i++;
|
|
30930
|
+
}
|
|
30931
|
+
const a = series[i];
|
|
30932
|
+
const b = series[i + 1];
|
|
30933
|
+
if (!b) {
|
|
30934
|
+
return Matrix4.fromTranslationQuaternionRotationScale(a.translation, a.rotation, a.scale);
|
|
30935
|
+
}
|
|
30936
|
+
const t = (timeMs - a.timeMs) / (b.timeMs - a.timeMs);
|
|
30937
|
+
return Matrix4.fromTranslationQuaternionRotationScale(Cartesian3.lerp(a.translation, b.translation, t, new Cartesian3()), Quaternion.slerp(a.rotation, b.rotation, t, new Quaternion()), Cartesian3.lerp(a.scale, b.scale, t, new Cartesian3()));
|
|
30938
|
+
}
|
|
30939
|
+
/*
|
|
30940
|
+
* Rebuilds each node's keyframes from the historic records held so far.
|
|
30941
|
+
* @returns whether any node has keyframes.
|
|
30942
|
+
*/
|
|
30943
|
+
absorbJointRecords(recordsByIds) {
|
|
30944
|
+
var _a;
|
|
30945
|
+
// Everything held is given, so a node with nothing left, eg. its simulated records cleared, stops moving.
|
|
30946
|
+
for (const entityId of Array.from(this.jointSeries.keys())) {
|
|
30947
|
+
if (!((_a = recordsByIds === null || recordsByIds === void 0 ? void 0 : recordsByIds[entityId]) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
30948
|
+
this.jointSeries.delete(entityId);
|
|
30949
|
+
}
|
|
30950
|
+
}
|
|
30951
|
+
for (const entityId of Object.keys(recordsByIds || {})) {
|
|
30952
|
+
const keyframes = [];
|
|
30953
|
+
for (const record of recordsByIds[entityId] || []) {
|
|
30954
|
+
const matrix = Manager.MatrixFromRows(record.assemblyPosition);
|
|
30955
|
+
const timeMs = new Date(record.dateTime).getTime();
|
|
30956
|
+
if (!matrix || isNaN(timeMs)) {
|
|
30957
|
+
continue;
|
|
30958
|
+
}
|
|
30959
|
+
const scale = Matrix4.getScale(matrix, new Cartesian3());
|
|
30960
|
+
const rotation = Matrix4.getRotation(matrix, new Matrix3());
|
|
30961
|
+
keyframes.push({
|
|
30962
|
+
timeMs,
|
|
30963
|
+
translation: Matrix4.getTranslation(matrix, new Cartesian3()),
|
|
30964
|
+
rotation: Quaternion.fromRotationMatrix(rotation),
|
|
30965
|
+
scale
|
|
30966
|
+
});
|
|
30967
|
+
}
|
|
30968
|
+
if (keyframes.length) {
|
|
30969
|
+
keyframes.sort((x, y) => x.timeMs - y.timeMs);
|
|
30970
|
+
this.jointSeries.set(entityId, keyframes);
|
|
30971
|
+
}
|
|
30972
|
+
}
|
|
30973
|
+
this.refreshAnimated();
|
|
30974
|
+
return this.jointSeries.size > 0;
|
|
30975
|
+
}
|
|
30976
|
+
/*
|
|
30977
|
+
* Rebuilds which drawn children can move with the clock, by walking each one up to the root.
|
|
30978
|
+
*/
|
|
30979
|
+
refreshAnimated() {
|
|
30980
|
+
this.animatedIds.clear();
|
|
30981
|
+
if (!this.jointSeries.size) {
|
|
30982
|
+
return;
|
|
30983
|
+
}
|
|
30984
|
+
for (const entityId of this.children.keys()) {
|
|
30985
|
+
if (this.hasAnimatedAncestry(entityId)) {
|
|
30986
|
+
this.animatedIds.add(entityId);
|
|
30987
|
+
}
|
|
30988
|
+
}
|
|
30989
|
+
}
|
|
30990
|
+
/*
|
|
30991
|
+
* Whether a node or anything above it has keyframes, so the clock can move it.
|
|
30992
|
+
*/
|
|
30993
|
+
hasAnimatedAncestry(entityId) {
|
|
30994
|
+
var _a, _b;
|
|
30995
|
+
let at = entityId;
|
|
30996
|
+
while (at && this.jointSeries.size) {
|
|
30997
|
+
if (this.jointSeries.has(at)) {
|
|
30998
|
+
return true;
|
|
30999
|
+
}
|
|
31000
|
+
at = (_b = (_a = this.hierarchyNodeByEntityId) === null || _a === void 0 ? void 0 : _a[at]) === null || _b === void 0 ? void 0 : _b.parentId;
|
|
31001
|
+
}
|
|
31002
|
+
return false;
|
|
31003
|
+
}
|
|
31004
|
+
/*
|
|
31005
|
+
* Which nodes to ask history for.
|
|
31006
|
+
*/
|
|
31007
|
+
async historicEntityIds(api) {
|
|
31008
|
+
var _a, _b;
|
|
31009
|
+
// Through the Assembly when there is one, so the hierarchy follows the relation type on its record.
|
|
31010
|
+
const assemblyId = this.item["Assembly.ID"];
|
|
31011
|
+
const root = assemblyId ? { key: "root", AssemblyID: assemblyId } : { key: "root", RootID: this.rootId };
|
|
31012
|
+
const historic = {
|
|
31013
|
+
key: "historic",
|
|
31014
|
+
Historic: { HistoricKey: ((_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey) || undefined }
|
|
31015
|
+
};
|
|
31016
|
+
const query = {
|
|
31017
|
+
[DataLab.EReqKey.Primary]: { Items: [root, historic], Select: { Type: DataLab.ESelectType.Id } }
|
|
31018
|
+
};
|
|
31019
|
+
const load = 1000;
|
|
31020
|
+
try {
|
|
31021
|
+
const ids = [];
|
|
31022
|
+
for (let skip = 0;; skip += load) {
|
|
31023
|
+
const { items } = await DataLab.Run({ api, query, skip, load });
|
|
31024
|
+
ids.push(...(items !== null && items !== void 0 ? items : []));
|
|
31025
|
+
if (!items || items.length < load) {
|
|
31026
|
+
return ids;
|
|
31027
|
+
}
|
|
31028
|
+
}
|
|
31029
|
+
}
|
|
31030
|
+
catch (e) {
|
|
31031
|
+
// An API without the historic criterion gets asked about every node, as before it existed.
|
|
31032
|
+
console.warn("AssemblyRenderManager.historicEntityIds()", e);
|
|
31033
|
+
}
|
|
31034
|
+
return Object.keys((_b = this.hierarchyNodeByEntityId) !== null && _b !== void 0 ? _b : { [this.rootId]: null });
|
|
31035
|
+
}
|
|
31036
|
+
/**
|
|
31037
|
+
* Builds a matrix from the row-major rows that Bruce/AssemblyPosition and AssemblyWorldPosition use.
|
|
31038
|
+
* @param rows
|
|
31039
|
+
*/
|
|
31040
|
+
static MatrixFromRows(rows) {
|
|
31041
|
+
if (!Array.isArray(rows) || rows.length !== 4 || rows.some(r => !Array.isArray(r) || r.length !== 4)) {
|
|
31042
|
+
return null;
|
|
31043
|
+
}
|
|
31044
|
+
return new Matrix4(+rows[0][0], +rows[0][1], +rows[0][2], +rows[0][3], +rows[1][0], +rows[1][1], +rows[1][2], +rows[1][3], +rows[2][0], +rows[2][1], +rows[2][2], +rows[2][3], +rows[3][0], +rows[3][1], +rows[3][2], +rows[3][3]);
|
|
31045
|
+
}
|
|
31046
|
+
/**
|
|
31047
|
+
* The inverse of MatrixFromRows.
|
|
31048
|
+
* @param matrix
|
|
31049
|
+
*/
|
|
31050
|
+
static RowsFromMatrix(matrix) {
|
|
31051
|
+
const rows = [];
|
|
31052
|
+
for (let r = 0; r < 4; r++) {
|
|
31053
|
+
const row = Matrix4.getRow(matrix, r, new Cartesian4());
|
|
31054
|
+
rows.push([row.x, row.y, row.z, row.w]);
|
|
31055
|
+
}
|
|
31056
|
+
return rows;
|
|
29402
31057
|
}
|
|
29403
31058
|
Init() {
|
|
29404
31059
|
this.renderPriority = this.item.renderPriority;
|
|
@@ -29406,6 +31061,7 @@ var AssemblyRenderManager;
|
|
|
29406
31061
|
this.renderPriority = 1;
|
|
29407
31062
|
}
|
|
29408
31063
|
(async () => {
|
|
31064
|
+
var _a, _b;
|
|
29409
31065
|
if (this.disposed) {
|
|
29410
31066
|
return;
|
|
29411
31067
|
}
|
|
@@ -29421,6 +31077,8 @@ var AssemblyRenderManager;
|
|
|
29421
31077
|
this.hierarchyUpdate.Trigger(hierarchy);
|
|
29422
31078
|
// Build hierarchy node cache for quick lookups
|
|
29423
31079
|
this.buildHierarchyNodes(hierarchy);
|
|
31080
|
+
// A set for membership, since searching the list took minutes at 200k nodes.
|
|
31081
|
+
const seenIds = new Set();
|
|
29424
31082
|
const traverseHierarchy = (node, leavesOnly) => {
|
|
29425
31083
|
var _a;
|
|
29426
31084
|
if (node.Children) {
|
|
@@ -29429,7 +31087,8 @@ var AssemblyRenderManager;
|
|
|
29429
31087
|
}
|
|
29430
31088
|
}
|
|
29431
31089
|
const addNode = !leavesOnly || !((_a = node.Children) === null || _a === void 0 ? void 0 : _a.length);
|
|
29432
|
-
if (addNode && node.ID && !
|
|
31090
|
+
if (addNode && node.ID && !seenIds.has(node.ID)) {
|
|
31091
|
+
seenIds.add(node.ID);
|
|
29433
31092
|
flatEntityIds.push(node.ID);
|
|
29434
31093
|
}
|
|
29435
31094
|
};
|
|
@@ -29448,17 +31107,17 @@ var AssemblyRenderManager;
|
|
|
29448
31107
|
}
|
|
29449
31108
|
}
|
|
29450
31109
|
this.rootId = rootId;
|
|
31110
|
+
this.simulationRemoval = (_b = (_a = this.simulation) === null || _a === void 0 ? void 0 : _a.OnChanged.Subscribe((change) => this.onSimulationChanged(change))) !== null && _b !== void 0 ? _b : null;
|
|
29451
31111
|
if (this.disposed) {
|
|
29452
31112
|
return;
|
|
29453
31113
|
}
|
|
29454
31114
|
else if (flatEntityIds.length === 0) {
|
|
29455
31115
|
return;
|
|
29456
31116
|
}
|
|
31117
|
+
// Followed while the parts load: in a large Assembly loading takes far longer than anyone waits.
|
|
31118
|
+
const following = this.viewerDateTimeSub();
|
|
29457
31119
|
await this.processEntityIds(flatEntityIds);
|
|
29458
|
-
|
|
29459
|
-
return;
|
|
29460
|
-
}
|
|
29461
|
-
this.viewerDateTimeSub();
|
|
31120
|
+
await following;
|
|
29462
31121
|
}
|
|
29463
31122
|
catch (e) {
|
|
29464
31123
|
console.error("AssemblyRenderManager.Manager.Init()", e);
|
|
@@ -29485,7 +31144,7 @@ var AssemblyRenderManager;
|
|
|
29485
31144
|
if (!batch.length) {
|
|
29486
31145
|
continue;
|
|
29487
31146
|
}
|
|
29488
|
-
const { entities:
|
|
31147
|
+
const { entities: apiEntities } = await Entity$1.GetListByIds({
|
|
29489
31148
|
entityIds: batch,
|
|
29490
31149
|
api: this.getters.GetBruceApi(),
|
|
29491
31150
|
expandLODs: true,
|
|
@@ -29497,6 +31156,16 @@ var AssemblyRenderManager;
|
|
|
29497
31156
|
if (this.disposed) {
|
|
29498
31157
|
return;
|
|
29499
31158
|
}
|
|
31159
|
+
const fetched = apiEntities.map((entity) => {
|
|
31160
|
+
var _a;
|
|
31161
|
+
this.apiEntities.set((_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID, entity);
|
|
31162
|
+
return this.withSimulation(entity);
|
|
31163
|
+
});
|
|
31164
|
+
for (const entity of fetched) {
|
|
31165
|
+
this.absorbNode(entity);
|
|
31166
|
+
}
|
|
31167
|
+
// Placements already worked out did not know about this batch's positions.
|
|
31168
|
+
this.pose = null;
|
|
29500
31169
|
for (const entity of fetched) {
|
|
29501
31170
|
// Filter for valid LODs then take the highest quality one (lowest level).
|
|
29502
31171
|
let lods = entity.Bruce.LOD || [];
|
|
@@ -29519,57 +31188,46 @@ var AssemblyRenderManager;
|
|
|
29519
31188
|
// Won't bother with vector data for this experiment.
|
|
29520
31189
|
continue;
|
|
29521
31190
|
}
|
|
29522
|
-
const
|
|
29523
|
-
|
|
29524
|
-
|
|
29525
|
-
|
|
29526
|
-
|
|
29527
|
-
returnHeightRef: HeightReference.NONE,
|
|
29528
|
-
allowRendered: false
|
|
29529
|
-
});
|
|
29530
|
-
if (!recordPos3d) {
|
|
31191
|
+
const entityId = entity.Bruce.ID;
|
|
31192
|
+
this.measureGroundOffset(entity);
|
|
31193
|
+
// A placement cached before the offset was known would leave the part off its ground.
|
|
31194
|
+
(_a = this.pose) === null || _a === void 0 ? void 0 : _a.placements.delete(entityId);
|
|
31195
|
+
if (!this.canMove(entityId) && !this.placementAt(entityId, this.viewer.clock.currentTime)) {
|
|
29531
31196
|
continue;
|
|
29532
31197
|
}
|
|
29533
|
-
const entityId = entity.Bruce.ID;
|
|
29534
|
-
if (entityId === this.rootId || !this.rootPos3d) {
|
|
29535
|
-
// Nothing has a frame to be relative to until the root has one.
|
|
29536
|
-
this.rootPos3d = recordPos3d;
|
|
29537
|
-
this.rootHeading = EnsureNumber((_a = entity.Bruce.Transform) === null || _a === void 0 ? void 0 : _a.heading, 0);
|
|
29538
|
-
}
|
|
29539
|
-
// Held as an offset in the root's frame, so a root move places it again without
|
|
29540
|
-
// anything being fetched. Where the root already moved, that is where it goes.
|
|
29541
|
-
const offset = Manager.ChildOffsetIn(this.rootPos3d, this.rootHeading, recordPos3d);
|
|
29542
|
-
const pos3d = Manager.ChildPositionFrom(this.rootPos3d, this.rootHeading, offset);
|
|
29543
|
-
// Optional: a child with no world matrix is still worth drawing, it just has no
|
|
29544
|
-
// orientation of its own to apply.
|
|
29545
|
-
const orient = EntityUtils.GetAssemblyOrientation(entity, pos3d);
|
|
29546
31198
|
const cEntity = this.viewer.entities.add({
|
|
29547
31199
|
model: {
|
|
29548
31200
|
uri: lod["ClientFile"].URL,
|
|
29549
31201
|
...ViewUtils.DefaultLightingProps(),
|
|
29550
31202
|
heightReference: HeightReference.NONE
|
|
29551
|
-
}
|
|
29552
|
-
position: pos3d,
|
|
29553
|
-
orientation: orient ? new ConstantProperty(orient) : undefined
|
|
31203
|
+
}
|
|
29554
31204
|
});
|
|
29555
31205
|
const prior = this.children.get(entityId);
|
|
29556
31206
|
if (prior && prior.cEntity !== cEntity) {
|
|
29557
31207
|
RemoveCEntityFromScene(this.viewer, prior.cEntity);
|
|
29558
31208
|
}
|
|
29559
|
-
|
|
31209
|
+
const child = {
|
|
29560
31210
|
entityId: entityId,
|
|
29561
31211
|
entity: entity,
|
|
29562
|
-
cEntity: cEntity
|
|
29563
|
-
|
|
29564
|
-
|
|
31212
|
+
cEntity: cEntity
|
|
31213
|
+
};
|
|
31214
|
+
this.children.set(entityId, child);
|
|
31215
|
+
// Joins the animated set by its own ancestry, so a late part never re-walks the rest.
|
|
31216
|
+
if (this.hasAnimatedAncestry(entityId)) {
|
|
31217
|
+
this.animatedIds.add(entityId);
|
|
31218
|
+
}
|
|
29565
31219
|
const geometryRadius = Entity$1.GetValue({
|
|
29566
31220
|
entity: entity,
|
|
29567
31221
|
path: ["Bruce", "GeometryRadius"]
|
|
29568
31222
|
});
|
|
29569
31223
|
cEntity.model["_radius"] = geometryRadius;
|
|
29570
31224
|
cEntity.model["_radiusLoaded"] = true;
|
|
31225
|
+
// Placed before it is registered, so the register never measures a visual with no position.
|
|
31226
|
+
this.bindPlacement(child);
|
|
29571
31227
|
this.visualsManager.AddRego({
|
|
29572
31228
|
rego: {
|
|
31229
|
+
moving: child.moving ? true : null,
|
|
31230
|
+
motion: (time) => this.motionAt(entity.Bruce.ID, time),
|
|
29573
31231
|
canEdit: true,
|
|
29574
31232
|
entityId: entity.Bruce.ID,
|
|
29575
31233
|
menuItemId: this.item.id,
|
|
@@ -29589,47 +31247,89 @@ var AssemblyRenderManager;
|
|
|
29589
31247
|
}
|
|
29590
31248
|
}
|
|
29591
31249
|
/*
|
|
29592
|
-
* Follows the scene clock
|
|
29593
|
-
* Only the root is fetched: everything under it is placed through ApplyRootPosition.
|
|
31250
|
+
* Follows the scene clock, moving the Assembly along the root's history and each joint along its own.
|
|
29594
31251
|
*/
|
|
29595
|
-
viewerDateTimeSub() {
|
|
29596
|
-
|
|
31252
|
+
async viewerDateTimeSub() {
|
|
31253
|
+
var _a;
|
|
31254
|
+
const historic = Manager.IsHistoric(this.item);
|
|
31255
|
+
if (this.followingClock || !this.rootId || (!historic && !this.simulatedNodeIds().length)) {
|
|
29597
31256
|
return;
|
|
29598
31257
|
}
|
|
31258
|
+
this.followingClock = true;
|
|
29599
31259
|
const api = this.getters.GetBruceApi();
|
|
29600
|
-
const
|
|
31260
|
+
const historicIds = historic ? await this.historicEntityIds(api) : [];
|
|
31261
|
+
if (this.disposed) {
|
|
31262
|
+
return;
|
|
31263
|
+
}
|
|
31264
|
+
const attrKey = (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey;
|
|
29601
31265
|
const recordHeightRef = Manager.GetRecordHeightRef(this.item);
|
|
29602
31266
|
const toPosses = (records) => {
|
|
29603
31267
|
return CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(this.viewer, recordHeightRef, HeightReference.NONE, records);
|
|
29604
31268
|
};
|
|
29605
|
-
|
|
29606
|
-
|
|
29607
|
-
|
|
29608
|
-
|
|
29609
|
-
|
|
29610
|
-
|
|
29611
|
-
|
|
29612
|
-
|
|
29613
|
-
|
|
29614
|
-
|
|
31269
|
+
if (historicIds.length) {
|
|
31270
|
+
this.historicGatherer = new HistoricGatherer({
|
|
31271
|
+
viewer: this.viewer,
|
|
31272
|
+
getApi: () => api,
|
|
31273
|
+
getAttrKey: () => attrKey,
|
|
31274
|
+
// For clock desync between whatever wrote the record and this client.
|
|
31275
|
+
paddingMs: 15000,
|
|
31276
|
+
simulation: this.simulation,
|
|
31277
|
+
onRecords: (recordsByIds) => {
|
|
31278
|
+
var _a;
|
|
31279
|
+
const records = recordsByIds[this.rootId];
|
|
31280
|
+
if (records === null || records === void 0 ? void 0 : records.length) {
|
|
31281
|
+
const posses = toPosses(records);
|
|
31282
|
+
(_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.SupplementSeries(posses);
|
|
31283
|
+
const moved = this.absorbRootRecords(posses, false);
|
|
31284
|
+
if (this.absorbRootAttitude(records, false) || moved) {
|
|
31285
|
+
this.repose();
|
|
31286
|
+
}
|
|
31287
|
+
}
|
|
31288
|
+
// Joint records go in together once the gather lands, so parents never draw apart from children.
|
|
29615
31289
|
}
|
|
29616
|
-
}
|
|
29617
|
-
}
|
|
31290
|
+
});
|
|
31291
|
+
}
|
|
31292
|
+
// The nodes with history: what the API has records for, and whatever has been simulated since.
|
|
31293
|
+
const nodes = () => Array.from(new Set([...historicIds, ...this.simulatedNodeIds()]));
|
|
29618
31294
|
let gathering = false;
|
|
29619
|
-
|
|
31295
|
+
// Set when what is held changed without a fetch, eg. a simulated record arriving.
|
|
31296
|
+
let stale = true;
|
|
31297
|
+
const gather = async (force) => {
|
|
31298
|
+
var _a, _b;
|
|
31299
|
+
stale = stale || Boolean(force);
|
|
29620
31300
|
if (this.disposed || gathering) {
|
|
29621
31301
|
return;
|
|
29622
31302
|
}
|
|
29623
31303
|
gathering = true;
|
|
29624
31304
|
try {
|
|
29625
|
-
const
|
|
31305
|
+
const ids = nodes();
|
|
31306
|
+
let fetched = false;
|
|
31307
|
+
let recordsByIds;
|
|
31308
|
+
if (this.historicGatherer) {
|
|
31309
|
+
({ fetched, recordsByIds } = await this.historicGatherer.Gather(ids.map(id => ({ Bruce: { ID: id } }))));
|
|
31310
|
+
}
|
|
31311
|
+
else {
|
|
31312
|
+
recordsByIds = (_b = (_a = this.simulation) === null || _a === void 0 ? void 0 : _a.MergeRecords({}, attrKey, ids)) !== null && _b !== void 0 ? _b : {};
|
|
31313
|
+
}
|
|
29626
31314
|
if (this.disposed) {
|
|
29627
31315
|
return;
|
|
29628
31316
|
}
|
|
31317
|
+
// A gather served from what is held changes nothing and runs every tick, so it stops here.
|
|
31318
|
+
if (!fetched && !stale && this.jointSeries.size) {
|
|
31319
|
+
return;
|
|
31320
|
+
}
|
|
31321
|
+
stale = false;
|
|
31322
|
+
let changed = this.absorbJointRecords(recordsByIds);
|
|
29629
31323
|
const posses = toPosses(recordsByIds[this.rootId] || []);
|
|
31324
|
+
changed = this.absorbRootRecords(posses, true) || changed;
|
|
31325
|
+
changed = this.absorbRootAttitude(recordsByIds[this.rootId] || [], true) || changed;
|
|
31326
|
+
if (changed) {
|
|
31327
|
+
this.repose();
|
|
31328
|
+
}
|
|
29630
31329
|
if (!posses.length) {
|
|
29631
31330
|
return;
|
|
29632
31331
|
}
|
|
31332
|
+
// Held for the trail alone; where the root is drawn comes from rootAt(), never from its smoothing.
|
|
29633
31333
|
if (!this.historicAnimation) {
|
|
29634
31334
|
this.historicAnimation = new CesiumAnimatedProperty.AnimatePositionSeries({
|
|
29635
31335
|
posses: posses,
|
|
@@ -29643,15 +31343,21 @@ var AssemblyRenderManager;
|
|
|
29643
31343
|
}
|
|
29644
31344
|
catch (e) {
|
|
29645
31345
|
console.error("AssemblyRenderManager.viewerDateTimeSub()", e);
|
|
31346
|
+
// A gather that throws would throw again straight away, so the retry waits for the next tick.
|
|
31347
|
+
stale = false;
|
|
29646
31348
|
}
|
|
29647
31349
|
finally {
|
|
29648
31350
|
gathering = false;
|
|
31351
|
+
// A change that landed mid-gather is not left for a tick that may never come on a paused clock.
|
|
31352
|
+
if (stale && !this.disposed) {
|
|
31353
|
+
gather();
|
|
31354
|
+
}
|
|
29649
31355
|
}
|
|
29650
31356
|
};
|
|
31357
|
+
this.regather = gather;
|
|
29651
31358
|
gather();
|
|
29652
31359
|
let lastTime = null;
|
|
29653
31360
|
const tickRemoval = this.viewer.clock.onTick.addEventListener(() => {
|
|
29654
|
-
var _a;
|
|
29655
31361
|
if (this.disposed) {
|
|
29656
31362
|
return;
|
|
29657
31363
|
}
|
|
@@ -29661,15 +31367,9 @@ var AssemblyRenderManager;
|
|
|
29661
31367
|
}
|
|
29662
31368
|
lastTime = now;
|
|
29663
31369
|
gather();
|
|
29664
|
-
|
|
29665
|
-
|
|
29666
|
-
|
|
29667
|
-
const pos3d = this.historicAnimation.GetValue();
|
|
29668
|
-
if (pos3d) {
|
|
29669
|
-
this.ApplyRootPosition({
|
|
29670
|
-
pos3d: pos3d,
|
|
29671
|
-
heading: (_a = this.historicAnimation.GetHeadingDegrees()) !== null && _a !== void 0 ? _a : this.rootHeading
|
|
29672
|
-
});
|
|
31370
|
+
// Moving parts read the clock themselves when drawn, so the scene only needs a new frame.
|
|
31371
|
+
if (this.rootSeries.length || this.rootAttitude.length || this.animatedIds.size) {
|
|
31372
|
+
this.viewer.scene.requestRender();
|
|
29673
31373
|
}
|
|
29674
31374
|
});
|
|
29675
31375
|
this.viewerDateTimeChangeRemoval = () => {
|
|
@@ -29678,6 +31378,10 @@ var AssemblyRenderManager;
|
|
|
29678
31378
|
(_a = this.historicGatherer) === null || _a === void 0 ? void 0 : _a.Dispose();
|
|
29679
31379
|
this.historicGatherer = null;
|
|
29680
31380
|
this.historicAnimation = null;
|
|
31381
|
+
this.regather = null;
|
|
31382
|
+
this.rootSeries = [];
|
|
31383
|
+
this.rootAttitude = [];
|
|
31384
|
+
this.pose = null;
|
|
29681
31385
|
};
|
|
29682
31386
|
}
|
|
29683
31387
|
/*
|
|
@@ -29685,7 +31389,7 @@ var AssemblyRenderManager;
|
|
|
29685
31389
|
*/
|
|
29686
31390
|
applyRootTrack() {
|
|
29687
31391
|
var _a;
|
|
29688
|
-
if (!this.item.historicDrawTrack || !this.historicAnimation || this.
|
|
31392
|
+
if (!this.item.historicDrawTrack || !this.historicAnimation || this.trail) {
|
|
29689
31393
|
return;
|
|
29690
31394
|
}
|
|
29691
31395
|
const trackStyle = EntityRenderEngine.GetTrackStyle({
|
|
@@ -29695,41 +31399,35 @@ var AssemblyRenderManager;
|
|
|
29695
31399
|
if (!trackStyle) {
|
|
29696
31400
|
return;
|
|
29697
31401
|
}
|
|
29698
|
-
this.
|
|
29699
|
-
id: ObjectUtils.UId(15),
|
|
29700
|
-
polyline: {
|
|
29701
|
-
positions: new CallbackProperty(() => { var _a, _b; return (_b = (_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.GetSeries()) !== null && _b !== void 0 ? _b : []; }, false),
|
|
29702
|
-
width: trackStyle.width,
|
|
29703
|
-
material: trackStyle.color,
|
|
29704
|
-
clampToGround: EntityRenderEngine.GetHeightRefPolyline(Manager.GetRecordHeightRef(this.item))
|
|
29705
|
-
== HeightReference.CLAMP_TO_GROUND,
|
|
29706
|
-
zIndex: 0,
|
|
29707
|
-
classificationType: ClassificationType.BOTH
|
|
29708
|
-
}
|
|
29709
|
-
});
|
|
29710
|
-
this.trackEntity._noEdit = true;
|
|
29711
|
-
this.trackEntity._noSelect = true;
|
|
29712
|
-
CesiumEntityStyler.SetDefaultColor({
|
|
29713
|
-
color: trackStyle.color,
|
|
29714
|
-
entity: this.trackEntity,
|
|
31402
|
+
this.trail = new HistoricTrail.Trail({
|
|
29715
31403
|
viewer: this.viewer,
|
|
29716
|
-
|
|
29717
|
-
|
|
31404
|
+
color: trackStyle.color,
|
|
31405
|
+
width: trackStyle.width,
|
|
31406
|
+
clampToGround: EntityRenderEngine.GetHeightRefPolyline(Manager.GetRecordHeightRef(this.item))
|
|
31407
|
+
== HeightReference.CLAMP_TO_GROUND,
|
|
31408
|
+
getSeries: () => { var _a, _b; return (_b = (_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.GetSeries()) !== null && _b !== void 0 ? _b : []; },
|
|
31409
|
+
trailSeconds: HistoricTrail.GetTrailSeconds(this.item),
|
|
31410
|
+
// Where the root is drawn, so the trail ends on the model; nothing before the first record held.
|
|
31411
|
+
positionAt: (timeMs) => (this.rootSeries.length && timeMs >= this.rootSeries[0].timeMs ? this.rootPositionAt(timeMs) : null)
|
|
29718
31412
|
});
|
|
29719
31413
|
}
|
|
29720
31414
|
Dispose() {
|
|
29721
|
-
var _a;
|
|
31415
|
+
var _a, _b, _c;
|
|
29722
31416
|
if (this.disposed) {
|
|
29723
31417
|
return;
|
|
29724
31418
|
}
|
|
29725
31419
|
this.disposed = true;
|
|
29726
31420
|
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
29727
31421
|
this.viewerDateTimeChangeRemoval = null;
|
|
29728
|
-
|
|
29729
|
-
|
|
29730
|
-
|
|
29731
|
-
|
|
31422
|
+
(_b = this.simulationRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
31423
|
+
this.simulationRemoval = null;
|
|
31424
|
+
this.apiEntities.clear();
|
|
31425
|
+
(_c = this.trail) === null || _c === void 0 ? void 0 : _c.Dispose();
|
|
31426
|
+
this.trail = null;
|
|
29732
31427
|
this.children.clear();
|
|
31428
|
+
this.localPositions.clear();
|
|
31429
|
+
this.jointSeries.clear();
|
|
31430
|
+
this.animatedIds.clear();
|
|
29733
31431
|
this.visualsManager.RemoveRegos({
|
|
29734
31432
|
menuItemId: this.item.id
|
|
29735
31433
|
});
|
|
@@ -29952,6 +31650,153 @@ var AssemblyRenderManager;
|
|
|
29952
31650
|
AssemblyRenderManager.Manager = Manager;
|
|
29953
31651
|
})(AssemblyRenderManager || (AssemblyRenderManager = {}));
|
|
29954
31652
|
|
|
31653
|
+
/**
|
|
31654
|
+
* Reads and picks between a menu item's ordered styles, writing the pick to the single field renderers read.
|
|
31655
|
+
*/
|
|
31656
|
+
var MenuItemStyles;
|
|
31657
|
+
(function (MenuItemStyles) {
|
|
31658
|
+
// Tileset items whose render manager applies styleId through a Styler.
|
|
31659
|
+
const TILESET_TYPES = [
|
|
31660
|
+
MenuItem.EType.CadTileset,
|
|
31661
|
+
MenuItem.EType.ArbTileset,
|
|
31662
|
+
MenuItem.EType.IonTileset,
|
|
31663
|
+
MenuItem.EType.EntityTileset
|
|
31664
|
+
];
|
|
31665
|
+
// Items whose style lives on their zoom control rows.
|
|
31666
|
+
const ZOOM_CONTROL_TYPES = [
|
|
31667
|
+
MenuItem.EType.Entities,
|
|
31668
|
+
MenuItem.EType.Entity,
|
|
31669
|
+
MenuItem.EType.EntitiesIds,
|
|
31670
|
+
MenuItem.EType.EntitiesLoaded,
|
|
31671
|
+
MenuItem.EType.DataLab
|
|
31672
|
+
];
|
|
31673
|
+
/**
|
|
31674
|
+
* Returns the ordered styles a user can swap between for the item, or an empty array when it offers no choice.
|
|
31675
|
+
*/
|
|
31676
|
+
function GetStyleIds(item) {
|
|
31677
|
+
var _a;
|
|
31678
|
+
if (isStyledTileset(item)) {
|
|
31679
|
+
return cleanIds(item.styleIds);
|
|
31680
|
+
}
|
|
31681
|
+
if (ZOOM_CONTROL_TYPES.includes(item === null || item === void 0 ? void 0 : item.Type)) {
|
|
31682
|
+
return cleanIds((_a = getVisibleRow(item.CameraZoomSettings)) === null || _a === void 0 ? void 0 : _a.StyleIDs);
|
|
31683
|
+
}
|
|
31684
|
+
return [];
|
|
31685
|
+
}
|
|
31686
|
+
MenuItemStyles.GetStyleIds = GetStyleIds;
|
|
31687
|
+
/**
|
|
31688
|
+
* Returns the style the item currently renders with, from styleId or its one non-hidden zoom row.
|
|
31689
|
+
*/
|
|
31690
|
+
function GetStyleId(item) {
|
|
31691
|
+
var _a;
|
|
31692
|
+
if (TILESET_TYPES.includes(item === null || item === void 0 ? void 0 : item.Type)) {
|
|
31693
|
+
return item.styleId;
|
|
31694
|
+
}
|
|
31695
|
+
if (ZOOM_CONTROL_TYPES.includes(item === null || item === void 0 ? void 0 : item.Type)) {
|
|
31696
|
+
return (_a = getVisibleRow(item.CameraZoomSettings)) === null || _a === void 0 ? void 0 : _a.StyleID;
|
|
31697
|
+
}
|
|
31698
|
+
return undefined;
|
|
31699
|
+
}
|
|
31700
|
+
MenuItemStyles.GetStyleId = GetStyleId;
|
|
31701
|
+
/**
|
|
31702
|
+
* Returns a copy of the item rendering with the given style, or null when that style is not one of its options.
|
|
31703
|
+
*/
|
|
31704
|
+
function WithStyleId(item, styleId) {
|
|
31705
|
+
const styleIds = GetStyleIds(item);
|
|
31706
|
+
const picked = styleIds.find(x => isSameId(x, styleId));
|
|
31707
|
+
if (picked == null) {
|
|
31708
|
+
return null;
|
|
31709
|
+
}
|
|
31710
|
+
if (isStyledTileset(item)) {
|
|
31711
|
+
return { ...item, styleId: picked };
|
|
31712
|
+
}
|
|
31713
|
+
const zItem = item;
|
|
31714
|
+
const visible = getVisibleRow(zItem.CameraZoomSettings);
|
|
31715
|
+
return {
|
|
31716
|
+
...zItem,
|
|
31717
|
+
CameraZoomSettings: zItem.CameraZoomSettings.map(row => {
|
|
31718
|
+
if (row !== visible) {
|
|
31719
|
+
return row;
|
|
31720
|
+
}
|
|
31721
|
+
// An inline style would win over the picked ID.
|
|
31722
|
+
const next = { ...row, StyleID: picked };
|
|
31723
|
+
delete next.Style;
|
|
31724
|
+
return next;
|
|
31725
|
+
})
|
|
31726
|
+
};
|
|
31727
|
+
}
|
|
31728
|
+
MenuItemStyles.WithStyleId = WithStyleId;
|
|
31729
|
+
/**
|
|
31730
|
+
* Returns the item on the first of its styles unless it already uses one, or the same object when it has none.
|
|
31731
|
+
*/
|
|
31732
|
+
function Resolve(item) {
|
|
31733
|
+
var _a;
|
|
31734
|
+
const styleIds = GetStyleIds(item);
|
|
31735
|
+
if (!styleIds.length) {
|
|
31736
|
+
return item;
|
|
31737
|
+
}
|
|
31738
|
+
const current = GetStyleId(item);
|
|
31739
|
+
if (current != null && styleIds.some(x => isSameId(x, current))) {
|
|
31740
|
+
return item;
|
|
31741
|
+
}
|
|
31742
|
+
return (_a = WithStyleId(item, styleIds[0])) !== null && _a !== void 0 ? _a : item;
|
|
31743
|
+
}
|
|
31744
|
+
MenuItemStyles.Resolve = Resolve;
|
|
31745
|
+
/**
|
|
31746
|
+
* Returns a copy on the style a bookmark alternation picked, or the item itself when that is not an option.
|
|
31747
|
+
*/
|
|
31748
|
+
function ApplyAlternation(item, alternation) {
|
|
31749
|
+
var _a, _b, _c;
|
|
31750
|
+
// Alternations are partial items and may carry no Type, so the pick is read from whichever field is present.
|
|
31751
|
+
const alt = alternation;
|
|
31752
|
+
const picked = (_a = alt === null || alt === void 0 ? void 0 : alt.styleId) !== null && _a !== void 0 ? _a : (_b = getVisibleRow(alt === null || alt === void 0 ? void 0 : alt.CameraZoomSettings)) === null || _b === void 0 ? void 0 : _b.StyleID;
|
|
31753
|
+
if (picked == null) {
|
|
31754
|
+
return item;
|
|
31755
|
+
}
|
|
31756
|
+
return (_c = WithStyleId(item, picked)) !== null && _c !== void 0 ? _c : item;
|
|
31757
|
+
}
|
|
31758
|
+
MenuItemStyles.ApplyAlternation = ApplyAlternation;
|
|
31759
|
+
/**
|
|
31760
|
+
* Returns true when the two items differ by nothing but which of their styles is picked.
|
|
31761
|
+
*/
|
|
31762
|
+
function IsStyleChangeOnly(from, to) {
|
|
31763
|
+
if (!from || !to || from.Type !== to.Type) {
|
|
31764
|
+
return false;
|
|
31765
|
+
}
|
|
31766
|
+
const toStyleId = GetStyleId(to);
|
|
31767
|
+
if (toStyleId == null || isSameId(GetStyleId(from), toStyleId)) {
|
|
31768
|
+
return false;
|
|
31769
|
+
}
|
|
31770
|
+
const moved = WithStyleId(from, toStyleId);
|
|
31771
|
+
// A false mismatch only costs the in-place swap, so key order is not normalized.
|
|
31772
|
+
return Boolean(moved) && JSON.stringify(moved) === JSON.stringify(to);
|
|
31773
|
+
}
|
|
31774
|
+
MenuItemStyles.IsStyleChangeOnly = IsStyleChangeOnly;
|
|
31775
|
+
function isStyledTileset(item) {
|
|
31776
|
+
if (!TILESET_TYPES.includes(item === null || item === void 0 ? void 0 : item.Type)) {
|
|
31777
|
+
return false;
|
|
31778
|
+
}
|
|
31779
|
+
// These two only run a Styler when asked to.
|
|
31780
|
+
if (item.Type === MenuItem.EType.ArbTileset || item.Type === MenuItem.EType.EntityTileset) {
|
|
31781
|
+
return Boolean(item.ApplyStyles);
|
|
31782
|
+
}
|
|
31783
|
+
return true;
|
|
31784
|
+
}
|
|
31785
|
+
function getVisibleRow(rows) {
|
|
31786
|
+
const visible = (rows !== null && rows !== void 0 ? rows : []).filter(x => x && x.DisplayType !== ZoomControl.EDisplayType.Hidden);
|
|
31787
|
+
return visible.length === 1 ? visible[0] : null;
|
|
31788
|
+
}
|
|
31789
|
+
function cleanIds(ids) {
|
|
31790
|
+
return (ids !== null && ids !== void 0 ? ids : []).filter(x => x != null && x !== "");
|
|
31791
|
+
}
|
|
31792
|
+
/*
|
|
31793
|
+
* Compares style references, which can be an ID typed as a string or a number.
|
|
31794
|
+
*/
|
|
31795
|
+
function isSameId(a, b) {
|
|
31796
|
+
return a != null && b != null && String(a) === String(b);
|
|
31797
|
+
}
|
|
31798
|
+
})(MenuItemStyles || (MenuItemStyles = {}));
|
|
31799
|
+
|
|
29955
31800
|
/**
|
|
29956
31801
|
* Util to batch Tileset and Root Entity coord requests between Menu Items.
|
|
29957
31802
|
* This avoids per-menu-item requests and allows for them to request together if enabled within N ms of each other.
|
|
@@ -30187,12 +32032,17 @@ var MenuItemManager;
|
|
|
30187
32032
|
this.OnSeriesUpdated.Trigger({ itemId, segments: [] });
|
|
30188
32033
|
}
|
|
30189
32034
|
}
|
|
32035
|
+
get Simulation() {
|
|
32036
|
+
return this.simulation;
|
|
32037
|
+
}
|
|
30190
32038
|
get Monitor() {
|
|
30191
32039
|
return this.sharedMonitor;
|
|
30192
32040
|
}
|
|
30193
32041
|
constructor(params) {
|
|
30194
32042
|
this.items = [];
|
|
30195
32043
|
this.pendingHandoffPool = [];
|
|
32044
|
+
// The settings bookmark alternations overwrite on a view's items, as that view authored them.
|
|
32045
|
+
this.authoredAlternations = new WeakMap();
|
|
30196
32046
|
this.onUpdate = null;
|
|
30197
32047
|
// Segments discovered so far per menu item ID.
|
|
30198
32048
|
this.seriesSegments = new Map();
|
|
@@ -30212,6 +32062,7 @@ var MenuItemManager;
|
|
|
30212
32062
|
this.visualsRegister = visualsRegister;
|
|
30213
32063
|
this.sharedGetters = new SharedGetters.Cache();
|
|
30214
32064
|
this.sharedHistoric = new SharedHistoricGetters.Cache();
|
|
32065
|
+
this.simulation = EntitySimulation.Get(this.viewer);
|
|
30215
32066
|
this.sharedMonitor = new CesiumViewMonitor.Monitor(this.viewer);
|
|
30216
32067
|
this.tilesetInitQueue = new InitQueueTileset(this.getters);
|
|
30217
32068
|
}
|
|
@@ -30247,7 +32098,7 @@ var MenuItemManager;
|
|
|
30247
32098
|
* @returns
|
|
30248
32099
|
*/
|
|
30249
32100
|
RenderItem(params) {
|
|
30250
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
32101
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
30251
32102
|
if (this.viewer.isDestroyed()) {
|
|
30252
32103
|
return null;
|
|
30253
32104
|
}
|
|
@@ -30271,13 +32122,21 @@ var MenuItemManager;
|
|
|
30271
32122
|
if (params.modelSpace == null) {
|
|
30272
32123
|
params.modelSpace = false;
|
|
30273
32124
|
}
|
|
32125
|
+
// An item with a style set renders its first style unless the caller already picked one of them.
|
|
32126
|
+
params = { ...params, item: MenuItemStyles.Resolve(params.item) };
|
|
30274
32127
|
let rItem = this.items.find(x => x.id == params.item.id);
|
|
30275
32128
|
let create = true;
|
|
30276
32129
|
// Item already exists so we'll check if we should re-create it.
|
|
30277
32130
|
if (rItem) {
|
|
32131
|
+
// Only the picked style changed, so what is drawn gets restyled rather than rebuilt.
|
|
32132
|
+
if (MenuItemStyles.IsStyleChangeOnly(rItem.item, params.item) && this.isStyleSwapCapable(rItem.renderManager)) {
|
|
32133
|
+
rItem.renderManager.SwapStyle(params.item);
|
|
32134
|
+
rItem.item = params.item;
|
|
32135
|
+
create = false;
|
|
32136
|
+
}
|
|
30278
32137
|
// This means we're updating an entities menu item re-using the same id.
|
|
30279
32138
|
// Eg: a bookmark swap that keeps the same item but changes tags, style, or zoom settings.
|
|
30280
|
-
if (rItem.type == MenuItem.EType.Entities && params.item.Type == MenuItem.EType.Entities) {
|
|
32139
|
+
else if (rItem.type == MenuItem.EType.Entities && params.item.Type == MenuItem.EType.Entities) {
|
|
30281
32140
|
rItem.renderManager.Init({
|
|
30282
32141
|
item: params.item,
|
|
30283
32142
|
});
|
|
@@ -30425,7 +32284,8 @@ var MenuItemManager;
|
|
|
30425
32284
|
monitor: this.sharedMonitor,
|
|
30426
32285
|
item: params.item,
|
|
30427
32286
|
sharedGetters: this.sharedGetters,
|
|
30428
|
-
onSeriesDiscovered: (segment) => this.RecordSeriesSegment(rItem.id, segment)
|
|
32287
|
+
onSeriesDiscovered: (segment) => this.RecordSeriesSegment(rItem.id, segment),
|
|
32288
|
+
simulation: this.simulation
|
|
30429
32289
|
});
|
|
30430
32290
|
break;
|
|
30431
32291
|
case MenuItem.EType.EntitiesLoaded:
|
|
@@ -30434,7 +32294,8 @@ var MenuItemManager;
|
|
|
30434
32294
|
register: this.visualsRegister,
|
|
30435
32295
|
apiGetter: params.apiGetter,
|
|
30436
32296
|
monitor: this.sharedMonitor,
|
|
30437
|
-
item: params.item
|
|
32297
|
+
item: params.item,
|
|
32298
|
+
simulation: this.simulation
|
|
30438
32299
|
});
|
|
30439
32300
|
break;
|
|
30440
32301
|
case MenuItem.EType.EntitiesIds:
|
|
@@ -30444,7 +32305,8 @@ var MenuItemManager;
|
|
|
30444
32305
|
apiGetter: params.apiGetter,
|
|
30445
32306
|
monitor: this.sharedMonitor,
|
|
30446
32307
|
item: params.item,
|
|
30447
|
-
sharedHistoric: this.sharedHistoric
|
|
32308
|
+
sharedHistoric: this.sharedHistoric,
|
|
32309
|
+
simulation: this.simulation
|
|
30448
32310
|
});
|
|
30449
32311
|
break;
|
|
30450
32312
|
case MenuItem.EType.Entity:
|
|
@@ -30453,7 +32315,8 @@ var MenuItemManager;
|
|
|
30453
32315
|
register: this.visualsRegister,
|
|
30454
32316
|
apiGetter: params.apiGetter,
|
|
30455
32317
|
monitor: this.sharedMonitor,
|
|
30456
|
-
item: params.item
|
|
32318
|
+
item: params.item,
|
|
32319
|
+
simulation: this.simulation
|
|
30457
32320
|
});
|
|
30458
32321
|
break;
|
|
30459
32322
|
case MenuItem.EType.CadTileset:
|
|
@@ -30463,7 +32326,8 @@ var MenuItemManager;
|
|
|
30463
32326
|
getters: this.getters,
|
|
30464
32327
|
item: params.item,
|
|
30465
32328
|
modelSpace: params.modelSpace,
|
|
30466
|
-
initQueue: this.tilesetInitQueue
|
|
32329
|
+
initQueue: this.tilesetInitQueue,
|
|
32330
|
+
simulation: this.simulation
|
|
30467
32331
|
});
|
|
30468
32332
|
break;
|
|
30469
32333
|
case MenuItem.EType.Assembly:
|
|
@@ -30473,6 +32337,7 @@ var MenuItemManager;
|
|
|
30473
32337
|
getters: params.getters,
|
|
30474
32338
|
item: params.item,
|
|
30475
32339
|
modelSpace: params.modelSpace,
|
|
32340
|
+
simulation: this.simulation
|
|
30476
32341
|
});
|
|
30477
32342
|
break;
|
|
30478
32343
|
case MenuItem.EType.Osm:
|
|
@@ -30500,7 +32365,8 @@ var MenuItemManager;
|
|
|
30500
32365
|
getters: this.getters,
|
|
30501
32366
|
monitor: this.sharedMonitor,
|
|
30502
32367
|
item: params.item,
|
|
30503
|
-
initQueue: this.tilesetInitQueue
|
|
32368
|
+
initQueue: this.tilesetInitQueue,
|
|
32369
|
+
simulation: this.simulation
|
|
30504
32370
|
});
|
|
30505
32371
|
break;
|
|
30506
32372
|
case MenuItem.EType.Kml:
|
|
@@ -30524,7 +32390,8 @@ var MenuItemManager;
|
|
|
30524
32390
|
getters: params.getters,
|
|
30525
32391
|
item: params.item,
|
|
30526
32392
|
viewer: this.viewer,
|
|
30527
|
-
register: this.visualsRegister
|
|
32393
|
+
register: this.visualsRegister,
|
|
32394
|
+
simulation: this.simulation
|
|
30528
32395
|
});
|
|
30529
32396
|
break;
|
|
30530
32397
|
// Deprecated to support a few demos until new one is phased in.
|
|
@@ -30534,7 +32401,8 @@ var MenuItemManager;
|
|
|
30534
32401
|
apiGetter: params.apiGetter,
|
|
30535
32402
|
item: params.item,
|
|
30536
32403
|
register: this.visualsRegister,
|
|
30537
|
-
viewer: this.viewer
|
|
32404
|
+
viewer: this.viewer,
|
|
32405
|
+
simulation: this.simulation
|
|
30538
32406
|
});
|
|
30539
32407
|
break;
|
|
30540
32408
|
case MenuItem.EType.Relationships:
|
|
@@ -30542,7 +32410,8 @@ var MenuItemManager;
|
|
|
30542
32410
|
apiGetter: params.apiGetter,
|
|
30543
32411
|
item: params.item,
|
|
30544
32412
|
register: this.visualsRegister,
|
|
30545
|
-
viewer: this.viewer
|
|
32413
|
+
viewer: this.viewer,
|
|
32414
|
+
simulation: this.simulation
|
|
30546
32415
|
});
|
|
30547
32416
|
break;
|
|
30548
32417
|
case MenuItem.EType.GooglePhotoTileset:
|
|
@@ -30574,7 +32443,8 @@ var MenuItemManager;
|
|
|
30574
32443
|
item: params.item,
|
|
30575
32444
|
apiGetter: params.apiGetter,
|
|
30576
32445
|
monitor: this.sharedMonitor,
|
|
30577
|
-
visualsRegister: this.visualsRegister
|
|
32446
|
+
visualsRegister: this.visualsRegister,
|
|
32447
|
+
simulation: this.simulation
|
|
30578
32448
|
});
|
|
30579
32449
|
break;
|
|
30580
32450
|
// Any "none" type can be ignored. These are just containers for other items.
|
|
@@ -30601,7 +32471,17 @@ var MenuItemManager;
|
|
|
30601
32471
|
// We no longer support folder items being both a folder and an action.
|
|
30602
32472
|
// Now an item must have no action to be a folder.
|
|
30603
32473
|
const isFolder = !params.item.Type || params.item.Type == MenuItem.EType.None;
|
|
30604
|
-
|
|
32474
|
+
const isRadioFolder = isFolder && Boolean(params.item.childrenAsRadios);
|
|
32475
|
+
if (((_f = params.item.Children) === null || _f === void 0 ? void 0 : _f.length) && params.recursive != false && isRadioFolder) {
|
|
32476
|
+
const picked = this.pickRadioChild(params.item.Children, params.preferredIds);
|
|
32477
|
+
const others = params.item.Children.filter(x => x !== picked && this.items.some(y => y.id === x.id));
|
|
32478
|
+
const childId = this.renderInPlaceOf(others.map(x => x.id), () => this.RenderItem({
|
|
32479
|
+
...params,
|
|
32480
|
+
item: picked
|
|
32481
|
+
}));
|
|
32482
|
+
rItem.childIds = childId ? [childId] : [];
|
|
32483
|
+
}
|
|
32484
|
+
else if (params.item.Children && params.recursive != false && isFolder) {
|
|
30605
32485
|
for (let i = 0; i < params.item.Children.length; i++) {
|
|
30606
32486
|
const childId = this.RenderItem({
|
|
30607
32487
|
...params,
|
|
@@ -30610,8 +32490,8 @@ var MenuItemManager;
|
|
|
30610
32490
|
rItem.childIds.push(childId);
|
|
30611
32491
|
}
|
|
30612
32492
|
}
|
|
30613
|
-
if (rItem.renderManager && !((
|
|
30614
|
-
(
|
|
32493
|
+
if (rItem.renderManager && !((_g = rItem.renderManager) === null || _g === void 0 ? void 0 : _g.Disposed)) {
|
|
32494
|
+
(_h = this.onUpdate) === null || _h === void 0 ? void 0 : _h.Trigger({ isEnabling: true, itemId: rItem.id });
|
|
30615
32495
|
}
|
|
30616
32496
|
return rItem.id;
|
|
30617
32497
|
}
|
|
@@ -30660,9 +32540,74 @@ var MenuItemManager;
|
|
|
30660
32540
|
(_b = this.onUpdate) === null || _b === void 0 ? void 0 : _b.Trigger({ isEnabling: false, itemId: item.id });
|
|
30661
32541
|
}
|
|
30662
32542
|
}
|
|
32543
|
+
/**
|
|
32544
|
+
* Replaces enabled menu items with another, which reuses their graphics where both draw the same data.
|
|
32545
|
+
*/
|
|
32546
|
+
SwapItem(params) {
|
|
32547
|
+
const { fromIds, item, modelSpace } = params;
|
|
32548
|
+
const parents = this.items.filter(x => x.childIds.some(id => fromIds.includes(id)));
|
|
32549
|
+
const id = this.renderInPlaceOf(fromIds, () => this.RenderItem({
|
|
32550
|
+
item,
|
|
32551
|
+
modelSpace
|
|
32552
|
+
}));
|
|
32553
|
+
// Keeps a radio folder's removal reaching the child that replaced its old one.
|
|
32554
|
+
for (const parent of parents) {
|
|
32555
|
+
const kept = parent.childIds.filter(x => !fromIds.includes(x));
|
|
32556
|
+
parent.childIds = id && !kept.includes(id) ? kept.concat(id) : kept;
|
|
32557
|
+
}
|
|
32558
|
+
return id;
|
|
32559
|
+
}
|
|
32560
|
+
/**
|
|
32561
|
+
* Restyles an enabled menu item in place with another of its own styles, returning false when it cannot.
|
|
32562
|
+
*/
|
|
32563
|
+
SetItemStyle(params) {
|
|
32564
|
+
var _a;
|
|
32565
|
+
const { menuItemId, styleId } = params;
|
|
32566
|
+
const rItem = this.items.find(x => x.id === menuItemId);
|
|
32567
|
+
if (!rItem || !this.isStyleSwapCapable(rItem.renderManager) || rItem.renderManager.Disposed) {
|
|
32568
|
+
return false;
|
|
32569
|
+
}
|
|
32570
|
+
const next = MenuItemStyles.WithStyleId(rItem.item, styleId);
|
|
32571
|
+
if (!next) {
|
|
32572
|
+
return false;
|
|
32573
|
+
}
|
|
32574
|
+
rItem.renderManager.SwapStyle(next);
|
|
32575
|
+
rItem.item = next;
|
|
32576
|
+
(_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.Trigger({ isEnabling: true, itemId: rItem.id });
|
|
32577
|
+
return true;
|
|
32578
|
+
}
|
|
32579
|
+
/*
|
|
32580
|
+
* Picks the child the caller asked for, else the one already enabled, else the first.
|
|
32581
|
+
*/
|
|
32582
|
+
pickRadioChild(children, preferredIds) {
|
|
32583
|
+
var _a, _b;
|
|
32584
|
+
return ((_b = (_a = children.find(x => preferredIds === null || preferredIds === void 0 ? void 0 : preferredIds.includes(x.id))) !== null && _a !== void 0 ? _a : children.find(x => this.items.some(y => y.id === x.id))) !== null && _b !== void 0 ? _b : children[0]);
|
|
32585
|
+
}
|
|
32586
|
+
/*
|
|
32587
|
+
* Removes the items so the render can claim their graphics, then disposes whatever it left unclaimed.
|
|
32588
|
+
*/
|
|
32589
|
+
renderInPlaceOf(removeIds, render) {
|
|
32590
|
+
const pooledBefore = new Set(this.pendingHandoffPool);
|
|
32591
|
+
for (const id of removeIds) {
|
|
32592
|
+
this.RemoveItemById({
|
|
32593
|
+
menuItemId: id,
|
|
32594
|
+
allowHandoff: true
|
|
32595
|
+
});
|
|
32596
|
+
}
|
|
32597
|
+
const pooled = this.pendingHandoffPool.filter(x => !pooledBefore.has(x));
|
|
32598
|
+
try {
|
|
32599
|
+
return render();
|
|
32600
|
+
}
|
|
32601
|
+
finally {
|
|
32602
|
+
this.disposePooled(x => pooled.includes(x));
|
|
32603
|
+
}
|
|
32604
|
+
}
|
|
30663
32605
|
isHandoffCapable(renderManager) {
|
|
30664
32606
|
return Boolean(renderManager) && typeof renderManager.PrepareHandoff === "function";
|
|
30665
32607
|
}
|
|
32608
|
+
isStyleSwapCapable(renderManager) {
|
|
32609
|
+
return Boolean(renderManager) && typeof renderManager.SwapStyle === "function";
|
|
32610
|
+
}
|
|
30666
32611
|
// Resolves the hand-off key a menu item's data would have.
|
|
30667
32612
|
computeHandoffKey(item, modelSpace) {
|
|
30668
32613
|
if (item.Type === MenuItem.EType.CadTileset) {
|
|
@@ -30738,12 +32683,15 @@ var MenuItemManager;
|
|
|
30738
32683
|
}
|
|
30739
32684
|
// Disposes everything left unclaimed in the pending-hand-off pool.
|
|
30740
32685
|
FlushPendingHandoffs() {
|
|
32686
|
+
this.disposePooled(() => true);
|
|
32687
|
+
}
|
|
32688
|
+
disposePooled(match) {
|
|
30741
32689
|
var _a;
|
|
30742
32690
|
if (!this.pendingHandoffPool.length) {
|
|
30743
32691
|
return;
|
|
30744
32692
|
}
|
|
30745
|
-
const pool = this.pendingHandoffPool;
|
|
30746
|
-
this.pendingHandoffPool =
|
|
32693
|
+
const pool = this.pendingHandoffPool.filter(match);
|
|
32694
|
+
this.pendingHandoffPool = this.pendingHandoffPool.filter(x => !match(x));
|
|
30747
32695
|
for (const item of pool) {
|
|
30748
32696
|
try {
|
|
30749
32697
|
(_a = item.renderManager) === null || _a === void 0 ? void 0 : _a.Dispose();
|
|
@@ -30754,6 +32702,26 @@ var MenuItemManager;
|
|
|
30754
32702
|
this.ClearSeriesSegments(item.id);
|
|
30755
32703
|
}
|
|
30756
32704
|
}
|
|
32705
|
+
/**
|
|
32706
|
+
* Returns the tags and attenuation the item's view authored, before any bookmark wrote over them.
|
|
32707
|
+
*/
|
|
32708
|
+
GetAuthoredAlternation(item) {
|
|
32709
|
+
var _a;
|
|
32710
|
+
let authored = this.authoredAlternations.get(item);
|
|
32711
|
+
if (!authored) {
|
|
32712
|
+
const eItem = item;
|
|
32713
|
+
const tItem = item;
|
|
32714
|
+
authored = JSON.parse(JSON.stringify({
|
|
32715
|
+
id: item.id,
|
|
32716
|
+
Type: item.Type,
|
|
32717
|
+
BruceEntity: { SelectedExpandLayers: (_a = eItem.BruceEntity) === null || _a === void 0 ? void 0 : _a.SelectedExpandLayers },
|
|
32718
|
+
attenuation: tItem.attenuation,
|
|
32719
|
+
attenuationMax: tItem.attenuationMax
|
|
32720
|
+
}));
|
|
32721
|
+
this.authoredAlternations.set(item, authored);
|
|
32722
|
+
}
|
|
32723
|
+
return authored;
|
|
32724
|
+
}
|
|
30757
32725
|
GetEnabledItemIds() {
|
|
30758
32726
|
return this.items.map(x => x.id);
|
|
30759
32727
|
}
|
|
@@ -30787,6 +32755,63 @@ var MenuItemManager;
|
|
|
30787
32755
|
}
|
|
30788
32756
|
}
|
|
30789
32757
|
}
|
|
32758
|
+
/**
|
|
32759
|
+
* Draws Entities from data given here as well as, or instead of, the API's, until ClearSimulation is called.
|
|
32760
|
+
* @param params.set the simulation this belongs to, so it can be cleared apart from others. Default "default".
|
|
32761
|
+
* @param params.entities stand-ins that replace each Entity's record; API data for them is ignored.
|
|
32762
|
+
* @param params.patches partial Entities laid over each Entity; live API data shows where a patch is silent.
|
|
32763
|
+
* @param params.records historic records naming entityId, dateTime and only the data they change.
|
|
32764
|
+
* @param params.menuItemIds the items to redraw. By default every item already drawing one of the Entities.
|
|
32765
|
+
*/
|
|
32766
|
+
async Simulate(params) {
|
|
32767
|
+
const { set, entities, patches, records, menuItemIds } = params;
|
|
32768
|
+
this.simulation.SetEntities(entities, set);
|
|
32769
|
+
this.simulation.SetPatches(patches, set);
|
|
32770
|
+
this.simulation.SetRecords(records, set);
|
|
32771
|
+
const entityIds = [
|
|
32772
|
+
...(entities || []).map(x => { var _a; return (_a = x === null || x === void 0 ? void 0 : x.Bruce) === null || _a === void 0 ? void 0 : _a.ID; }),
|
|
32773
|
+
...(patches || []).map(x => { var _a; return (_a = x === null || x === void 0 ? void 0 : x.Bruce) === null || _a === void 0 ? void 0 : _a.ID; }),
|
|
32774
|
+
...(records || []).map(x => x === null || x === void 0 ? void 0 : x.entityId)
|
|
32775
|
+
];
|
|
32776
|
+
await this.reRenderSimulated(entityIds, menuItemIds);
|
|
32777
|
+
}
|
|
32778
|
+
/**
|
|
32779
|
+
* Stops simulating these Entities, or every Entity when none are named, and redraws them.
|
|
32780
|
+
* @param params.set the simulation to clear. By default every one.
|
|
32781
|
+
* @param params.entities clear the stand-ins and patches. Default true.
|
|
32782
|
+
* @param params.records clear the historic records. Default true.
|
|
32783
|
+
*/
|
|
32784
|
+
async ClearSimulation(params) {
|
|
32785
|
+
var _a;
|
|
32786
|
+
const entityIds = (_a = params === null || params === void 0 ? void 0 : params.entityIds) !== null && _a !== void 0 ? _a : [
|
|
32787
|
+
...this.simulation.GetEntityIds(),
|
|
32788
|
+
...this.simulation.GetRecordEntityIds()
|
|
32789
|
+
];
|
|
32790
|
+
this.simulation.Clear({ set: params === null || params === void 0 ? void 0 : params.set, entityIds, entities: params === null || params === void 0 ? void 0 : params.entities, records: params === null || params === void 0 ? void 0 : params.records });
|
|
32791
|
+
await this.reRenderSimulated(entityIds, params === null || params === void 0 ? void 0 : params.menuItemIds);
|
|
32792
|
+
}
|
|
32793
|
+
/*
|
|
32794
|
+
* Redraws simulated Entities only in the items holding a visual for them, unless the caller names the items.
|
|
32795
|
+
*/
|
|
32796
|
+
async reRenderSimulated(entityIds, menuItemIds) {
|
|
32797
|
+
const ids = Array.from(new Set(entityIds.filter(x => !!x)));
|
|
32798
|
+
if (!ids.length) {
|
|
32799
|
+
return;
|
|
32800
|
+
}
|
|
32801
|
+
const items = (menuItemIds === null || menuItemIds === void 0 ? void 0 : menuItemIds.length) ? this.items.filter(x => menuItemIds.includes(x.id)) : this.items;
|
|
32802
|
+
for (const item of items) {
|
|
32803
|
+
// Some managers follow the store themselves, and redrawing them here would only repeat that.
|
|
32804
|
+
if (!item.renderManager || item.renderManager.FollowsSimulation) {
|
|
32805
|
+
continue;
|
|
32806
|
+
}
|
|
32807
|
+
const drawn = (menuItemIds === null || menuItemIds === void 0 ? void 0 : menuItemIds.length)
|
|
32808
|
+
? ids
|
|
32809
|
+
: ids.filter(id => this.visualsRegister.GetRego({ entityId: id, menuItemId: item.id }));
|
|
32810
|
+
if (drawn.length) {
|
|
32811
|
+
await item.renderManager.ReRender({ entityIds: drawn, force: true });
|
|
32812
|
+
}
|
|
32813
|
+
}
|
|
32814
|
+
}
|
|
30790
32815
|
}
|
|
30791
32816
|
MenuItemManager.Manager = Manager;
|
|
30792
32817
|
})(MenuItemManager || (MenuItemManager = {}));
|
|
@@ -31771,6 +33796,7 @@ var EMenuItemState;
|
|
|
31771
33796
|
})(EMenuItemState || (EMenuItemState = {}));
|
|
31772
33797
|
// Icons are inline so the library stays dependency free.
|
|
31773
33798
|
const ICON_CHECK = `<svg viewBox="0 0 11 8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 4L4 7L10 1" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
33799
|
+
const ICON_RADIO = `<svg viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" r="3.5" fill="white"/></svg>`;
|
|
31774
33800
|
const ICON_PARTIAL_CHECK = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 12H16" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
31775
33801
|
const ICON_CHEV_DOWN = `<svg viewBox="0 0 16 9" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15 1L8 8L1 1" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
31776
33802
|
const ICON_CHEV_RIGHT = `<svg viewBox="0 0 10 17" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 1.5L8.5 8.5L1.5 15.5" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
@@ -31974,6 +34000,10 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
31974
34000
|
margin-right: 8px;
|
|
31975
34001
|
}
|
|
31976
34002
|
|
|
34003
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowCheckbox[is-radio="true"] {
|
|
34004
|
+
border-radius: 50%;
|
|
34005
|
+
}
|
|
34006
|
+
|
|
31977
34007
|
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowToggle {
|
|
31978
34008
|
margin-right: 3px;
|
|
31979
34009
|
}
|
|
@@ -32224,13 +34254,15 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32224
34254
|
}
|
|
32225
34255
|
return this._waitedForView ? "No view is loaded." : "Loading..";
|
|
32226
34256
|
}
|
|
32227
|
-
_renderRow(item, depth, parent) {
|
|
34257
|
+
_renderRow(item, depth, parent, radioParent) {
|
|
32228
34258
|
var _a;
|
|
32229
34259
|
if (!(item === null || item === void 0 ? void 0 : item.id)) {
|
|
32230
34260
|
return;
|
|
32231
34261
|
}
|
|
32232
34262
|
const isFolder = !item.Type || item.Type === MenuItem.EType.None;
|
|
32233
|
-
const
|
|
34263
|
+
const isRadioFolder = isFolder && Boolean(item.childrenAsRadios);
|
|
34264
|
+
// Radios are the folder's whole point, so they show even when the folder also hides its children.
|
|
34265
|
+
const children = item.hideChildren && !isRadioFolder ? [] : ((_a = item.Children) !== null && _a !== void 0 ? _a : []);
|
|
32234
34266
|
const hasChildren = children.length > 0;
|
|
32235
34267
|
const row = document.createElement("div");
|
|
32236
34268
|
row.className = "NextspaceMenuItemRow";
|
|
@@ -32262,8 +34294,9 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32262
34294
|
}
|
|
32263
34295
|
const checkbox = document.createElement("div");
|
|
32264
34296
|
checkbox.className = "NextspaceMenuItemRowCheckbox";
|
|
34297
|
+
checkbox.setAttribute("is-radio", radioParent ? "true" : "false");
|
|
32265
34298
|
checkbox.onclick = () => {
|
|
32266
|
-
this._toggleItem(item);
|
|
34299
|
+
this._toggleItem(item, radioParent);
|
|
32267
34300
|
};
|
|
32268
34301
|
itemElement.appendChild(checkbox);
|
|
32269
34302
|
const title = document.createElement("div");
|
|
@@ -32313,10 +34346,11 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32313
34346
|
itemElement,
|
|
32314
34347
|
checkboxElement: checkbox,
|
|
32315
34348
|
countElement: count,
|
|
32316
|
-
childrenElement
|
|
34349
|
+
childrenElement,
|
|
34350
|
+
radioParent
|
|
32317
34351
|
});
|
|
32318
34352
|
for (const child of children) {
|
|
32319
|
-
this._renderRow(child, depth + 1, childrenElement);
|
|
34353
|
+
this._renderRow(child, depth + 1, childrenElement, isRadioFolder ? item : undefined);
|
|
32320
34354
|
}
|
|
32321
34355
|
}
|
|
32322
34356
|
_getOpen(itemId, depth) {
|
|
@@ -32351,7 +34385,10 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32351
34385
|
for (const row of Array.from(this._rows.values())) {
|
|
32352
34386
|
const state = this._resolveState(row.item, enabledIds);
|
|
32353
34387
|
row.itemElement.setAttribute("is-enabled", state === EMenuItemState.Disabled ? "false" : "true");
|
|
32354
|
-
if (state
|
|
34388
|
+
if (row.radioParent && state !== EMenuItemState.Disabled) {
|
|
34389
|
+
row.checkboxElement.innerHTML = ICON_RADIO;
|
|
34390
|
+
}
|
|
34391
|
+
else if (state === EMenuItemState.Enabled) {
|
|
32355
34392
|
row.checkboxElement.innerHTML = ICON_CHECK;
|
|
32356
34393
|
}
|
|
32357
34394
|
else if (state === EMenuItemState.ChildEnabled) {
|
|
@@ -32366,17 +34403,33 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32366
34403
|
* Works out a single item's state, rolling up children so a folder can report a partial state.
|
|
32367
34404
|
*/
|
|
32368
34405
|
_resolveState(item, enabledIds) {
|
|
32369
|
-
var _a;
|
|
34406
|
+
var _a, _b;
|
|
32370
34407
|
const isFolder = !item.Type || item.Type === MenuItem.EType.None;
|
|
32371
34408
|
if (!isFolder) {
|
|
32372
34409
|
return enabledIds.has(item.id) ? EMenuItemState.Enabled : EMenuItemState.Disabled;
|
|
32373
34410
|
}
|
|
34411
|
+
// Only one radio is ever enabled, so the folder is as enabled as that one.
|
|
34412
|
+
if (item.childrenAsRadios && ((_a = item.Children) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
34413
|
+
const states = item.Children.map(x => this._resolveState(x, enabledIds));
|
|
34414
|
+
if (states.includes(EMenuItemState.Enabled)) {
|
|
34415
|
+
return EMenuItemState.Enabled;
|
|
34416
|
+
}
|
|
34417
|
+
return states.includes(EMenuItemState.ChildEnabled) ? EMenuItemState.ChildEnabled : EMenuItemState.Disabled;
|
|
34418
|
+
}
|
|
32374
34419
|
// Folders derive from the leaves below them rather than their own enabled flag.
|
|
32375
34420
|
let actionCount = 0;
|
|
32376
34421
|
let enabledActionCount = 0;
|
|
32377
34422
|
const traverse = (current) => {
|
|
32378
|
-
var _a;
|
|
34423
|
+
var _a, _b;
|
|
32379
34424
|
const currentIsFolder = !current.Type || current.Type === MenuItem.EType.None;
|
|
34425
|
+
// A radio folder counts as one choice rather than as each of its radios.
|
|
34426
|
+
if (currentIsFolder && current.childrenAsRadios && ((_a = current.Children) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
34427
|
+
actionCount += 1;
|
|
34428
|
+
if (this._resolveState(current, enabledIds) === EMenuItemState.Enabled) {
|
|
34429
|
+
enabledActionCount += 1;
|
|
34430
|
+
}
|
|
34431
|
+
return;
|
|
34432
|
+
}
|
|
32380
34433
|
if (!currentIsFolder) {
|
|
32381
34434
|
actionCount += 1;
|
|
32382
34435
|
if (enabledIds.has(current.id)) {
|
|
@@ -32384,11 +34437,11 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32384
34437
|
}
|
|
32385
34438
|
return;
|
|
32386
34439
|
}
|
|
32387
|
-
if ((
|
|
34440
|
+
if ((_b = current.Children) === null || _b === void 0 ? void 0 : _b.length) {
|
|
32388
34441
|
current.Children.forEach(traverse);
|
|
32389
34442
|
}
|
|
32390
34443
|
};
|
|
32391
|
-
(
|
|
34444
|
+
(_b = item.Children) === null || _b === void 0 ? void 0 : _b.forEach(traverse);
|
|
32392
34445
|
if (actionCount <= 0) {
|
|
32393
34446
|
return enabledIds.has(item.id) ? EMenuItemState.Enabled : EMenuItemState.Disabled;
|
|
32394
34447
|
}
|
|
@@ -32414,7 +34467,7 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32414
34467
|
row.countElement.textContent = count.toLocaleString();
|
|
32415
34468
|
}
|
|
32416
34469
|
}
|
|
32417
|
-
_toggleItem(item) {
|
|
34470
|
+
_toggleItem(item, radioParent) {
|
|
32418
34471
|
var _a;
|
|
32419
34472
|
const manager = (_a = this._widget) === null || _a === void 0 ? void 0 : _a._getManager();
|
|
32420
34473
|
if (!manager) {
|
|
@@ -32422,7 +34475,21 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32422
34475
|
}
|
|
32423
34476
|
const enabledIds = new Set(manager.GetEnabledItemIds());
|
|
32424
34477
|
const state = this._resolveState(item, enabledIds);
|
|
32425
|
-
|
|
34478
|
+
// A radio stays picked until another one is, the folder's own checkbox turns them all off.
|
|
34479
|
+
if (radioParent && state === EMenuItemState.Enabled) {
|
|
34480
|
+
return;
|
|
34481
|
+
}
|
|
34482
|
+
let siblingIds = [];
|
|
34483
|
+
if (radioParent && state === EMenuItemState.Disabled) {
|
|
34484
|
+
siblingIds = radioParent.Children.filter(x => x !== item).flatMap(x => this._getEnabledIdsUnder(x, enabledIds));
|
|
34485
|
+
}
|
|
34486
|
+
if (siblingIds.length) {
|
|
34487
|
+
manager.SwapItem({
|
|
34488
|
+
fromIds: siblingIds,
|
|
34489
|
+
item
|
|
34490
|
+
});
|
|
34491
|
+
}
|
|
34492
|
+
else if (state === EMenuItemState.Enabled) {
|
|
32426
34493
|
this._disableItem(item);
|
|
32427
34494
|
}
|
|
32428
34495
|
else {
|
|
@@ -32432,6 +34499,16 @@ class WidgetLeftPanelTabMenuItems extends WidgetLeftPanelTab.ATab {
|
|
|
32432
34499
|
}
|
|
32433
34500
|
this._stateQueue.Call(true);
|
|
32434
34501
|
}
|
|
34502
|
+
/*
|
|
34503
|
+
* Returns the highest enabled ids at or below the item, since removing one removes everything under it.
|
|
34504
|
+
*/
|
|
34505
|
+
_getEnabledIdsUnder(item, enabledIds) {
|
|
34506
|
+
var _a;
|
|
34507
|
+
if (enabledIds.has(item.id)) {
|
|
34508
|
+
return [item.id];
|
|
34509
|
+
}
|
|
34510
|
+
return ((_a = item.Children) !== null && _a !== void 0 ? _a : []).flatMap(x => this._getEnabledIdsUnder(x, enabledIds));
|
|
34511
|
+
}
|
|
32435
34512
|
_disableItem(item) {
|
|
32436
34513
|
var _a, _b;
|
|
32437
34514
|
const manager = (_a = this._widget) === null || _a === void 0 ? void 0 : _a._getManager();
|
|
@@ -33964,33 +36041,50 @@ var MenuItemCreator;
|
|
|
33964
36041
|
}
|
|
33965
36042
|
const renderedItemIds = [];
|
|
33966
36043
|
if ((menuItems === null || menuItems === void 0 ? void 0 : menuItems.length) && (enabledIds === null || enabledIds === void 0 ? void 0 : enabledIds.length)) {
|
|
33967
|
-
const
|
|
36044
|
+
const alternateItems = (item) => {
|
|
36045
|
+
var _a, _b, _c, _d;
|
|
36046
|
+
// The project view menu item contains the instruction to enable tags, the bookmark specifies which ones.
|
|
36047
|
+
if (item.Type == MenuItem.EType.Entities && ((_a = item.BruceEntity) === null || _a === void 0 ? void 0 : _a.ExpandLayers)) {
|
|
36048
|
+
const eItem = item;
|
|
36049
|
+
// A setting the bookmark leaves out gets the view's own value back, not the last bookmark's.
|
|
36050
|
+
const authored = manager.GetAuthoredAlternation(item);
|
|
36051
|
+
const eItemAlt = alternations[item.id];
|
|
36052
|
+
const tags = (_b = eItemAlt === null || eItemAlt === void 0 ? void 0 : eItemAlt.BruceEntity) === null || _b === void 0 ? void 0 : _b.SelectedExpandLayers;
|
|
36053
|
+
eItem.BruceEntity = {
|
|
36054
|
+
...eItem.BruceEntity,
|
|
36055
|
+
SelectedExpandLayers: tags !== undefined ? tags : (_c = authored.BruceEntity) === null || _c === void 0 ? void 0 : _c.SelectedExpandLayers,
|
|
36056
|
+
};
|
|
36057
|
+
}
|
|
36058
|
+
else if (item.Type == MenuItem.EType.EntityTileset) {
|
|
36059
|
+
const tItem = item;
|
|
36060
|
+
const authored = manager.GetAuthoredAlternation(item);
|
|
36061
|
+
const tItemAlt = alternations[item.id];
|
|
36062
|
+
const hasAttenuation = (tItemAlt === null || tItemAlt === void 0 ? void 0 : tItemAlt.attenuation) !== undefined || (tItemAlt === null || tItemAlt === void 0 ? void 0 : tItemAlt.attenuationMax) !== undefined;
|
|
36063
|
+
const source = hasAttenuation ? tItemAlt : authored;
|
|
36064
|
+
tItem.attenuation = source.attenuation;
|
|
36065
|
+
tItem.attenuationMax = source.attenuationMax;
|
|
36066
|
+
}
|
|
36067
|
+
(_d = item.Children) === null || _d === void 0 ? void 0 : _d.forEach(alternateItems);
|
|
36068
|
+
};
|
|
36069
|
+
/*
|
|
36070
|
+
* Lays each picked style over a copy, so it never stays on the view's item for a later bookmark.
|
|
36071
|
+
*/
|
|
36072
|
+
const styleItems = (item) => {
|
|
33968
36073
|
var _a;
|
|
33969
|
-
|
|
33970
|
-
|
|
33971
|
-
|
|
33972
|
-
|
|
33973
|
-
const eItem = item;
|
|
33974
|
-
if (eItem.BruceEntity.ExpandLayers) {
|
|
33975
|
-
const eItemAlt = alternations[item.id];
|
|
33976
|
-
eItem.BruceEntity = {
|
|
33977
|
-
...eItem.BruceEntity,
|
|
33978
|
-
SelectedExpandLayers: (_a = eItemAlt.BruceEntity) === null || _a === void 0 ? void 0 : _a.SelectedExpandLayers,
|
|
33979
|
-
};
|
|
33980
|
-
}
|
|
33981
|
-
}
|
|
33982
|
-
else if (item.Type == MenuItem.EType.EntityTileset) {
|
|
33983
|
-
const tItem = item;
|
|
33984
|
-
const tItemAlt = alternations[item.id];
|
|
33985
|
-
tItem.attenuation = tItemAlt.attenuation;
|
|
33986
|
-
tItem.attenuationMax = tItemAlt.attenuationMax;
|
|
33987
|
-
}
|
|
36074
|
+
let next = alternations[item.id] ? MenuItemStyles.ApplyAlternation(item, alternations[item.id]) : item;
|
|
36075
|
+
const children = (_a = item.Children) === null || _a === void 0 ? void 0 : _a.map(styleItems);
|
|
36076
|
+
if (children === null || children === void 0 ? void 0 : children.some((child, i) => child !== item.Children[i])) {
|
|
36077
|
+
next = { ...next, Children: children };
|
|
33988
36078
|
}
|
|
36079
|
+
return next;
|
|
36080
|
+
};
|
|
36081
|
+
const traverseItems = async (item) => {
|
|
33989
36082
|
if (enabledIds.includes(item.id)) {
|
|
33990
36083
|
const itemId = await manager.RenderItem({
|
|
33991
36084
|
item: item,
|
|
33992
36085
|
getters: getters,
|
|
33993
|
-
modelSpace: contentType === ProjectViewBookmark.EContentType.WEB_3D_MODEL_SPACE
|
|
36086
|
+
modelSpace: contentType === ProjectViewBookmark.EContentType.WEB_3D_MODEL_SPACE,
|
|
36087
|
+
preferredIds: enabledIds
|
|
33994
36088
|
});
|
|
33995
36089
|
renderedItemIds.push(itemId);
|
|
33996
36090
|
}
|
|
@@ -34000,8 +36094,11 @@ var MenuItemCreator;
|
|
|
34000
36094
|
}
|
|
34001
36095
|
}
|
|
34002
36096
|
};
|
|
34003
|
-
|
|
34004
|
-
|
|
36097
|
+
// Tag and attenuation alternations write into the view's items, since Navigator's tag tree reads them back.
|
|
36098
|
+
menuItems.forEach(alternateItems);
|
|
36099
|
+
const styled = menuItems.map(styleItems);
|
|
36100
|
+
for (let i = 0; i < styled.length; i++) {
|
|
36101
|
+
await traverseItems(styled[i]);
|
|
34005
36102
|
}
|
|
34006
36103
|
}
|
|
34007
36104
|
return {
|
|
@@ -39346,6 +41443,7 @@ function groupAttributes(paths, attributes) {
|
|
|
39346
41443
|
}
|
|
39347
41444
|
class WidgetInfoView extends Widget.AWidget {
|
|
39348
41445
|
constructor(params) {
|
|
41446
|
+
var _a;
|
|
39349
41447
|
super(params);
|
|
39350
41448
|
this.STYLESHEET_ID = "nextspace-info-view-stylesheet";
|
|
39351
41449
|
this._generateStyles();
|
|
@@ -39355,10 +41453,19 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39355
41453
|
this._updateInfoView();
|
|
39356
41454
|
}
|
|
39357
41455
|
});
|
|
41456
|
+
// The selected Entity is read once per selection, so a change to its simulation reads it again.
|
|
41457
|
+
this._simulationRemoval = (_a = this._manager.Simulation) === null || _a === void 0 ? void 0 : _a.OnChanged.Subscribe((change) => {
|
|
41458
|
+
if (this._lastSelectedId && change.entityIds.includes(this._lastSelectedId)) {
|
|
41459
|
+
this._lastSelectedId = null;
|
|
41460
|
+
this._updateInfoView();
|
|
41461
|
+
}
|
|
41462
|
+
});
|
|
39358
41463
|
}
|
|
39359
41464
|
Dispose() {
|
|
41465
|
+
var _a;
|
|
39360
41466
|
super.Dispose();
|
|
39361
41467
|
this._updateRemoval();
|
|
41468
|
+
(_a = this._simulationRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
39362
41469
|
}
|
|
39363
41470
|
_generateStyles() {
|
|
39364
41471
|
if (document.getElementById(this.STYLESHEET_ID)) {
|
|
@@ -39820,7 +41927,7 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39820
41927
|
}
|
|
39821
41928
|
}
|
|
39822
41929
|
async _updateInfoView() {
|
|
39823
|
-
var
|
|
41930
|
+
var _a, _c, _d, _e, _f;
|
|
39824
41931
|
const selectedIds = this._manager.VisualsRegister.GetSelected();
|
|
39825
41932
|
if (selectedIds.length <= 0) {
|
|
39826
41933
|
this._element.style.display = "none";
|
|
@@ -39842,17 +41949,20 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39842
41949
|
this._summary.innerHTML = "";
|
|
39843
41950
|
this._imageContainer.style.display = "none";
|
|
39844
41951
|
const api = this._apiGetters.GetBruceApi();
|
|
39845
|
-
|
|
41952
|
+
// A simulated Entity is shown as simulated: a stand-in as is, a patch over what the API has.
|
|
41953
|
+
const simulation = this._manager.Simulation;
|
|
41954
|
+
let entity = (_a = simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(firstId)) !== null && _a !== void 0 ? _a : (await Entity$1.Get({
|
|
39846
41955
|
entityId: firstId,
|
|
39847
41956
|
api: api,
|
|
39848
41957
|
migrated: true,
|
|
39849
41958
|
expandLocation: DISPLAY_ASSEMBLY_INFO
|
|
39850
|
-
});
|
|
41959
|
+
})).entity;
|
|
41960
|
+
entity = entity && simulation ? simulation.Resolve(firstId, entity) : entity;
|
|
39851
41961
|
if (!entity) {
|
|
39852
41962
|
throw (new Error("Could not get entity."));
|
|
39853
41963
|
}
|
|
39854
41964
|
const { entityType } = await EntityType.Get({
|
|
39855
|
-
entityTypeId: (
|
|
41965
|
+
entityTypeId: (_c = entity.Bruce) === null || _c === void 0 ? void 0 : _c["EntityType.ID"],
|
|
39856
41966
|
api: api
|
|
39857
41967
|
});
|
|
39858
41968
|
let name = Entity$1.CalculateName({
|
|
@@ -39875,7 +41985,7 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39875
41985
|
const defaultImage = images.length ? images[0] : null;
|
|
39876
41986
|
if (defaultImage) {
|
|
39877
41987
|
this._imageContainer.style.display = "flex";
|
|
39878
|
-
const url = (
|
|
41988
|
+
const url = (_d = defaultImage.URL) !== null && _d !== void 0 ? _d : ClientFile.GetUrl({
|
|
39879
41989
|
fileId: defaultImage["ClientFile.ID"],
|
|
39880
41990
|
api: api,
|
|
39881
41991
|
viaCdn: true
|
|
@@ -39888,7 +41998,7 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39888
41998
|
this._summary.appendChild(detailsTitle);
|
|
39889
41999
|
// TODO: Selection for what mode instead of always doing "all".
|
|
39890
42000
|
const attributes = gatherAttributes(EMode.ShowAll, entity, entityType);
|
|
39891
|
-
const groups = groupAttributes(attributes, (
|
|
42001
|
+
const groups = groupAttributes(attributes, (_f = (_e = entityType.DataSchema) === null || _e === void 0 ? void 0 : _e.Structure) !== null && _f !== void 0 ? _f : []);
|
|
39892
42002
|
for (const group of groups) {
|
|
39893
42003
|
this._generateAttrGroup(entityType, entity, group);
|
|
39894
42004
|
}
|
|
@@ -42485,7 +44595,7 @@ var EntityUtils;
|
|
|
42485
44595
|
* @param params
|
|
42486
44596
|
*/
|
|
42487
44597
|
async function GetLocation(params) {
|
|
42488
|
-
var _a, _b, _c, _d;
|
|
44598
|
+
var _a, _b, _c, _d, _e;
|
|
42489
44599
|
let { api, viewer, samples, visualRegister, minimumAlt, paddingAlt } = params;
|
|
42490
44600
|
if (!paddingAlt) {
|
|
42491
44601
|
paddingAlt = 0;
|
|
@@ -43033,6 +45143,13 @@ var EntityUtils;
|
|
|
43033
45143
|
recordSamples.push(sample);
|
|
43034
45144
|
}
|
|
43035
45145
|
}
|
|
45146
|
+
// A simulated Entity is where its blob says, never where the API has it.
|
|
45147
|
+
const simulation = EntitySimulation.Get(viewer);
|
|
45148
|
+
for (const sample of recordSamples) {
|
|
45149
|
+
if (!sample.entity && sample.entityId) {
|
|
45150
|
+
sample.entity = (_e = simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(sample.entityId)) !== null && _e !== void 0 ? _e : sample.entity;
|
|
45151
|
+
}
|
|
45152
|
+
}
|
|
43036
45153
|
// Bulk requesting Entity records.
|
|
43037
45154
|
try {
|
|
43038
45155
|
const toSearchIds = recordSamples.filter(x => !x.entity && x.entityId).map(x => x.entityId);
|
|
@@ -43053,7 +45170,8 @@ var EntityUtils;
|
|
|
43053
45170
|
for (let i = 0; i < recordSamples.length; i++) {
|
|
43054
45171
|
const sample = recordSamples[i];
|
|
43055
45172
|
if (!sample.entity && sample.entityId) {
|
|
43056
|
-
|
|
45173
|
+
const read = entitiesMap.get(sample.entityId);
|
|
45174
|
+
sample.entity = read && simulation ? simulation.Overlay(read) : read;
|
|
43057
45175
|
}
|
|
43058
45176
|
}
|
|
43059
45177
|
}
|
|
@@ -43067,6 +45185,11 @@ var EntityUtils;
|
|
|
43067
45185
|
// We have to detect whatever is an Assembly Entity and expand it.
|
|
43068
45186
|
try {
|
|
43069
45187
|
const needsExpansion = recordSamples.filter(x => {
|
|
45188
|
+
var _a;
|
|
45189
|
+
// Expanding reads the API's record, which would replace the stand-in or undo the patch.
|
|
45190
|
+
if (simulation === null || simulation === void 0 ? void 0 : simulation.HasBlob((_a = x.entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID)) {
|
|
45191
|
+
return false;
|
|
45192
|
+
}
|
|
43070
45193
|
const assemblyPos = Entity$1.GetValue({
|
|
43071
45194
|
entity: x.entity,
|
|
43072
45195
|
path: ["Bruce", "AssemblyPosition"]
|
|
@@ -43425,6 +45548,21 @@ var EntityUtils;
|
|
|
43425
45548
|
return Quaternion.multiply(combined, _assemblyAxisShift, new Quaternion());
|
|
43426
45549
|
}
|
|
43427
45550
|
EntityUtils.GetAssemblyOrientation = GetAssemblyOrientation;
|
|
45551
|
+
/**
|
|
45552
|
+
* Returns the orientation a part's model is drawn with, for its world matrix within the root's frame.
|
|
45553
|
+
* @param rootFrame the root's frame in the world, eg. from Transforms.headingPitchRollToFixedFrame.
|
|
45554
|
+
* @param world the part's matrix within the root's frame.
|
|
45555
|
+
*/
|
|
45556
|
+
function GetAssemblyOrientationInFrame(rootFrame, world) {
|
|
45557
|
+
if (!rootFrame || !world) {
|
|
45558
|
+
return null;
|
|
45559
|
+
}
|
|
45560
|
+
const combined = Matrix4.multiply(rootFrame, world, new Matrix4());
|
|
45561
|
+
const rotation = Matrix4.getRotation(combined, new Matrix3());
|
|
45562
|
+
const q = Quaternion.fromRotationMatrix(rotation);
|
|
45563
|
+
return Quaternion.multiply(q, _assemblyAxisShift, new Quaternion());
|
|
45564
|
+
}
|
|
45565
|
+
EntityUtils.GetAssemblyOrientationInFrame = GetAssemblyOrientationInFrame;
|
|
43428
45566
|
/**
|
|
43429
45567
|
* Returns the position of the entity.
|
|
43430
45568
|
* This is an async variant that checks for related assemblies.
|
|
@@ -43434,6 +45572,18 @@ var EntityUtils;
|
|
|
43434
45572
|
*/
|
|
43435
45573
|
async function GetPosAsync(params) {
|
|
43436
45574
|
let { viewer, entityId, entity, visualRegister, returnHeightRef, recordHeightRef, api } = params;
|
|
45575
|
+
// A simulated Entity is where its stand-in says, or where its patch puts the API's record.
|
|
45576
|
+
const simulation = EntitySimulation.Get(viewer);
|
|
45577
|
+
entity = entity !== null && entity !== void 0 ? entity : simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(entityId);
|
|
45578
|
+
if (!entity && entityId && (simulation === null || simulation === void 0 ? void 0 : simulation.HasBlob(entityId))) {
|
|
45579
|
+
try {
|
|
45580
|
+
const read = (await Entity$1.Get({ api, entityId, expandLocation: false, migrated: true })).entity;
|
|
45581
|
+
entity = read ? simulation.Overlay(read) : null;
|
|
45582
|
+
}
|
|
45583
|
+
catch (e) {
|
|
45584
|
+
console.error(e);
|
|
45585
|
+
}
|
|
45586
|
+
}
|
|
43437
45587
|
// We have issues where imported BRZ files have improper expandLocation=true info.
|
|
43438
45588
|
// As a result we'll double-request the data.
|
|
43439
45589
|
// If there is a location then we won't bother using expanded information.
|
|
@@ -53434,7 +55584,7 @@ var StyleUtils;
|
|
|
53434
55584
|
StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
|
|
53435
55585
|
})(StyleUtils || (StyleUtils = {}));
|
|
53436
55586
|
|
|
53437
|
-
const VERSION = "7.6.
|
|
55587
|
+
const VERSION = "7.6.3";
|
|
53438
55588
|
/**
|
|
53439
55589
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
53440
55590
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|
|
@@ -53451,5 +55601,5 @@ const getENVIRONMENT = () => {
|
|
|
53451
55601
|
return ENVIRONMENT;
|
|
53452
55602
|
};
|
|
53453
55603
|
|
|
53454
|
-
export { VERSION, setENVIRONMENT, getENVIRONMENT, ClusterItems, PointClustering, PointClusterSize, CesiumAnimatedInOut, DisplacedSurfacePrimitive, CesiumAnimatedProperty, isStyleChanged, isOutlineChanged$1 as isOutlineChanged, StyleEffective, EntityRenderEngine, EntityRenderEngineModel3d, EntityRenderEnginePoint, extractMetadataFromFileUrl, EntityRenderEnginePolygon, EntityRenderEnginePolyline, TextureFrameSeriesAnimator, TextureValueLabels, MenuItemCreator, MenuItemManager, CesiumParabola, EntityLabel, EntityLabelGroup, LiveCursor, SharedGetters, DataSourceStaticKmlManager, DataLabRenderManager, EntitiesIdsRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, AssemblyRenderManager, GoogleSearchRenderManager, RelationsRenderManager, RenderManager, TilesetArbRenderManager, TilesetCadRenderManager, TilesetEntitiesRenderManager, TilesetGooglePhotosRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TileRenderEngine, createTileset, TilesetRenderEngine, ViewRenderEngine, VisualRegisterCuller, VisualsRegister, XGridsRenderEngine, CesiumEntityStyler, DrawingUtils, EntityUtils, MeasureUtils, StyleUtils, CESIUM_INSPECTOR_KEY, CESIUM_TIMELINE_KEY, CESIUM_TIMELINE_LIVE_KEY, CESIUM_TIMELINE_LIVE_PADDING_KEY, CESIUM_TIMELINE_INTERVAL_KEY, CESIUM_MODEL_SPACE_KEY, DEFAULT_LIVE_PADDING_SECONDS, DEFAULT_BRIGHTNESS_SHIFT, DEFAULT_LIGHT_INTENSITY, LIGHTING_SETTINGS_VERSION, LIGHT_INTENSITY_COMPENSATION, MAX_COMPENSATED_LIGHT_INTENSITY, ViewUtils, CesiumViewMonitor, ViewGroundArea, ViewerEventTracker, ViewerUtils, Draw3dPolygon, Draw3dPolyline, MeasureCreator, Walkthrough, WidgetControlViewBar, WidgetControlViewBarSearch, WidgetLeftPanelTab, WidgetLeftPanelTabBookmarks, WidgetLeftPanelTabDashboard, EMenuItemState, WidgetLeftPanelTabMenuItems, Widget, VIEWER_BOOKMARKS_WIDGET_KEY, WidgetBookmarks, WidgetBranding, ECursor, WidgetCursorBar, WidgetEmbeddedInfoView, WidgetInfoView, VIEWER_LEFT_PANEL_WIDGET_KEY, VIEWER_LEFT_PANEL_CSS_VAR_LEFT, CreateTabIconSvg, WidgetLeftPanel, WidgetNavCompass$$1 as WidgetNavCompass, VIEWER_VIEW_BAR_WIDGET_KEY, WidgetViewBar };
|
|
55604
|
+
export { VERSION, setENVIRONMENT, getENVIRONMENT, ClusterItems, PointClustering, PointClusterSize, CesiumAnimatedInOut, DisplacedSurfacePrimitive, CesiumAnimatedProperty, isStyleChanged, isOutlineChanged$1 as isOutlineChanged, StyleEffective, EntityRenderEngine, EntityRenderEngineModel3d, EntityRenderEnginePoint, extractMetadataFromFileUrl, EntityRenderEnginePolygon, EntityRenderEnginePolyline, TextureFrameSeriesAnimator, TextureValueLabels, MenuItemCreator, MenuItemManager, MenuItemStyles, CesiumParabola, EntityLabel, EntityLabelGroup, LiveCursor, SharedGetters, EntitySimulation, DataSourceStaticKmlManager, DataLabRenderManager, EntitiesIdsRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, AssemblyRenderManager, GoogleSearchRenderManager, RelationsRenderManager, RenderManager, TilesetArbRenderManager, TilesetCadRenderManager, TilesetEntitiesRenderManager, TilesetGooglePhotosRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TileRenderEngine, createTileset, TilesetRenderEngine, ViewRenderEngine, VisualRegisterCuller, VisualsRegister, XGridsRenderEngine, CesiumEntityStyler, DrawingUtils, EntityUtils, MeasureUtils, StyleUtils, CESIUM_INSPECTOR_KEY, CESIUM_TIMELINE_KEY, CESIUM_TIMELINE_LIVE_KEY, CESIUM_TIMELINE_LIVE_PADDING_KEY, CESIUM_TIMELINE_INTERVAL_KEY, CESIUM_MODEL_SPACE_KEY, DEFAULT_LIVE_PADDING_SECONDS, DEFAULT_BRIGHTNESS_SHIFT, DEFAULT_LIGHT_INTENSITY, LIGHTING_SETTINGS_VERSION, LIGHT_INTENSITY_COMPENSATION, MAX_COMPENSATED_LIGHT_INTENSITY, ViewUtils, CesiumViewMonitor, ViewGroundArea, ViewerEventTracker, ViewerUtils, Draw3dPolygon, Draw3dPolyline, MeasureCreator, Walkthrough, WidgetControlViewBar, WidgetControlViewBarSearch, WidgetLeftPanelTab, WidgetLeftPanelTabBookmarks, WidgetLeftPanelTabDashboard, EMenuItemState, WidgetLeftPanelTabMenuItems, Widget, VIEWER_BOOKMARKS_WIDGET_KEY, WidgetBookmarks, WidgetBranding, ECursor, WidgetCursorBar, WidgetEmbeddedInfoView, WidgetInfoView, VIEWER_LEFT_PANEL_WIDGET_KEY, VIEWER_LEFT_PANEL_CSS_VAR_LEFT, CreateTabIconSvg, WidgetLeftPanel, WidgetNavCompass$$1 as WidgetNavCompass, VIEWER_VIEW_BAR_WIDGET_KEY, WidgetViewBar };
|
|
53455
55605
|
//# sourceMappingURL=bruce-cesium.es5.js.map
|