bruce-cesium 7.6.0 → 7.6.2
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 +2057 -348
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +2050 -345
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +2 -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-manager.js +83 -10
- package/dist/lib/rendering/menu-item-manager.js.map +1 -1
- 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 +94 -12
- 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 +3 -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 +10 -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 +3 -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 +18 -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 +1 -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 +2 -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 +130 -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 +3 -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/widget-info-view.js +20 -7
- package/dist/lib/widgets/widget-info-view.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +2 -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 +33 -1
- 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 +5 -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 +2 -0
- package/dist/types/rendering/render-managers/entities/entities-ids-render-manager.d.ts +2 -0
- package/dist/types/rendering/render-managers/entities/entities-loaded-render-manager.d.ts +2 -0
- package/dist/types/rendering/render-managers/entities/entities-render-manager.d.ts +2 -0
- package/dist/types/rendering/render-managers/entities/entity-render-manager.d.ts +2 -0
- 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 +4 -0
- package/dist/types/rendering/render-managers/tilesets/tileset-arb-render-manager.d.ts +3 -0
- package/dist/types/rendering/render-managers/tilesets/tileset-cad-render-manager.d.ts +11 -1
- package/dist/types/rendering/render-managers/tilesets/tileset-entities-render-manager.d.ts +3 -0
- 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/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,
|
|
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,
|
|
2
|
+
import { Cartographic, Entity, ConstantPositionProperty, HeightReference, Color, DistanceDisplayCondition, ColorMaterialProperty, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, ColorBlendMode, HeadingPitchRoll, Math as Math$1, Transforms, ShadowMode, Cartesian3, ClassificationType, Model, JulianDate, Quaternion, Matrix4, HorizontalOrigin, VerticalOrigin, 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, FeatureDetection, Matrix3, NearFarScalar, KmlDataSource, GeoJsonDataSource, Cesium3DTileStyle, HeadingPitchRange, Ion, IonResource, Cesium3DTileColorBlendMode, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, Cesium3DTileset, OrthographicFrustum, EasingFunction, Intersect, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, PolygonPipeline, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, CustomDataSource, GeometryInstance, CesiumInspector, ClockRange, DynamicEnvironmentMapManager, ScreenSpaceEventHandler, ScreenSpaceEventType, Fullscreen, CzmlDataSource } from 'cesium';
|
|
3
|
+
import { Cartes, LRUCache, ProjectViewTile, ENVIRONMENT, Calculator, ClientFile, Entity as Entity$1, EntityLod, EntityTag, EntityType, ObjectUtils, Style, UrlUtils, Api, Carto, Geometry as Geometry$1, Bounds, ClientFileValueMap, Color as Color$1, MenuItem, ProjectView, ProjectViewBookmark, Tileset, ZoomControl, BruceEvent, EntityCoords, DataLab, DelayQueue, AccountConcept, BruceApi, EntityRelation, RecordChangeFeed, EntitySource, ProgramKey, ProjectViewLegacyTile, Camera, Account, AccountLimits, Session, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, ProjectViewBookmarkGroup, 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.
|
|
@@ -6436,6 +6873,22 @@ var EntityLabel;
|
|
|
6436
6873
|
return centre && half && (axes === null || axes === void 0 ? void 0 : axes.every(Boolean)) ? { centre, axes, half } : null;
|
|
6437
6874
|
}
|
|
6438
6875
|
EntityLabel.ReadOrientedBox = ReadOrientedBox;
|
|
6876
|
+
/*
|
|
6877
|
+
* Whether a placement turns what it places. Scale alone does not count.
|
|
6878
|
+
*/
|
|
6879
|
+
function isRotated(matrix) {
|
|
6880
|
+
for (let column = 0; column < 3; column++) {
|
|
6881
|
+
const axis = [0, 1, 2].map(row => Number(matrix[row][column]));
|
|
6882
|
+
const length = Math.hypot(...axis);
|
|
6883
|
+
if (!(length > 0)) {
|
|
6884
|
+
return false;
|
|
6885
|
+
}
|
|
6886
|
+
if (axis.some((value, row) => Math.abs(value / length - Number(row === column)) > 1e-5)) {
|
|
6887
|
+
return true;
|
|
6888
|
+
}
|
|
6889
|
+
}
|
|
6890
|
+
return false;
|
|
6891
|
+
}
|
|
6439
6892
|
/*
|
|
6440
6893
|
* The eight padded world corners of an assembly Entity's geometry box, or null when the record cannot give one.
|
|
6441
6894
|
*
|
|
@@ -6454,6 +6907,10 @@ var EntityLabel;
|
|
|
6454
6907
|
if ((matrix === null || matrix === void 0 ? void 0 : matrix.length) !== 4 || !matrix.every(row => (row === null || row === void 0 ? void 0 : row.length) === 4) || !Number.isFinite(+(root === null || root === void 0 ? void 0 : root.latitude)) || !Number.isFinite(+(root === null || root === void 0 ? void 0 : root.longitude))) {
|
|
6455
6908
|
return null;
|
|
6456
6909
|
}
|
|
6910
|
+
// A pure translation can hide a rotation baked into the vertices, which leaves the extents loose.
|
|
6911
|
+
if (!shape && !isRotated(matrix)) {
|
|
6912
|
+
return null;
|
|
6913
|
+
}
|
|
6457
6914
|
const pivot = ((_c = bruce.GeometryPivot) === null || _c === void 0 ? void 0 : _c.length) >= 3 ? bruce.GeometryPivot.slice(0, 3).map(Number) : [0, 0, 0];
|
|
6458
6915
|
// Without an oriented box the record's own extents are an axis-aligned box about the pivot.
|
|
6459
6916
|
const box = shape || { centre: pivot, axes: [[1, 0, 0], [0, 1, 0], [0, 0, 1]], half: half };
|
|
@@ -6744,6 +7201,7 @@ var EntityLabel;
|
|
|
6744
7201
|
constructor() {
|
|
6745
7202
|
// Whether a box competes for space comes only from inputs (camera distance, hover, the pointer), never from
|
|
6746
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.
|
|
6747
7205
|
this.entries = new Map();
|
|
6748
7206
|
this.groups = null;
|
|
6749
7207
|
// The hovered Entity. Its box is drawn on its own and whole, ahead of every other box.
|
|
@@ -6761,7 +7219,7 @@ var EntityLabel;
|
|
|
6761
7219
|
Set(id, corners, entityId, inputs) {
|
|
6762
7220
|
const current = this.entries.get(id);
|
|
6763
7221
|
// A label rebuilt over the same box keeps its place and how far it has animated.
|
|
6764
|
-
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) {
|
|
6765
7223
|
Object.assign(current, inputs);
|
|
6766
7224
|
return;
|
|
6767
7225
|
}
|
|
@@ -6769,17 +7227,41 @@ var EntityLabel;
|
|
|
6769
7227
|
return;
|
|
6770
7228
|
}
|
|
6771
7229
|
if (corners) {
|
|
6772
|
-
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 });
|
|
6773
7231
|
}
|
|
6774
7232
|
else
|
|
6775
7233
|
this.entries.delete(id);
|
|
6776
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) {
|
|
6777
7241
|
this.groups = null;
|
|
6778
7242
|
for (const [key, group] of this.outlines) {
|
|
6779
7243
|
if (group.members.includes(id))
|
|
6780
7244
|
this.outlines.delete(key);
|
|
6781
7245
|
}
|
|
6782
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
|
+
}
|
|
6783
7265
|
/*
|
|
6784
7266
|
* The box drawn for a label this frame, or undefined when it has none or lost its place.
|
|
6785
7267
|
*/
|
|
@@ -6847,6 +7329,7 @@ var EntityLabel;
|
|
|
6847
7329
|
*/
|
|
6848
7330
|
Resolve(viewer, pointer) {
|
|
6849
7331
|
var _a, _b, _c, _d;
|
|
7332
|
+
this.follow();
|
|
6850
7333
|
this.frames.clear();
|
|
6851
7334
|
this.hulls.clear();
|
|
6852
7335
|
this.drawn = [];
|
|
@@ -7269,9 +7752,16 @@ var EntityLabel;
|
|
|
7269
7752
|
}
|
|
7270
7753
|
if (this.api) {
|
|
7271
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
|
+
}
|
|
7272
7762
|
this.rego.name = await Entity$1.CalculateNameAsync({
|
|
7273
7763
|
api: this.api,
|
|
7274
|
-
entity:
|
|
7764
|
+
entity: simulated,
|
|
7275
7765
|
entityId: rego.entityId,
|
|
7276
7766
|
defaultToId: false
|
|
7277
7767
|
});
|
|
@@ -7300,6 +7790,21 @@ var EntityLabel;
|
|
|
7300
7790
|
clearTimeout(this.loadTimeout);
|
|
7301
7791
|
this.loadTimeout = null;
|
|
7302
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
|
+
}
|
|
7303
7808
|
/*
|
|
7304
7809
|
* Rebuilds only when configuration changes; state refreshes must not recreate DOM every frame.
|
|
7305
7810
|
*/
|
|
@@ -7530,7 +8035,7 @@ var EntityLabel;
|
|
|
7530
8035
|
}
|
|
7531
8036
|
clearTimeout(this.loadTimeout);
|
|
7532
8037
|
this.loadTimeout = setTimeout(async () => {
|
|
7533
|
-
var _a, _b, _c, _d, _e;
|
|
8038
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7534
8039
|
if (this.disposed || this.counter != counter) {
|
|
7535
8040
|
return;
|
|
7536
8041
|
}
|
|
@@ -7557,16 +8062,19 @@ var EntityLabel;
|
|
|
7557
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;
|
|
7558
8063
|
// Read for its attributes, and for a photo when the label has no icon of its own.
|
|
7559
8064
|
if (attributes || !HasIcon(this.options)) {
|
|
7560
|
-
|
|
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;
|
|
7561
8068
|
try {
|
|
7562
|
-
entity = (await Entity$1.Get({
|
|
8069
|
+
entity = entity !== null && entity !== void 0 ? entity : (await Entity$1.Get({
|
|
7563
8070
|
api: this.api,
|
|
7564
8071
|
entityId: this.rego.entityId,
|
|
7565
|
-
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,
|
|
7566
8073
|
schemaId: this.rego.schema,
|
|
7567
8074
|
migrated: true,
|
|
7568
8075
|
expandAttachments: !HasIcon(this.options)
|
|
7569
8076
|
})).entity;
|
|
8077
|
+
entity = entity && simulation ? simulation.Resolve(this.rego.entityId, entity) : entity;
|
|
7570
8078
|
}
|
|
7571
8079
|
// Entity doesn't exist.
|
|
7572
8080
|
// Likely a graphic with an ID that points to no record.
|
|
@@ -7950,11 +8458,17 @@ var EntityLabel;
|
|
|
7950
8458
|
// Past the wait a slow record no longer holds the label back; a box that comes later eases in.
|
|
7951
8459
|
setTimeout(settle, MODEL_BOX_WAIT);
|
|
7952
8460
|
this.modelBox.load.then(corners => {
|
|
8461
|
+
var _a, _b;
|
|
7953
8462
|
if (!corners || this.disposed || this.counter !== counter) {
|
|
7954
8463
|
return;
|
|
7955
8464
|
}
|
|
7956
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);
|
|
7957
8468
|
const centre = Cartesian3.midpoint(corners[0], corners[7], new Cartesian3());
|
|
8469
|
+
if (motion) {
|
|
8470
|
+
Matrix4.multiplyByPoint(motion, centre, centre);
|
|
8471
|
+
}
|
|
7958
8472
|
if (Cartesian3.distance(centre, found) > Cartesian3.distance(corners[0], corners[7]) * 0.75 + 2) {
|
|
7959
8473
|
return;
|
|
7960
8474
|
}
|
|
@@ -7962,6 +8476,7 @@ var EntityLabel;
|
|
|
7962
8476
|
// Let go a little further out than it is taken, so a camera resting at the limit does not flip it.
|
|
7963
8477
|
let near = false;
|
|
7964
8478
|
layer.modelBoxes.Set(this.id, corners, rego.entityId, {
|
|
8479
|
+
motion: rego.motion ? () => rego.motion(this.viewer.clock.currentTime) : undefined,
|
|
7965
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); },
|
|
7966
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)); },
|
|
7967
8482
|
near: () => {
|
|
@@ -8168,7 +8683,7 @@ var EntityLabel;
|
|
|
8168
8683
|
viewportWidth: this.viewer.canvas.clientWidth,
|
|
8169
8684
|
id: this.id, entityKey: ((_x = this.rego) === null || _x === void 0 ? void 0 : _x.entityId) ? JSON.stringify([this.rego.entityId, this.rego.menuItemId || "", this.Transient && !this.Persistent ? "hover" : ""]) : undefined,
|
|
8170
8685
|
entityId: (_y = this.rego) === null || _y === void 0 ? void 0 : _y.entityId, group: this.groupId, x, y, width, height, anchorX, anchorY, depth, leaderLength, leaderRun, leaderSide, distance,
|
|
8171
|
-
iconRadius: icon === null || icon === void 0 ? void 0 : icon.radius, modelBox: boxed || undefined, boxBlend,
|
|
8686
|
+
iconRadius: icon === null || icon === void 0 ? void 0 : icon.radius, modelBox: boxed || undefined, boxBlend, follows: !pinned && Boolean(transientPivot || cursorMotion.target),
|
|
8172
8687
|
// Priority shows the hovered member individually without dragging its cluster along.
|
|
8173
8688
|
opacity: waiting ? 0 : opacity, priority: hover || cursorAmount > 0 || (state === null || state === void 0 ? void 0 : state.highlighted) ? 1 : 0, options: this.options, text: originalText, clusterBounds
|
|
8174
8689
|
};
|
|
@@ -8295,15 +8810,16 @@ var EntityLabel;
|
|
|
8295
8810
|
const normalRadius = (!leader || (ring === null || ring === void 0 ? void 0 : ring.enabled) === false ? 0 : Math.max(frame.distance <= ((_l = ring === null || ring === void 0 ? void 0 : ring.nearDistance) !== null && _l !== void 0 ? _l : 100) ? ((_m = ring === null || ring === void 0 ? void 0 : ring.nearRadius) !== null && _m !== void 0 ? _m : 10) : 0, hovered ? ((_o = ring === null || ring === void 0 ? void 0 : ring.hoverRadius) !== null && _o !== void 0 ? _o : (this.Transient && !this.Persistent ? 15.4 : 22)) : 0));
|
|
8296
8811
|
const targetRadius = normalRadius + (15.4 - normalRadius) * cursorMotion.amount;
|
|
8297
8812
|
// Around a glyph the ring keeps the glyph's size and only fades its stroke in, so it never covers the icon.
|
|
8298
|
-
|
|
8299
|
-
const
|
|
8813
|
+
// A ring around the cursor marks nothing, so a riding label keeps only its leader.
|
|
8814
|
+
const targetOuter = frame.follows ? 0 : iconRing || targetRadius || 2.5;
|
|
8815
|
+
const targetInner = frame.follows ? 0 : iconRing ? (targetRadius > 0 ? iconRing - 2 : iconRing) : Math.max(0, targetRadius - 2);
|
|
8300
8816
|
const now = Date.now();
|
|
8301
8817
|
const duration = (_p = ring === null || ring === void 0 ? void 0 : ring.transitionDuration) !== null && _p !== void 0 ? _p : 200;
|
|
8302
8818
|
const sharedRing = this.Transient && !this.Persistent && this.hoverFade.to === 1 ? this.hoverRingState : undefined;
|
|
8303
8819
|
let ringAnimation = sharedRing ? sharedRing.animation : this.ringAnimation;
|
|
8304
8820
|
if (!ringAnimation) {
|
|
8305
|
-
const outer = iconRing || 2.5;
|
|
8306
|
-
const inner = iconRing;
|
|
8821
|
+
const outer = frame.follows ? 0 : iconRing || 2.5;
|
|
8822
|
+
const inner = frame.follows ? 0 : iconRing;
|
|
8307
8823
|
ringAnimation = { target: outer, targetInner: inner, start: now, outer, inner, fromOuter: outer, fromInner: inner };
|
|
8308
8824
|
}
|
|
8309
8825
|
const animateRing = () => {
|
|
@@ -8942,9 +9458,9 @@ var EntityLabelGroup;
|
|
|
8942
9458
|
* Reads the entities behind items that name one without carrying it, attachments included,
|
|
8943
9459
|
* so a label's default image needs no second request.
|
|
8944
9460
|
*/
|
|
8945
|
-
async function Hydrate(items, api, signal) {
|
|
9461
|
+
async function Hydrate(items, api, signal, simulation) {
|
|
8946
9462
|
var _a, _b;
|
|
8947
|
-
if (!api) {
|
|
9463
|
+
if (!api && !simulation) {
|
|
8948
9464
|
return items;
|
|
8949
9465
|
}
|
|
8950
9466
|
const hydrated = items.slice();
|
|
@@ -8955,12 +9471,15 @@ var EntityLabelGroup;
|
|
|
8955
9471
|
}
|
|
8956
9472
|
const chunk = missing.slice(start, start + HYDRATE_AT_ONCE);
|
|
8957
9473
|
try {
|
|
8958
|
-
|
|
8959
|
-
|
|
8960
|
-
}
|
|
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: [] };
|
|
8961
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]; }));
|
|
8962
9480
|
for (const at of chunk) {
|
|
8963
|
-
const
|
|
9481
|
+
const id = hydrated[at].entityId;
|
|
9482
|
+
const entity = simulation ? simulation.Resolve(id, found.get(id)) : found.get(id);
|
|
8964
9483
|
if (entity) {
|
|
8965
9484
|
// The API leaves Attachment out when there are none; an empty list records that they were read.
|
|
8966
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 : [] } } };
|
|
@@ -8977,7 +9496,7 @@ var EntityLabelGroup;
|
|
|
8977
9496
|
/*
|
|
8978
9497
|
* Uses the existing DataLab grammar, discarding actions and projections that cannot return Entities.
|
|
8979
9498
|
*/
|
|
8980
|
-
async function Loader(source, api, signal, hydrate) {
|
|
9499
|
+
async function Loader(source, api, signal, hydrate, simulation) {
|
|
8981
9500
|
var _a;
|
|
8982
9501
|
var _b;
|
|
8983
9502
|
if (source.type === "provider") {
|
|
@@ -8992,7 +9511,7 @@ var EntityLabelGroup;
|
|
|
8992
9511
|
return async (offset, limit, signal) => {
|
|
8993
9512
|
const page = items.slice(offset, offset + limit);
|
|
8994
9513
|
return {
|
|
8995
|
-
items: hydrate ? await Hydrate(page, api, signal) : page,
|
|
9514
|
+
items: hydrate ? await Hydrate(page, api, signal, simulation) : page,
|
|
8996
9515
|
hasMore: offset + limit < items.length
|
|
8997
9516
|
};
|
|
8998
9517
|
};
|
|
@@ -9134,7 +9653,7 @@ var EntityLabelGroup;
|
|
|
9134
9653
|
const items = new Map();
|
|
9135
9654
|
let truncated = false;
|
|
9136
9655
|
try {
|
|
9137
|
-
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));
|
|
9138
9657
|
let offset = 0;
|
|
9139
9658
|
for (let pageNumber = 0;; pageNumber++) {
|
|
9140
9659
|
if (controller.signal.aborted || this.register.Disposed) {
|
|
@@ -9956,8 +10475,25 @@ var RelationRenderEngine;
|
|
|
9956
10475
|
return `${relation["Related.Entity.ID"]}-${relation["Principal.Entity.ID"]}-${relation["Relation.Type.ID"]}`;
|
|
9957
10476
|
}
|
|
9958
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;
|
|
9959
10495
|
async function Render(params) {
|
|
9960
|
-
const { apiGetter, viewer, visualRegister, menuItemId, relations } = params;
|
|
10496
|
+
const { apiGetter, viewer, visualRegister, menuItemId, relations, simulation } = params;
|
|
9961
10497
|
const api = apiGetter.getApi(apiGetter.accountId);
|
|
9962
10498
|
const rendered = {};
|
|
9963
10499
|
let neededEntityIdsIds = [];
|
|
@@ -9975,13 +10511,15 @@ var RelationRenderEngine;
|
|
|
9975
10511
|
}
|
|
9976
10512
|
// Turn the set unique.
|
|
9977
10513
|
neededEntityIdsIds = neededEntityIdsIds.filter((v, i, a) => a.indexOf(v) === i);
|
|
9978
|
-
// Get all entities in one go.
|
|
9979
|
-
|
|
9980
|
-
|
|
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,
|
|
9981
10519
|
api: apiGetter.getApi(),
|
|
9982
10520
|
migrated: true,
|
|
9983
10521
|
maxSearchTimeSec: 60 * 2
|
|
9984
|
-
})).entities;
|
|
10522
|
+
})).entities.map(entity => simulation ? simulation.Overlay(entity) : entity) : []).concat(simulated);
|
|
9985
10523
|
// Create a map for quick reference.
|
|
9986
10524
|
const entitiesMap = {};
|
|
9987
10525
|
for (let i = 0; i < entities.length; i++) {
|
|
@@ -10475,6 +11013,8 @@ function isCullingIgnored(viewer, rego) {
|
|
|
10475
11013
|
rego.overrideShow != null ||
|
|
10476
11014
|
// Being dragged around right now, so its extent is changing faster than we could measure it.
|
|
10477
11015
|
rego.editing == true ||
|
|
11016
|
+
// Placed by the clock every frame, so no measurement of where it is stays true.
|
|
11017
|
+
rego.moving == true ||
|
|
10478
11018
|
// Part of a collection we did not create, eg. a geojson data source, which may have its own rules for
|
|
10479
11019
|
// what is in the scene. Our own per-menu-item data sources are fair game.
|
|
10480
11020
|
VisualsRegister.IsForeignCollection(rego) ||
|
|
@@ -11314,6 +11854,7 @@ var VisualsRegister;
|
|
|
11314
11854
|
}
|
|
11315
11855
|
get OnLabelGroupsChanged() { return this.labelGroupsChanged; }
|
|
11316
11856
|
constructor(params) {
|
|
11857
|
+
var _a, _b;
|
|
11317
11858
|
this.id = ObjectUtils.UId();
|
|
11318
11859
|
this.disposed = false;
|
|
11319
11860
|
this.rego = {};
|
|
@@ -11353,6 +11894,8 @@ var VisualsRegister;
|
|
|
11353
11894
|
this.menuItemSources = new Map();
|
|
11354
11895
|
// Set when the data source order no longer matches the zIndexes seen, so it is re-applied once.
|
|
11355
11896
|
this.sourceOrderDirty = false;
|
|
11897
|
+
// Stops following what is simulated, so labels can read it again when it changes.
|
|
11898
|
+
this.simulationRemoval = null;
|
|
11356
11899
|
this.labelGroupsChanged = new BruceEvent();
|
|
11357
11900
|
this.hoverRingState = {};
|
|
11358
11901
|
this.retiringHoverLabels = new Map();
|
|
@@ -11387,6 +11930,33 @@ var VisualsRegister;
|
|
|
11387
11930
|
this.cameraCullerDispose = VisualRegisterCuller.Monitor({
|
|
11388
11931
|
register: this
|
|
11389
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
|
+
}
|
|
11390
11960
|
}
|
|
11391
11961
|
/**
|
|
11392
11962
|
* Returns the collection a menu item's visuals belong in, creating its data source on first use.
|
|
@@ -12289,7 +12859,9 @@ var VisualsRegister;
|
|
|
12289
12859
|
(_b = this.viewer.scene) === null || _b === void 0 ? void 0 : _b.requestRender();
|
|
12290
12860
|
}
|
|
12291
12861
|
Dispose() {
|
|
12292
|
-
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;
|
|
12293
12865
|
CesiumEntityStyler.SetDimming(this.viewer, this.id, false);
|
|
12294
12866
|
this.ClearLabelHover();
|
|
12295
12867
|
clearTimeout(this.hoverRingReset);
|
|
@@ -12299,14 +12871,14 @@ var VisualsRegister;
|
|
|
12299
12871
|
EntityLabel.Detatch({ label });
|
|
12300
12872
|
}
|
|
12301
12873
|
this.retiringHoverLabels.clear();
|
|
12302
|
-
(
|
|
12874
|
+
(_b = this.labelGroups) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
12303
12875
|
this.labelGroupsChanged.Clear();
|
|
12304
12876
|
for (const regos of Object.values(this.rego)) {
|
|
12305
12877
|
for (const rego of regos)
|
|
12306
12878
|
EntityLabel.Detatch({ rego, force: true });
|
|
12307
12879
|
}
|
|
12308
12880
|
EntityLabel.SetContainer(this.viewer);
|
|
12309
|
-
(
|
|
12881
|
+
(_c = this.cameraCullerDispose) === null || _c === void 0 ? void 0 : _c.call(this, {
|
|
12310
12882
|
uncull: false
|
|
12311
12883
|
});
|
|
12312
12884
|
this.cameraCullerDispose = null;
|
|
@@ -12322,7 +12894,7 @@ var VisualsRegister;
|
|
|
12322
12894
|
this.disposed = true;
|
|
12323
12895
|
for (const record of Array.from(this.menuItemSources.values())) {
|
|
12324
12896
|
try {
|
|
12325
|
-
(
|
|
12897
|
+
(_e = (_d = this.viewer) === null || _d === void 0 ? void 0 : _d.dataSources) === null || _e === void 0 ? void 0 : _e.remove(record.source, true);
|
|
12326
12898
|
}
|
|
12327
12899
|
catch (e) {
|
|
12328
12900
|
console.error(e);
|
|
@@ -12331,7 +12903,7 @@ var VisualsRegister;
|
|
|
12331
12903
|
this.menuItemSources.clear();
|
|
12332
12904
|
// Hand every tileset's show flag back to its owner, holding whatever the owner last asked for.
|
|
12333
12905
|
for (const rego of Array.from(this.tilesets.values())) {
|
|
12334
|
-
(
|
|
12906
|
+
(_f = rego.gate) === null || _f === void 0 ? void 0 : _f.Release();
|
|
12335
12907
|
}
|
|
12336
12908
|
this.tilesets.clear();
|
|
12337
12909
|
}
|
|
@@ -12505,21 +13077,7 @@ var VisualsRegister;
|
|
|
12505
13077
|
changed = true;
|
|
12506
13078
|
}
|
|
12507
13079
|
if (editing) {
|
|
12508
|
-
|
|
12509
|
-
entity: rego.visual
|
|
12510
|
-
});
|
|
12511
|
-
for (let k = 0; k < parts.length; k++) {
|
|
12512
|
-
const part = parts[k];
|
|
12513
|
-
if (!(part instanceof Entity)) {
|
|
12514
|
-
continue;
|
|
12515
|
-
}
|
|
12516
|
-
const removalPending = VisualRegisterCuller.CancelQueuedSceneChange(part);
|
|
12517
|
-
const wasCulled = part[VisualRegisterCuller.VISUAL_CULL_KEY] == true || removalPending;
|
|
12518
|
-
delete part[VisualRegisterCuller.VISUAL_CULL_KEY];
|
|
12519
|
-
if (wasCulled && !IsCEntityInScene(this.viewer, part)) {
|
|
12520
|
-
AddCEntityToScene(this.viewer, part, rego.collection);
|
|
12521
|
-
}
|
|
12522
|
-
}
|
|
13080
|
+
this.restoreCulled(rego);
|
|
12523
13081
|
}
|
|
12524
13082
|
else {
|
|
12525
13083
|
VisualRegisterCuller.InvalidateBounds(rego.visual);
|
|
@@ -12531,6 +13089,56 @@ var VisualsRegister;
|
|
|
12531
13089
|
(_b = (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.scene) === null || _b === void 0 ? void 0 : _b.requestRender();
|
|
12532
13090
|
}
|
|
12533
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
|
+
}
|
|
12534
13142
|
SetSelected(params) {
|
|
12535
13143
|
var _a;
|
|
12536
13144
|
let { entityIds, selected, refreshIfSelected, requestRender, menuItemId, source } = params;
|
|
@@ -14023,12 +14631,41 @@ var VisualsRegister;
|
|
|
14023
14631
|
* Tracks per-entity rerender state for unsaved blob maintenance and stale API response suppression.
|
|
14024
14632
|
*/
|
|
14025
14633
|
class EntityReRenderMaintainState {
|
|
14026
|
-
constructor() {
|
|
14634
|
+
constructor(simulation, pointInTime) {
|
|
14635
|
+
this.simulation = simulation;
|
|
14636
|
+
this.pointInTime = pointInTime;
|
|
14027
14637
|
this.maintainedEntitiesById = {};
|
|
14028
14638
|
this.apiRevisionByEntityId = {};
|
|
14029
14639
|
this.skipApiRunByEntityId = {};
|
|
14030
14640
|
this.checkRunId = 0;
|
|
14031
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
|
+
}
|
|
14032
14669
|
setMaintainedEntities(entities) {
|
|
14033
14670
|
var _a;
|
|
14034
14671
|
for (let i = 0; i < entities.length; i++) {
|
|
@@ -14050,15 +14687,21 @@ class EntityReRenderMaintainState {
|
|
|
14050
14687
|
}
|
|
14051
14688
|
}
|
|
14052
14689
|
getMaintainedEntities(entityIds) {
|
|
14690
|
+
var _a;
|
|
14053
14691
|
const entities = [];
|
|
14054
14692
|
for (let i = 0; i < entityIds.length; i++) {
|
|
14055
14693
|
const id = entityIds[i];
|
|
14056
14694
|
if (!id) {
|
|
14057
14695
|
continue;
|
|
14058
14696
|
}
|
|
14059
|
-
|
|
14060
|
-
|
|
14061
|
-
|
|
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]);
|
|
14062
14705
|
}
|
|
14063
14706
|
}
|
|
14064
14707
|
return entities;
|
|
@@ -14115,7 +14758,7 @@ class EntityReRenderMaintainState {
|
|
|
14115
14758
|
}
|
|
14116
14759
|
filterCurrentApiEntities(params) {
|
|
14117
14760
|
const { entities, revisions, runId } = params;
|
|
14118
|
-
|
|
14761
|
+
const current = entities.filter((entity) => {
|
|
14119
14762
|
var _a, _b, _c;
|
|
14120
14763
|
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
14121
14764
|
if (!id) {
|
|
@@ -14124,8 +14767,12 @@ class EntityReRenderMaintainState {
|
|
|
14124
14767
|
if (runId != null && this.shouldSkipInRun(id, runId)) {
|
|
14125
14768
|
return false;
|
|
14126
14769
|
}
|
|
14770
|
+
if (this.isSimulated(id)) {
|
|
14771
|
+
return false;
|
|
14772
|
+
}
|
|
14127
14773
|
return ((_b = this.apiRevisionByEntityId[id]) !== null && _b !== void 0 ? _b : 0) === ((_c = revisions[id]) !== null && _c !== void 0 ? _c : 0);
|
|
14128
14774
|
});
|
|
14775
|
+
return this.atPoint(this.simulation && !this.simulation.IsEmpty ? current.map((entity) => this.simulation.Overlay(entity)) : current);
|
|
14129
14776
|
}
|
|
14130
14777
|
}
|
|
14131
14778
|
|
|
@@ -15561,7 +16208,7 @@ class HistoricGatherer {
|
|
|
15561
16208
|
this.cache = new HistoricRangeCache();
|
|
15562
16209
|
}
|
|
15563
16210
|
get Records() {
|
|
15564
|
-
return this.cache.GetRecords();
|
|
16211
|
+
return this.withSimulated(this.cache.GetRecords());
|
|
15565
16212
|
}
|
|
15566
16213
|
Clear() {
|
|
15567
16214
|
this.cache.Clear();
|
|
@@ -15585,8 +16232,9 @@ class HistoricGatherer {
|
|
|
15585
16232
|
*/
|
|
15586
16233
|
async Gather(entities) {
|
|
15587
16234
|
var _a;
|
|
15588
|
-
|
|
15589
|
-
|
|
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) };
|
|
15590
16238
|
}
|
|
15591
16239
|
const { viewer } = this.params;
|
|
15592
16240
|
const windowStart = new Date(viewer.clock.startTime.toString()).getTime();
|
|
@@ -15606,7 +16254,7 @@ class HistoricGatherer {
|
|
|
15606
16254
|
if (plan.coarse && !this.cache.CoversCoarse(plan.coarse.start, plan.coarse.stop)) {
|
|
15607
16255
|
const records = await this.request(plan.coarse.start, plan.coarse.stop, entities, plan.coarse.sample);
|
|
15608
16256
|
if (this.disposed) {
|
|
15609
|
-
return { fetched, recordsByIds: this.cache.GetRecords() };
|
|
16257
|
+
return { fetched, recordsByIds: this.withSimulated(this.cache.GetRecords(), entityIds) };
|
|
15610
16258
|
}
|
|
15611
16259
|
this.cache.Absorb(plan.coarse.start, this.holdTo(plan.coarse.stop, liveEdge, liveTail), records, true);
|
|
15612
16260
|
fetched = true;
|
|
@@ -15641,7 +16289,17 @@ class HistoricGatherer {
|
|
|
15641
16289
|
}
|
|
15642
16290
|
}
|
|
15643
16291
|
}
|
|
15644
|
-
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);
|
|
15645
16303
|
}
|
|
15646
16304
|
/*
|
|
15647
16305
|
* Returns how much of a range that was just read may be marked as held.
|
|
@@ -15676,7 +16334,7 @@ class HistoricGatherer {
|
|
|
15676
16334
|
}).then((res) => {
|
|
15677
16335
|
const records = res.recordsByIds || {};
|
|
15678
16336
|
if (!this.disposed && this.params.onRecords) {
|
|
15679
|
-
this.params.onRecords(records);
|
|
16337
|
+
this.params.onRecords(this.withSimulated(records, entityIds));
|
|
15680
16338
|
}
|
|
15681
16339
|
return records;
|
|
15682
16340
|
}).finally(() => {
|
|
@@ -15753,7 +16411,6 @@ var EntitiesRenderManager;
|
|
|
15753
16411
|
this.renderQueue = [];
|
|
15754
16412
|
this.renderQueueInterval = null;
|
|
15755
16413
|
this.sources = [];
|
|
15756
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
15757
16414
|
// Highly experimental flag to try improve rendering large sets of polygons and polylines.
|
|
15758
16415
|
// Many things are not supported when this is enabled.
|
|
15759
16416
|
this.useGeojson = false;
|
|
@@ -15773,6 +16430,14 @@ var EntitiesRenderManager;
|
|
|
15773
16430
|
*/
|
|
15774
16431
|
this.renderAsIndividualsChain = Promise.resolve();
|
|
15775
16432
|
const { viewer, apiGetter, monitor, item, register: visualsManager, sharedGetters, onSeriesDiscovered } = params;
|
|
16433
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation, () => {
|
|
16434
|
+
// Read at the scene's time only when the item follows history, the same choice its reads make.
|
|
16435
|
+
const bruceEntity = this.item.BruceEntity;
|
|
16436
|
+
if (!(bruceEntity === null || bruceEntity === void 0 ? void 0 : bruceEntity.historic) && !(bruceEntity === null || bruceEntity === void 0 ? void 0 : bruceEntity.historicAttrKey)) {
|
|
16437
|
+
return null;
|
|
16438
|
+
}
|
|
16439
|
+
return { timeMs: JulianDate.toDate(this.viewer.clock.currentTime).getTime(), attrKey: bruceEntity.historicAttrKey };
|
|
16440
|
+
});
|
|
15776
16441
|
this.viewer = viewer;
|
|
15777
16442
|
this.sharedGetters = sharedGetters;
|
|
15778
16443
|
this.monitor = monitor;
|
|
@@ -15786,7 +16451,8 @@ var EntitiesRenderManager;
|
|
|
15786
16451
|
getApi: () => this.apiGetter.getApi(),
|
|
15787
16452
|
getAttrKey: () => { var _a; return (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey; },
|
|
15788
16453
|
// A second either side, to take in records sitting exactly on the boundary.
|
|
15789
|
-
paddingMs: 1000
|
|
16454
|
+
paddingMs: 1000,
|
|
16455
|
+
simulation: params.simulation
|
|
15790
16456
|
});
|
|
15791
16457
|
this.useGeojson = item.renderAsGeojson == true;
|
|
15792
16458
|
if (item.enableClustering) {
|
|
@@ -15967,8 +16633,9 @@ var EntitiesRenderManager;
|
|
|
15967
16633
|
return;
|
|
15968
16634
|
}
|
|
15969
16635
|
this.updateAllowedTypeIDs(data.entityTypeSources, data.entities);
|
|
16636
|
+
// The getter answers from the API, so a simulated Entity in its answer is swapped for its blob.
|
|
15970
16637
|
if (isTagItem) {
|
|
15971
|
-
this.distributeForRender(data.entities.filter((entity) => {
|
|
16638
|
+
this.distributeForRender(this.reRenderState.withSimulated(data.entities.filter((entity) => {
|
|
15972
16639
|
let entityTags = entity.Bruce["Layer.ID"];
|
|
15973
16640
|
if (!entityTags) {
|
|
15974
16641
|
entityTags = [];
|
|
@@ -15976,10 +16643,10 @@ var EntitiesRenderManager;
|
|
|
15976
16643
|
return entityTags.some((tag) => {
|
|
15977
16644
|
return tagsToRender.indexOf(tag) !== -1;
|
|
15978
16645
|
});
|
|
15979
|
-
}));
|
|
16646
|
+
})));
|
|
15980
16647
|
}
|
|
15981
16648
|
else {
|
|
15982
|
-
this.distributeForRender(data.entities);
|
|
16649
|
+
this.distributeForRender(this.reRenderState.withSimulated(data.entities));
|
|
15983
16650
|
}
|
|
15984
16651
|
});
|
|
15985
16652
|
// Cesium itself handles single-visibility ranges very well.
|
|
@@ -16019,6 +16686,10 @@ var EntitiesRenderManager;
|
|
|
16019
16686
|
// Remove regos directly.
|
|
16020
16687
|
if (event.action === "D") {
|
|
16021
16688
|
for (const entityId of affectedIds) {
|
|
16689
|
+
// Deleted in the API, but drawn from its simulation until that is cleared.
|
|
16690
|
+
if (this.reRenderState.isSimulated(entityId)) {
|
|
16691
|
+
continue;
|
|
16692
|
+
}
|
|
16022
16693
|
this.visualsManager.RemoveRegos({
|
|
16023
16694
|
entityId,
|
|
16024
16695
|
menuItemId: this.item.id,
|
|
@@ -17148,7 +17819,6 @@ var EntitiesLoadedRenderManager;
|
|
|
17148
17819
|
// Highly experimental flag to try improve rendering large sets of polygons and polylines.
|
|
17149
17820
|
// Many things are not supported when this is enabled.
|
|
17150
17821
|
this.useGeojson = false;
|
|
17151
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
17152
17822
|
/**
|
|
17153
17823
|
* Our default path.
|
|
17154
17824
|
* We render each entity individually.
|
|
@@ -17158,6 +17828,7 @@ var EntitiesLoadedRenderManager;
|
|
|
17158
17828
|
*/
|
|
17159
17829
|
this.renderAsIndividualsChain = Promise.resolve();
|
|
17160
17830
|
const { viewer, apiGetter, monitor, item, register: visualsManager } = params;
|
|
17831
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation);
|
|
17161
17832
|
this.viewer = viewer;
|
|
17162
17833
|
this.apiGetter = apiGetter;
|
|
17163
17834
|
this.monitor = monitor;
|
|
@@ -17280,7 +17951,8 @@ var EntitiesLoadedRenderManager;
|
|
|
17280
17951
|
continue;
|
|
17281
17952
|
}
|
|
17282
17953
|
}
|
|
17283
|
-
|
|
17954
|
+
// The item carries its own Entities, so a simulated one among them is swapped for its blob.
|
|
17955
|
+
this.onGetterUpdate(this.reRenderState.withSimulated(entities));
|
|
17284
17956
|
});
|
|
17285
17957
|
this.getter.Start();
|
|
17286
17958
|
}
|
|
@@ -17927,8 +18599,15 @@ var EntitiesIdsRenderManager;
|
|
|
17927
18599
|
this.renderQueueActive = false;
|
|
17928
18600
|
this.renderQueue = [];
|
|
17929
18601
|
this.renderQueueForceFlags = [];
|
|
17930
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
17931
18602
|
const { viewer, apiGetter, monitor, item, register: visualsManager } = params;
|
|
18603
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation, () => {
|
|
18604
|
+
// Read at the scene's time only when the item follows history, the same choice its reads make.
|
|
18605
|
+
const bruceEntity = this.item.BruceEntity;
|
|
18606
|
+
if (!(bruceEntity === null || bruceEntity === void 0 ? void 0 : bruceEntity.historic) && !(bruceEntity === null || bruceEntity === void 0 ? void 0 : bruceEntity.historicAttrKey)) {
|
|
18607
|
+
return null;
|
|
18608
|
+
}
|
|
18609
|
+
return { timeMs: JulianDate.toDate(this.viewer.clock.currentTime).getTime(), attrKey: bruceEntity.historicAttrKey };
|
|
18610
|
+
});
|
|
17932
18611
|
this.sharedHistoric = params.sharedHistoric;
|
|
17933
18612
|
this.viewer = viewer;
|
|
17934
18613
|
this.apiGetter = apiGetter;
|
|
@@ -17941,7 +18620,8 @@ var EntitiesIdsRenderManager;
|
|
|
17941
18620
|
getApi: () => this.apiGetter.getApi(),
|
|
17942
18621
|
getAttrKey: () => { var _a; return (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey; },
|
|
17943
18622
|
// Padding either side of a requested range, for clock desync between us and the server.
|
|
17944
|
-
paddingMs: 15000
|
|
18623
|
+
paddingMs: 15000,
|
|
18624
|
+
simulation: params.simulation
|
|
17945
18625
|
});
|
|
17946
18626
|
if (this.item.enableClustering) {
|
|
17947
18627
|
this.clustering = new PointClustering(visualsManager, this.item.id, (_a = this.item) === null || _a === void 0 ? void 0 : _a.clustering);
|
|
@@ -18403,9 +19083,9 @@ var EntityRenderManager;
|
|
|
18403
19083
|
this.getter = null;
|
|
18404
19084
|
this.getterSub = null;
|
|
18405
19085
|
this.disposed = false;
|
|
18406
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
18407
19086
|
this.renderEntityChain = Promise.resolve();
|
|
18408
19087
|
const { viewer, apiGetter, monitor, item, register: visualsManager } = params;
|
|
19088
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation);
|
|
18409
19089
|
this.viewer = viewer;
|
|
18410
19090
|
this.apiGetter = apiGetter;
|
|
18411
19091
|
this.monitor = monitor;
|
|
@@ -18679,6 +19359,122 @@ var CodeLogicExceptions;
|
|
|
18679
19359
|
];
|
|
18680
19360
|
})(CodeLogicExceptions || (CodeLogicExceptions = {}));
|
|
18681
19361
|
|
|
19362
|
+
/**
|
|
19363
|
+
* The line drawn through where a moving thing has been, from its history, as a whole path or a fading trail.
|
|
19364
|
+
*/
|
|
19365
|
+
var HistoricTrail;
|
|
19366
|
+
(function (HistoricTrail) {
|
|
19367
|
+
const BANDS = 12;
|
|
19368
|
+
const SAMPLES = 96;
|
|
19369
|
+
const WIDTH_FAR = 1;
|
|
19370
|
+
const ALPHA_FAR = 0.05;
|
|
19371
|
+
// Above 1, so width and alpha hold near the head and give way further back.
|
|
19372
|
+
const WIDTH_CURVE = 1.4;
|
|
19373
|
+
const ALPHA_CURVE = 1.25;
|
|
19374
|
+
// How strongly a line is drawn where it passes behind the globe, against its own alpha.
|
|
19375
|
+
const BEHIND_ALPHA = 0.35;
|
|
19376
|
+
/**
|
|
19377
|
+
* The trail length a menu item asks for in its historicTrackSeconds, or null for the whole path.
|
|
19378
|
+
*/
|
|
19379
|
+
function GetTrailSeconds(item) {
|
|
19380
|
+
const seconds = Number(item === null || item === void 0 ? void 0 : item.historicTrackSeconds);
|
|
19381
|
+
return seconds > 0 ? seconds : null;
|
|
19382
|
+
}
|
|
19383
|
+
HistoricTrail.GetTrailSeconds = GetTrailSeconds;
|
|
19384
|
+
class Trail {
|
|
19385
|
+
constructor(params) {
|
|
19386
|
+
this.entities = [];
|
|
19387
|
+
this.memoTime = null;
|
|
19388
|
+
this.memo = [];
|
|
19389
|
+
this.viewer = params.viewer;
|
|
19390
|
+
const trailing = params.trailSeconds > 0 && Boolean(params.positionAt);
|
|
19391
|
+
if (!trailing) {
|
|
19392
|
+
this.add(params, params.color, params.width, () => { var _a; return (_a = params.getSeries()) !== null && _a !== void 0 ? _a : []; });
|
|
19393
|
+
return;
|
|
19394
|
+
}
|
|
19395
|
+
for (let band = 0; band < BANDS; band++) {
|
|
19396
|
+
// 0 at the head, 1 at the far end.
|
|
19397
|
+
const age = band / (BANDS - 1);
|
|
19398
|
+
const width = params.width - (params.width - WIDTH_FAR) * Math.pow(age, WIDTH_CURVE);
|
|
19399
|
+
const alpha = params.color.alpha - (params.color.alpha - ALPHA_FAR) * Math.pow(age, ALPHA_CURVE);
|
|
19400
|
+
this.add(params, params.color.withAlpha(alpha), Math.max(WIDTH_FAR, width), (time) => {
|
|
19401
|
+
return this.slice(this.sample(params, time), band);
|
|
19402
|
+
});
|
|
19403
|
+
}
|
|
19404
|
+
}
|
|
19405
|
+
/*
|
|
19406
|
+
* One polyline of the trail, its positions read from the scene's time.
|
|
19407
|
+
*/
|
|
19408
|
+
add(params, color, width, positions) {
|
|
19409
|
+
const entity = this.viewer.entities.add({
|
|
19410
|
+
id: ObjectUtils.UId(15),
|
|
19411
|
+
polyline: {
|
|
19412
|
+
positions: new CallbackProperty((time) => positions(time), false),
|
|
19413
|
+
width: width,
|
|
19414
|
+
material: color,
|
|
19415
|
+
clampToGround: params.clampToGround,
|
|
19416
|
+
// A path through the air follows no ellipsoid, so it is drawn as the straight runs it holds.
|
|
19417
|
+
arcType: params.clampToGround ? ArcType.GEODESIC : ArcType.NONE,
|
|
19418
|
+
// Drawn dimmer behind the globe rather than winking in and out against the terrain along the limb.
|
|
19419
|
+
depthFailMaterial: params.clampToGround ? undefined : color.withAlpha(color.alpha * BEHIND_ALPHA),
|
|
19420
|
+
zIndex: 0,
|
|
19421
|
+
classificationType: params.clampToGround ? ClassificationType.BOTH : undefined
|
|
19422
|
+
}
|
|
19423
|
+
});
|
|
19424
|
+
entity._noEdit = true;
|
|
19425
|
+
entity._noSelect = true;
|
|
19426
|
+
CesiumEntityStyler.SetDefaultColor({
|
|
19427
|
+
color: color,
|
|
19428
|
+
entity: entity,
|
|
19429
|
+
viewer: this.viewer,
|
|
19430
|
+
override: true,
|
|
19431
|
+
requestRender: false
|
|
19432
|
+
});
|
|
19433
|
+
this.entities.push(entity);
|
|
19434
|
+
}
|
|
19435
|
+
/*
|
|
19436
|
+
* The trail's positions at a time, newest last, kept for that time so every band reads the same set.
|
|
19437
|
+
*/
|
|
19438
|
+
sample(params, time) {
|
|
19439
|
+
var _a;
|
|
19440
|
+
if (this.memoTime && JulianDate.equals(this.memoTime, time)) {
|
|
19441
|
+
return this.memo;
|
|
19442
|
+
}
|
|
19443
|
+
this.memoTime = JulianDate.clone(time, (_a = this.memoTime) !== null && _a !== void 0 ? _a : new JulianDate());
|
|
19444
|
+
const nowMs = JulianDate.toDate(time).getTime();
|
|
19445
|
+
const spanMs = params.trailSeconds * 1000;
|
|
19446
|
+
const points = [];
|
|
19447
|
+
for (let i = 0; i <= SAMPLES; i++) {
|
|
19448
|
+
const pos3d = params.positionAt(nowMs - spanMs + spanMs * i / SAMPLES);
|
|
19449
|
+
if (pos3d) {
|
|
19450
|
+
points.push(pos3d);
|
|
19451
|
+
}
|
|
19452
|
+
}
|
|
19453
|
+
this.memo = points;
|
|
19454
|
+
return points;
|
|
19455
|
+
}
|
|
19456
|
+
/*
|
|
19457
|
+
* A band's run of the samples, counted back from the head, sharing its end point with the next band.
|
|
19458
|
+
*/
|
|
19459
|
+
slice(points, band) {
|
|
19460
|
+
if (points.length < 2) {
|
|
19461
|
+
return [];
|
|
19462
|
+
}
|
|
19463
|
+
const per = (points.length - 1) / BANDS;
|
|
19464
|
+
const end = points.length - 1 - Math.round(band * per);
|
|
19465
|
+
const start = points.length - 1 - Math.round((band + 1) * per);
|
|
19466
|
+
return start < end ? points.slice(Math.max(0, start), end + 1) : [];
|
|
19467
|
+
}
|
|
19468
|
+
Dispose() {
|
|
19469
|
+
for (const entity of this.entities) {
|
|
19470
|
+
RemoveCEntityFromScene(this.viewer, entity);
|
|
19471
|
+
}
|
|
19472
|
+
this.entities = [];
|
|
19473
|
+
}
|
|
19474
|
+
}
|
|
19475
|
+
HistoricTrail.Trail = Trail;
|
|
19476
|
+
})(HistoricTrail || (HistoricTrail = {}));
|
|
19477
|
+
|
|
18682
19478
|
class EntityGatherer {
|
|
18683
19479
|
get OnQueueProgress() {
|
|
18684
19480
|
if (!this._onQueueProgress) {
|
|
@@ -18686,7 +19482,11 @@ class EntityGatherer {
|
|
|
18686
19482
|
}
|
|
18687
19483
|
return this._onQueueProgress;
|
|
18688
19484
|
}
|
|
18689
|
-
|
|
19485
|
+
/**
|
|
19486
|
+
* @param simulation what callers simulate in place of API data, used where this gatherer has no override.
|
|
19487
|
+
*/
|
|
19488
|
+
constructor(api, viewer, emitEntities, simulation) {
|
|
19489
|
+
this.simulation = simulation;
|
|
18690
19490
|
this.disposed = false;
|
|
18691
19491
|
this.expandSources = false;
|
|
18692
19492
|
this.historic = null;
|
|
@@ -19263,15 +20063,19 @@ class EntityGatherer {
|
|
|
19263
20063
|
}
|
|
19264
20064
|
}
|
|
19265
20065
|
}
|
|
20066
|
+
// A historic read is as at the scene's time, and so is any simulated record laid over it.
|
|
20067
|
+
const rTimeMs = new Date(rTime).getTime();
|
|
20068
|
+
const atPoint = (entity) => this.historic && this.simulation ? this.simulation.ApplyAt(entity, rTimeMs) : entity;
|
|
19266
20069
|
for (const entityId of requestedBatch || []) {
|
|
20070
|
+
// A caller's own override is an unsaved edit, newer than any simulation, so it is used as is.
|
|
19267
20071
|
const override = this.entityDataOverrides.get(entityId);
|
|
19268
20072
|
if (override) {
|
|
19269
20073
|
resolvedEntities.push(override);
|
|
19270
20074
|
continue;
|
|
19271
20075
|
}
|
|
19272
|
-
const found = foundById.get(entityId);
|
|
20076
|
+
const found = this.simulation ? this.simulation.Resolve(entityId, foundById.get(entityId)) : foundById.get(entityId);
|
|
19273
20077
|
if (found) {
|
|
19274
|
-
resolvedEntities.push(found);
|
|
20078
|
+
resolvedEntities.push(atPoint(found));
|
|
19275
20079
|
continue;
|
|
19276
20080
|
}
|
|
19277
20081
|
resolvedEntities.push(this.createFallbackEntity(entityId));
|
|
@@ -19635,7 +20439,7 @@ class TilesetStyler {
|
|
|
19635
20439
|
this.styleTilesetFeatureFullData(feature, entity, eTags);
|
|
19636
20440
|
}
|
|
19637
20441
|
}
|
|
19638
|
-
});
|
|
20442
|
+
}, params.simulation);
|
|
19639
20443
|
// Only Entities Sets bake coordinates into their features, so for any other source this
|
|
19640
20444
|
// resolves nothing and the gather stays in insertion order.
|
|
19641
20445
|
this.entityGatherer.SetViewMonitor(this.monitor);
|
|
@@ -21165,6 +21969,9 @@ var TilesetCadRenderManager;
|
|
|
21165
21969
|
return this.modelTreeUpdate;
|
|
21166
21970
|
}
|
|
21167
21971
|
constructor(params) {
|
|
21972
|
+
this.simulationRemoval = null;
|
|
21973
|
+
// Where the tileset stands by its own record, so a cleared simulation puts it back without a refetch.
|
|
21974
|
+
this.restCoords = null;
|
|
21168
21975
|
this.disposed = false;
|
|
21169
21976
|
this.modelSpace = false;
|
|
21170
21977
|
this.cTileset = null;
|
|
@@ -21202,7 +22009,7 @@ var TilesetCadRenderManager;
|
|
|
21202
22009
|
this.historicAnimation = null;
|
|
21203
22010
|
this.historicGatherer = null;
|
|
21204
22011
|
// The trail through the root's own movement, which describes the whole assembly.
|
|
21205
|
-
this.
|
|
22012
|
+
this.trail = null;
|
|
21206
22013
|
this.historicPossesLoadingProm = null;
|
|
21207
22014
|
// Queue of loaded in features that we haven't processed yet.
|
|
21208
22015
|
this.featureQueue = [];
|
|
@@ -21216,6 +22023,7 @@ var TilesetCadRenderManager;
|
|
|
21216
22023
|
this.featurePropCache = new Map();
|
|
21217
22024
|
this.featurePropsChecked = 0;
|
|
21218
22025
|
const { viewer, register: visualsManager, getters, item, modelSpace, initQueue } = params;
|
|
22026
|
+
this.simulation = params.simulation;
|
|
21219
22027
|
this.viewer = viewer;
|
|
21220
22028
|
this.getters = getters;
|
|
21221
22029
|
this.item = item;
|
|
@@ -21380,7 +22188,7 @@ var TilesetCadRenderManager;
|
|
|
21380
22188
|
historicPoint: this.viewer.clock.currentTime.toString(),
|
|
21381
22189
|
api: api
|
|
21382
22190
|
});
|
|
21383
|
-
coords = coordsFromHistoricEntity(root);
|
|
22191
|
+
coords = coordsFromHistoricEntity(this.atClock(root));
|
|
21384
22192
|
}
|
|
21385
22193
|
catch (e) {
|
|
21386
22194
|
console.error(e);
|
|
@@ -21421,6 +22229,10 @@ var TilesetCadRenderManager;
|
|
|
21421
22229
|
this.doDispose();
|
|
21422
22230
|
return;
|
|
21423
22231
|
}
|
|
22232
|
+
this.restCoords = coords;
|
|
22233
|
+
if (this.simulatedRootCoords()) {
|
|
22234
|
+
this.applyCoords(tileset, this.simulatedRootCoords());
|
|
22235
|
+
}
|
|
21424
22236
|
this.viewer.scene.requestRender();
|
|
21425
22237
|
TilesetRenderEngine.OnTilesetReady(this.cTileset).then(() => {
|
|
21426
22238
|
var _a, _b, _c;
|
|
@@ -21440,6 +22252,7 @@ var TilesetCadRenderManager;
|
|
|
21440
22252
|
}
|
|
21441
22253
|
this.onCTilesetLoad();
|
|
21442
22254
|
this.styler.Init({
|
|
22255
|
+
simulation: this.simulation,
|
|
21443
22256
|
viewer: this.viewer,
|
|
21444
22257
|
// Default API instead of the account one.
|
|
21445
22258
|
// Records are driven by the account loading it instead of the source account.
|
|
@@ -21455,6 +22268,7 @@ var TilesetCadRenderManager;
|
|
|
21455
22268
|
});
|
|
21456
22269
|
this.viewer.scene.requestRender();
|
|
21457
22270
|
// Monitor scene time changes and update the root Entity.
|
|
22271
|
+
this.followSimulation(tileset);
|
|
21458
22272
|
this.viewerDateTimeSub(tileset);
|
|
21459
22273
|
}
|
|
21460
22274
|
catch (e) {
|
|
@@ -21510,7 +22324,7 @@ var TilesetCadRenderManager;
|
|
|
21510
22324
|
*/
|
|
21511
22325
|
applyRootTrack() {
|
|
21512
22326
|
var _a;
|
|
21513
|
-
if (!this.item.historicDrawTrack || !this.historicAnimation || this.
|
|
22327
|
+
if (!this.item.historicDrawTrack || !this.historicAnimation || this.trail) {
|
|
21514
22328
|
return;
|
|
21515
22329
|
}
|
|
21516
22330
|
const trackStyle = EntityRenderEngine.GetTrackStyle({
|
|
@@ -21520,26 +22334,14 @@ var TilesetCadRenderManager;
|
|
|
21520
22334
|
if (!trackStyle) {
|
|
21521
22335
|
return;
|
|
21522
22336
|
}
|
|
21523
|
-
this
|
|
21524
|
-
|
|
21525
|
-
polyline: {
|
|
21526
|
-
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),
|
|
21527
|
-
width: trackStyle.width,
|
|
21528
|
-
material: trackStyle.color,
|
|
21529
|
-
clampToGround: EntityRenderEngine.GetHeightRefPolyline(Manager.GetRecordHeightRef(this.item))
|
|
21530
|
-
== HeightReference.CLAMP_TO_GROUND,
|
|
21531
|
-
zIndex: 0,
|
|
21532
|
-
classificationType: ClassificationType.BOTH
|
|
21533
|
-
}
|
|
21534
|
-
});
|
|
21535
|
-
this.trackEntity._noEdit = true;
|
|
21536
|
-
this.trackEntity._noSelect = true;
|
|
21537
|
-
CesiumEntityStyler.SetDefaultColor({
|
|
21538
|
-
color: trackStyle.color,
|
|
21539
|
-
entity: this.trackEntity,
|
|
22337
|
+
// The series has no position at an arbitrary time, so this draws the whole path rather than a trail.
|
|
22338
|
+
this.trail = new HistoricTrail.Trail({
|
|
21540
22339
|
viewer: this.viewer,
|
|
21541
|
-
|
|
21542
|
-
|
|
22340
|
+
color: trackStyle.color,
|
|
22341
|
+
width: trackStyle.width,
|
|
22342
|
+
clampToGround: EntityRenderEngine.GetHeightRefPolyline(Manager.GetRecordHeightRef(this.item))
|
|
22343
|
+
== HeightReference.CLAMP_TO_GROUND,
|
|
22344
|
+
getSeries: () => { var _a, _b; return (_b = (_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.GetSeries()) !== null && _b !== void 0 ? _b : []; }
|
|
21543
22345
|
});
|
|
21544
22346
|
}
|
|
21545
22347
|
/**
|
|
@@ -21592,7 +22394,7 @@ var TilesetCadRenderManager;
|
|
|
21592
22394
|
}
|
|
21593
22395
|
// Returns null (fall back to a normal Dispose()) if the tileset hasn't finished loading yet.
|
|
21594
22396
|
PrepareHandoff() {
|
|
21595
|
-
var _a, _b, _c, _d;
|
|
22397
|
+
var _a, _b, _c, _d, _e;
|
|
21596
22398
|
if (this.disposed || !this.cTileset || this.cTileset.isDestroyed()) {
|
|
21597
22399
|
return null;
|
|
21598
22400
|
}
|
|
@@ -21610,9 +22412,11 @@ var TilesetCadRenderManager;
|
|
|
21610
22412
|
this.handoffSourceMenuItemId = null;
|
|
21611
22413
|
// Not transferred, the receiving manager sets up its own fresh copy if needed.
|
|
21612
22414
|
this.viewerDateTimeDispose();
|
|
21613
|
-
(_b = this.
|
|
21614
|
-
|
|
21615
|
-
(
|
|
22415
|
+
(_b = this.simulationRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
22416
|
+
this.simulationRemoval = null;
|
|
22417
|
+
(_c = this.styler) === null || _c === void 0 ? void 0 : _c.Dispose();
|
|
22418
|
+
(_d = this.tileLoadRemoval) === null || _d === void 0 ? void 0 : _d.call(this);
|
|
22419
|
+
(_e = this.tileUnloadRemoval) === null || _e === void 0 ? void 0 : _e.call(this);
|
|
21616
22420
|
this.tileLoadRemoval = null;
|
|
21617
22421
|
this.tileUnloadRemoval = null;
|
|
21618
22422
|
const payload = {
|
|
@@ -21633,7 +22437,7 @@ var TilesetCadRenderManager;
|
|
|
21633
22437
|
// Takes ownership of a PrepareHandoff() payload instead of loading via Init().
|
|
21634
22438
|
// Then re-parents every already-registered rego to this menu item and re-runs styling.
|
|
21635
22439
|
AdoptHandoff(payload) {
|
|
21636
|
-
var _a, _b, _c, _d;
|
|
22440
|
+
var _a, _b, _c, _d, _e;
|
|
21637
22441
|
this.cTileset = payload.cTileset;
|
|
21638
22442
|
this.tileset = payload.tileset;
|
|
21639
22443
|
this.rootId = payload.rootId;
|
|
@@ -21664,6 +22468,7 @@ var TilesetCadRenderManager;
|
|
|
21664
22468
|
// Same visuals, same registrations so just re-keyed onto this menu item.
|
|
21665
22469
|
this.onCTilesetLoad();
|
|
21666
22470
|
this.styler.Init({
|
|
22471
|
+
simulation: this.simulation,
|
|
21667
22472
|
viewer: this.viewer,
|
|
21668
22473
|
api: this.getters.GetBruceApi(),
|
|
21669
22474
|
cTileset: this.cTileset,
|
|
@@ -21697,7 +22502,9 @@ var TilesetCadRenderManager;
|
|
|
21697
22502
|
}
|
|
21698
22503
|
});
|
|
21699
22504
|
this.viewer.scene.requestRender();
|
|
21700
|
-
if (
|
|
22505
|
+
if (this.tileset) {
|
|
22506
|
+
this.restCoords = (_d = this.restCoords) !== null && _d !== void 0 ? _d : (_e = this.cTileset) === null || _e === void 0 ? void 0 : _e._bruceCoords;
|
|
22507
|
+
this.followSimulation(this.tileset);
|
|
21701
22508
|
this.viewerDateTimeSub(this.tileset);
|
|
21702
22509
|
}
|
|
21703
22510
|
}
|
|
@@ -22285,7 +23092,7 @@ var TilesetCadRenderManager;
|
|
|
22285
23092
|
this.doDispose();
|
|
22286
23093
|
}
|
|
22287
23094
|
doDispose() {
|
|
22288
|
-
var _a, _b, _c;
|
|
23095
|
+
var _a, _b, _c, _d;
|
|
22289
23096
|
if (this.featureQueueInterval) {
|
|
22290
23097
|
clearInterval(this.featureQueueInterval);
|
|
22291
23098
|
this.featureQueueInterval = null;
|
|
@@ -22320,6 +23127,8 @@ var TilesetCadRenderManager;
|
|
|
22320
23127
|
this.handoffSourceMenuItemId = null;
|
|
22321
23128
|
}
|
|
22322
23129
|
this.viewerDateTimeDispose();
|
|
23130
|
+
(_d = this.simulationRemoval) === null || _d === void 0 ? void 0 : _d.call(this);
|
|
23131
|
+
this.simulationRemoval = null;
|
|
22323
23132
|
}
|
|
22324
23133
|
async ReRender(params) {
|
|
22325
23134
|
let { entityIds, force, entities, maintain } = params;
|
|
@@ -22345,8 +23154,11 @@ var TilesetCadRenderManager;
|
|
|
22345
23154
|
* @param tileset
|
|
22346
23155
|
*/
|
|
22347
23156
|
viewerDateTimeSub(tileset) {
|
|
22348
|
-
var _a;
|
|
22349
|
-
|
|
23157
|
+
var _a, _b;
|
|
23158
|
+
// An item that is not historic still follows the root's simulated records, once there are some.
|
|
23159
|
+
const historic = Boolean((_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historic);
|
|
23160
|
+
const simulated = Boolean(this.rootId && ((_b = this.simulation) === null || _b === void 0 ? void 0 : _b.GetRecords(this.rootId).length));
|
|
23161
|
+
if ((!historic && !simulated) || this.historicGatherer || this.viewerDateTimeChangeRemoval) {
|
|
22350
23162
|
return;
|
|
22351
23163
|
}
|
|
22352
23164
|
const accountId = this.accountIdForRecords();
|
|
@@ -22375,6 +23187,8 @@ var TilesetCadRenderManager;
|
|
|
22375
23187
|
// Time padding in milliseconds (15 seconds).
|
|
22376
23188
|
// Helps account for desync between client and server.
|
|
22377
23189
|
paddingMs: 15000,
|
|
23190
|
+
simulation: this.simulation,
|
|
23191
|
+
simulatedOnly: !historic,
|
|
22378
23192
|
onRecords: (recordsByIds) => {
|
|
22379
23193
|
var _a;
|
|
22380
23194
|
const records = recordsByIds[this.rootId];
|
|
@@ -22402,6 +23216,7 @@ var TilesetCadRenderManager;
|
|
|
22402
23216
|
*/
|
|
22403
23217
|
const getInitialPosses = async () => {
|
|
22404
23218
|
this.historicPossesLoadingProm = new Promise(async (res) => {
|
|
23219
|
+
var _a;
|
|
22405
23220
|
try {
|
|
22406
23221
|
if (this.disposed) {
|
|
22407
23222
|
res(false);
|
|
@@ -22414,11 +23229,16 @@ var TilesetCadRenderManager;
|
|
|
22414
23229
|
return;
|
|
22415
23230
|
}
|
|
22416
23231
|
// Also request the current position in case its not in the range.
|
|
22417
|
-
|
|
23232
|
+
// A simulated root, or an item that is not historic, has no current record to ask the API for.
|
|
23233
|
+
if (!historic || ((_a = this.simulation) === null || _a === void 0 ? void 0 : _a.HasEntity(this.rootId))) {
|
|
23234
|
+
res(positions);
|
|
23235
|
+
return;
|
|
23236
|
+
}
|
|
23237
|
+
const entity = this.atClock((await Entity$1.Get({
|
|
22418
23238
|
entityId: this.rootId,
|
|
22419
23239
|
historicPoint: this.viewer.clock.currentTime.toString(),
|
|
22420
23240
|
api: api
|
|
22421
|
-
});
|
|
23241
|
+
})).entity);
|
|
22422
23242
|
if (this.disposed || !entity) {
|
|
22423
23243
|
res(false);
|
|
22424
23244
|
return;
|
|
@@ -22498,14 +23318,15 @@ var TilesetCadRenderManager;
|
|
|
22498
23318
|
}
|
|
22499
23319
|
});
|
|
22500
23320
|
this.viewerDateTimeChangeRemoval = () => {
|
|
23321
|
+
var _a, _b;
|
|
22501
23322
|
if (this.historicAnimation) {
|
|
22502
23323
|
this.historicAnimation.stop();
|
|
22503
23324
|
this.historicAnimation = null;
|
|
22504
23325
|
}
|
|
22505
|
-
|
|
22506
|
-
|
|
22507
|
-
|
|
22508
|
-
|
|
23326
|
+
(_a = this.historicGatherer) === null || _a === void 0 ? void 0 : _a.Dispose();
|
|
23327
|
+
this.historicGatherer = null;
|
|
23328
|
+
(_b = this.trail) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
23329
|
+
this.trail = null;
|
|
22509
23330
|
if (clockTickRemoval) {
|
|
22510
23331
|
clockTickRemoval();
|
|
22511
23332
|
clockTickRemoval = null;
|
|
@@ -22513,10 +23334,84 @@ var TilesetCadRenderManager;
|
|
|
22513
23334
|
};
|
|
22514
23335
|
});
|
|
22515
23336
|
}
|
|
22516
|
-
|
|
23337
|
+
/*
|
|
23338
|
+
* Keeps the tileset in line with what is simulated for its root Entity.
|
|
23339
|
+
*/
|
|
23340
|
+
followSimulation(tileset) {
|
|
23341
|
+
if (this.simulationRemoval || !this.simulation) {
|
|
23342
|
+
return;
|
|
23343
|
+
}
|
|
23344
|
+
this.simulationRemoval = this.simulation.OnChanged.Subscribe((change) => {
|
|
23345
|
+
var _a;
|
|
23346
|
+
if (this.disposed || !this.rootId || !change.entityIds.includes(this.rootId)) {
|
|
23347
|
+
return;
|
|
23348
|
+
}
|
|
23349
|
+
if (change.records) {
|
|
23350
|
+
this.regatherRoot(tileset);
|
|
23351
|
+
}
|
|
23352
|
+
// A simulated root is where the tileset stands outside its history; recorded positions still win.
|
|
23353
|
+
if (change.entities && !((_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.getDateRange().minDate)) {
|
|
23354
|
+
this.applyRootRest(tileset);
|
|
23355
|
+
}
|
|
23356
|
+
});
|
|
23357
|
+
}
|
|
23358
|
+
/*
|
|
23359
|
+
* Re-reads the root's history after its simulated records changed, following the clock if it was not.
|
|
23360
|
+
*/
|
|
23361
|
+
async regatherRoot(tileset) {
|
|
22517
23362
|
var _a;
|
|
23363
|
+
if (!this.historicGatherer) {
|
|
23364
|
+
this.viewerDateTimeSub(tileset);
|
|
23365
|
+
return;
|
|
23366
|
+
}
|
|
23367
|
+
await this.historicPossesLoadingProm;
|
|
23368
|
+
const { recordsByIds } = await this.historicGatherer.Gather([{ Bruce: { ID: this.rootId } }]);
|
|
23369
|
+
if (this.disposed) {
|
|
23370
|
+
return;
|
|
23371
|
+
}
|
|
23372
|
+
const posses = Manager.HistoricPossesFor({ viewer: this.viewer, item: this.item, records: recordsByIds[this.rootId] || [] });
|
|
23373
|
+
(_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.replacePositions(posses);
|
|
23374
|
+
if (!posses.length) {
|
|
23375
|
+
this.applyRootRest(tileset);
|
|
23376
|
+
}
|
|
23377
|
+
}
|
|
23378
|
+
/*
|
|
23379
|
+
* The root as read at the scene's time, with any simulated record at that time laid over it.
|
|
23380
|
+
*/
|
|
23381
|
+
atClock(root) {
|
|
23382
|
+
return this.simulation && root
|
|
23383
|
+
? this.simulation.ApplyAt(root, JulianDate.toDate(this.viewer.clock.currentTime).getTime())
|
|
23384
|
+
: root;
|
|
23385
|
+
}
|
|
23386
|
+
/*
|
|
23387
|
+
* Stands the tileset where its root is outside history: the simulated root, else the root's own record.
|
|
23388
|
+
*/
|
|
23389
|
+
applyRootRest(tileset) {
|
|
23390
|
+
var _a;
|
|
23391
|
+
this.applyCoords(tileset, (_a = this.simulatedRootCoords()) !== null && _a !== void 0 ? _a : this.restCoords);
|
|
23392
|
+
}
|
|
23393
|
+
/*
|
|
23394
|
+
* Where a simulated root puts the tileset, or null; a patch only places it when it names a whole location.
|
|
23395
|
+
*/
|
|
23396
|
+
simulatedRootCoords() {
|
|
23397
|
+
var _a, _b;
|
|
23398
|
+
const simulation = this.rootId ? this.simulation : null;
|
|
23399
|
+
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);
|
|
23400
|
+
const location = (_b = root === null || root === void 0 ? void 0 : root.Bruce) === null || _b === void 0 ? void 0 : _b.Location;
|
|
23401
|
+
if ((location === null || location === void 0 ? void 0 : location.latitude) == null || (location === null || location === void 0 ? void 0 : location.longitude) == null) {
|
|
23402
|
+
return null;
|
|
23403
|
+
}
|
|
23404
|
+
const pos3d = Cartesian3.fromDegrees(+location.longitude, +location.latitude, EnsureNumber(location.altitude, 0));
|
|
23405
|
+
const transform = root.Bruce.Transform;
|
|
23406
|
+
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);
|
|
23407
|
+
}
|
|
23408
|
+
viewerDateTimeDispose() {
|
|
23409
|
+
var _a, _b;
|
|
22518
23410
|
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
22519
23411
|
this.viewerDateTimeChangeRemoval = null;
|
|
23412
|
+
// Made before the first positions land, so it can outlive a removal that was never set.
|
|
23413
|
+
(_b = this.historicGatherer) === null || _b === void 0 ? void 0 : _b.Dispose();
|
|
23414
|
+
this.historicGatherer = null;
|
|
22520
23415
|
}
|
|
22521
23416
|
/**
|
|
22522
23417
|
* Updates the Tileset with latest coordinates.
|
|
@@ -23659,11 +24554,11 @@ var DataLabRenderManager;
|
|
|
23659
24554
|
this.viewMonitorRemoval = null;
|
|
23660
24555
|
this.renderQueue = [];
|
|
23661
24556
|
this.renderQueueInterval = null;
|
|
23662
|
-
this.reRenderState = new EntityReRenderMaintainState();
|
|
23663
24557
|
this.zoomControl = [];
|
|
23664
24558
|
this.queryLoadId = 0;
|
|
23665
24559
|
this.renderDataLabEntitiesChain = Promise.resolve();
|
|
23666
24560
|
const { viewer, item, apiGetter, monitor, visualsRegister } = params;
|
|
24561
|
+
this.reRenderState = new EntityReRenderMaintainState(params.simulation);
|
|
23667
24562
|
this.viewer = viewer;
|
|
23668
24563
|
this.item = item;
|
|
23669
24564
|
this.apiGetter = apiGetter;
|
|
@@ -23760,7 +24655,8 @@ var DataLabRenderManager;
|
|
|
23760
24655
|
if (!((_a = data === null || data === void 0 ? void 0 : data.entities) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
23761
24656
|
return;
|
|
23762
24657
|
}
|
|
23763
|
-
|
|
24658
|
+
// The getter answers from the API, so a simulated Entity in its answer is swapped for its blob.
|
|
24659
|
+
this.distributeForRender(this.reRenderState.withSimulated(data.entities));
|
|
23764
24660
|
});
|
|
23765
24661
|
}
|
|
23766
24662
|
unsetGetter() {
|
|
@@ -25511,6 +26407,7 @@ var TilesetEntitiesRenderManager;
|
|
|
25511
26407
|
this.featurePropCache = new Map();
|
|
25512
26408
|
this.featurePropsChecked = 0;
|
|
25513
26409
|
const { viewer, register: visualsManager, getters: apiGetter, item, initQueue, monitor } = params;
|
|
26410
|
+
this.simulation = params.simulation;
|
|
25514
26411
|
this.monitor = monitor;
|
|
25515
26412
|
this.viewer = viewer;
|
|
25516
26413
|
this.getters = apiGetter;
|
|
@@ -25611,6 +26508,7 @@ var TilesetEntitiesRenderManager;
|
|
|
25611
26508
|
if (Manager.NeedsStyler(this.item)) {
|
|
25612
26509
|
const api = this.getters.GetBruceApi();
|
|
25613
26510
|
this.styler.Init({
|
|
26511
|
+
simulation: this.simulation,
|
|
25614
26512
|
viewer: this.viewer,
|
|
25615
26513
|
api: api,
|
|
25616
26514
|
cTileset: this.cTileset,
|
|
@@ -25968,6 +26866,7 @@ var TilesetEntitiesRenderManager;
|
|
|
25968
26866
|
const needsStyler = Manager.NeedsStyler(this.item);
|
|
25969
26867
|
if (needsStyler) {
|
|
25970
26868
|
this.styler.Init({
|
|
26869
|
+
simulation: this.simulation,
|
|
25971
26870
|
viewer: this.viewer,
|
|
25972
26871
|
api: this.getters.GetBruceApi(),
|
|
25973
26872
|
cTileset: this.cTileset,
|
|
@@ -26659,6 +27558,7 @@ var TilesetArbRenderManager;
|
|
|
26659
27558
|
// LCC object if we're using XGrids to render LCC data.
|
|
26660
27559
|
this.lccObject = null;
|
|
26661
27560
|
this.viewer = params.viewer;
|
|
27561
|
+
this.simulation = params.simulation;
|
|
26662
27562
|
this.getters = params.getters;
|
|
26663
27563
|
this.visualsManager = params.register;
|
|
26664
27564
|
// We modify the object due to a lot of backwards compatibility.
|
|
@@ -26893,6 +27793,7 @@ var TilesetArbRenderManager;
|
|
|
26893
27793
|
this.item.Type == MenuItem.EType.IonTileset) {
|
|
26894
27794
|
const api = this.getters.GetBruceApi();
|
|
26895
27795
|
this.styler.Init({
|
|
27796
|
+
simulation: this.simulation,
|
|
26896
27797
|
viewer: this.viewer,
|
|
26897
27798
|
api: api,
|
|
26898
27799
|
cTileset: this.cTileset,
|
|
@@ -27234,14 +28135,32 @@ var RelationsRenderManager;
|
|
|
27234
28135
|
}
|
|
27235
28136
|
;
|
|
27236
28137
|
constructor(params) {
|
|
28138
|
+
var _a, _b;
|
|
27237
28139
|
// If true, this menu item is disposed and should not be used.
|
|
27238
28140
|
// Any rendering will be ignored.
|
|
27239
28141
|
this.disposed = false;
|
|
28142
|
+
this.simulationRemoval = null;
|
|
28143
|
+
this.FollowsSimulation = true;
|
|
27240
28144
|
const { apiGetter, item, register, viewer } = params;
|
|
27241
28145
|
this.apiGetter = apiGetter;
|
|
27242
28146
|
this.item = item;
|
|
27243
28147
|
this.register = register;
|
|
27244
28148
|
this.viewer = viewer;
|
|
28149
|
+
this.simulation = params.simulation;
|
|
28150
|
+
// Ends are not this item's own Entities, so it watches the store itself rather than wait to be asked.
|
|
28151
|
+
this.simulationRemoval = (_b = (_a = this.simulation) === null || _a === void 0 ? void 0 : _a.OnChanged.Subscribe((change) => {
|
|
28152
|
+
if (this.disposed) {
|
|
28153
|
+
return;
|
|
28154
|
+
}
|
|
28155
|
+
const relations = RelationRenderEngine.TakeRelationsTouching({
|
|
28156
|
+
visualRegister: this.register,
|
|
28157
|
+
menuItemId: this.item.id,
|
|
28158
|
+
entityIds: change.entityIds
|
|
28159
|
+
});
|
|
28160
|
+
if (relations.length) {
|
|
28161
|
+
this.onGetterUpdate(relations);
|
|
28162
|
+
}
|
|
28163
|
+
})) !== null && _b !== void 0 ? _b : null;
|
|
27245
28164
|
}
|
|
27246
28165
|
/**
|
|
27247
28166
|
* Starts rendering the menu item.
|
|
@@ -27310,10 +28229,13 @@ var RelationsRenderManager;
|
|
|
27310
28229
|
return items;
|
|
27311
28230
|
}
|
|
27312
28231
|
Dispose() {
|
|
28232
|
+
var _a;
|
|
27313
28233
|
if (this.disposed) {
|
|
27314
28234
|
return;
|
|
27315
28235
|
}
|
|
27316
28236
|
this.disposed = true;
|
|
28237
|
+
(_a = this.simulationRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
28238
|
+
this.simulationRemoval = null;
|
|
27317
28239
|
this.register.RemoveRegos({
|
|
27318
28240
|
menuItemId: this.item.id
|
|
27319
28241
|
});
|
|
@@ -27552,7 +28474,8 @@ var RelationsRenderManager;
|
|
|
27552
28474
|
menuItemId: this.item.id,
|
|
27553
28475
|
relations: relations,
|
|
27554
28476
|
viewer: this.viewer,
|
|
27555
|
-
visualRegister: this.register
|
|
28477
|
+
visualRegister: this.register,
|
|
28478
|
+
simulation: this.simulation
|
|
27556
28479
|
});
|
|
27557
28480
|
if (this.disposed) {
|
|
27558
28481
|
this.register.RemoveRegos({
|
|
@@ -27835,9 +28758,12 @@ var LegacyRelationsRenderManager;
|
|
|
27835
28758
|
}
|
|
27836
28759
|
;
|
|
27837
28760
|
constructor(params) {
|
|
28761
|
+
var _a, _b;
|
|
27838
28762
|
// If true, this menu item is disposed and should not be used.
|
|
27839
28763
|
// Any rendering will be ignored.
|
|
27840
28764
|
this.disposed = false;
|
|
28765
|
+
this.simulationRemoval = null;
|
|
28766
|
+
this.FollowsSimulation = true;
|
|
27841
28767
|
// Record of the currently drawn entity IDs.
|
|
27842
28768
|
// This is to avoid re-queueing already drawn entities when Init is called multiple times.
|
|
27843
28769
|
this.drawnIds = [];
|
|
@@ -27846,6 +28772,21 @@ var LegacyRelationsRenderManager;
|
|
|
27846
28772
|
this.item = item;
|
|
27847
28773
|
this.register = register;
|
|
27848
28774
|
this.viewer = viewer;
|
|
28775
|
+
this.simulation = params.simulation;
|
|
28776
|
+
// Ends are not this item's own Entities, so it watches the store itself rather than wait to be asked.
|
|
28777
|
+
this.simulationRemoval = (_b = (_a = this.simulation) === null || _a === void 0 ? void 0 : _a.OnChanged.Subscribe((change) => {
|
|
28778
|
+
if (this.disposed) {
|
|
28779
|
+
return;
|
|
28780
|
+
}
|
|
28781
|
+
const relations = RelationRenderEngine.TakeRelationsTouching({
|
|
28782
|
+
visualRegister: this.register,
|
|
28783
|
+
menuItemId: this.item.id,
|
|
28784
|
+
entityIds: change.entityIds
|
|
28785
|
+
});
|
|
28786
|
+
if (relations.length) {
|
|
28787
|
+
this.onGetterUpdate(relations);
|
|
28788
|
+
}
|
|
28789
|
+
})) !== null && _b !== void 0 ? _b : null;
|
|
27849
28790
|
}
|
|
27850
28791
|
/**
|
|
27851
28792
|
* Starts rendering the menu item.
|
|
@@ -27888,10 +28829,13 @@ var LegacyRelationsRenderManager;
|
|
|
27888
28829
|
this.drawnIds = [].concat(entityIds);
|
|
27889
28830
|
}
|
|
27890
28831
|
Dispose() {
|
|
28832
|
+
var _a;
|
|
27891
28833
|
if (this.disposed) {
|
|
27892
28834
|
return;
|
|
27893
28835
|
}
|
|
27894
28836
|
this.disposed = true;
|
|
28837
|
+
(_a = this.simulationRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
28838
|
+
this.simulationRemoval = null;
|
|
27895
28839
|
this.register.RemoveRegos({
|
|
27896
28840
|
menuItemId: this.item.id
|
|
27897
28841
|
});
|
|
@@ -28052,7 +28996,8 @@ var LegacyRelationsRenderManager;
|
|
|
28052
28996
|
menuItemId: this.item.id,
|
|
28053
28997
|
relations: relations,
|
|
28054
28998
|
viewer: this.viewer,
|
|
28055
|
-
visualRegister: this.register
|
|
28999
|
+
visualRegister: this.register,
|
|
29000
|
+
simulation: this.simulation
|
|
28056
29001
|
});
|
|
28057
29002
|
if (this.disposed) {
|
|
28058
29003
|
this.register.RemoveRegos({
|
|
@@ -29285,6 +30230,55 @@ var AssemblyRenderManager;
|
|
|
29285
30230
|
get ModelSpace() {
|
|
29286
30231
|
return this.modelSpace;
|
|
29287
30232
|
}
|
|
30233
|
+
/**
|
|
30234
|
+
* Every node of the Assembly read so far, so a caller can work out motion in the Assembly's own terms.
|
|
30235
|
+
* @param timeMs the scene time for each node's current pose. Default: the clock's.
|
|
30236
|
+
* @returns per node its pose within its parent from the API (local) and as drawn at the time (current).
|
|
30237
|
+
*/
|
|
30238
|
+
GetNodes(timeMs) {
|
|
30239
|
+
const at = timeMs !== null && timeMs !== void 0 ? timeMs : JulianDate.toDate(this.viewer.clock.currentTime).getTime();
|
|
30240
|
+
const rowsOf = (m) => m ? [0, 1, 2, 3].map(row => [0, 1, 2, 3].map(column => m[(column * 4) + row])) : null;
|
|
30241
|
+
return Object.values(this.hierarchyNodeByEntityId || {}).map(node => {
|
|
30242
|
+
var _a, _b, _c;
|
|
30243
|
+
const entity = (_a = this.apiEntities.get(node.entityId)) !== null && _a !== void 0 ? _a : null;
|
|
30244
|
+
const rows = (_b = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _b === void 0 ? void 0 : _b.AssemblyPosition;
|
|
30245
|
+
return {
|
|
30246
|
+
entityId: node.entityId,
|
|
30247
|
+
name: node.name,
|
|
30248
|
+
parentId: (_c = node.parentId) !== null && _c !== void 0 ? _c : null,
|
|
30249
|
+
local: Manager.MatrixFromRows(rows) ? rows : null,
|
|
30250
|
+
current: rowsOf(this.localAt(node.entityId, at)),
|
|
30251
|
+
entity
|
|
30252
|
+
};
|
|
30253
|
+
});
|
|
30254
|
+
}
|
|
30255
|
+
/**
|
|
30256
|
+
* The root's world frame at a time, history and simulation included, eg. to follow or frame the Assembly.
|
|
30257
|
+
* @param timeMs the scene time. Default: the clock's.
|
|
30258
|
+
* @returns null until the root has been read.
|
|
30259
|
+
*/
|
|
30260
|
+
GetRootFrame(timeMs) {
|
|
30261
|
+
const root = this.rootAt(timeMs !== null && timeMs !== void 0 ? timeMs : JulianDate.toDate(this.viewer.clock.currentTime).getTime());
|
|
30262
|
+
return root ? Manager.rootFrame(root.pos3d, root.heading, root.pitch, root.roll) : null;
|
|
30263
|
+
}
|
|
30264
|
+
/**
|
|
30265
|
+
* A part's world frame at a time as its records and its parents place it, size included.
|
|
30266
|
+
* @param entityId the part.
|
|
30267
|
+
* @param timeMs the scene time. Default: the clock's.
|
|
30268
|
+
* @returns null until the root and the part have been read.
|
|
30269
|
+
*/
|
|
30270
|
+
GetPartFrame(entityId, timeMs) {
|
|
30271
|
+
const at = timeMs !== null && timeMs !== void 0 ? timeMs : JulianDate.toDate(this.viewer.clock.currentTime).getTime();
|
|
30272
|
+
const rootFrame = this.GetRootFrame(at);
|
|
30273
|
+
const world = entityId === this.rootId ? Matrix4.IDENTITY : this.composeWorld(entityId, at);
|
|
30274
|
+
if (!rootFrame || !world) {
|
|
30275
|
+
return null;
|
|
30276
|
+
}
|
|
30277
|
+
// Where the part is drawn, so its own ground offset is part of its frame.
|
|
30278
|
+
const ground = this.groundOffsets.get(entityId);
|
|
30279
|
+
const placed = ground ? Matrix4.multiply(Matrix4.fromTranslation(ground), world, new Matrix4()) : world;
|
|
30280
|
+
return Matrix4.multiply(rootFrame, placed, new Matrix4());
|
|
30281
|
+
}
|
|
29288
30282
|
constructor(params) {
|
|
29289
30283
|
this.disposed = false;
|
|
29290
30284
|
// Cache of the hierarchy so that our scene-tree can reference it.
|
|
@@ -29294,19 +30288,41 @@ var AssemblyRenderManager;
|
|
|
29294
30288
|
this.hierarchyNodeByEntityId = null;
|
|
29295
30289
|
this.modelSpace = false;
|
|
29296
30290
|
this.rootId = null;
|
|
29297
|
-
// Where the root sits
|
|
29298
|
-
// Every child is placed through this, so a root move is one value changing rather than a refetch of the whole Assembly.
|
|
30291
|
+
// Where the root sits outside its history, and which way it faces in degrees. Children are placed through it.
|
|
29299
30292
|
this.rootPos3d = null;
|
|
29300
30293
|
this.rootHeading = 0;
|
|
29301
|
-
|
|
30294
|
+
this.rootPitch = 0;
|
|
30295
|
+
this.rootRoll = 0;
|
|
30296
|
+
// The root's recorded positions and attitudes, oldest first, kept apart since a record may name only one.
|
|
30297
|
+
this.rootSeries = [];
|
|
30298
|
+
this.rootAttitude = [];
|
|
30299
|
+
// Every placement worked out for the scene time last asked about, shared by all parts drawn at it.
|
|
30300
|
+
this.pose = null;
|
|
30301
|
+
// Entity ID -> what was drawn for it.
|
|
29302
30302
|
this.children = new Map();
|
|
30303
|
+
// Entity ID -> its live position within its parent, for every node fetched including undrawn groups.
|
|
30304
|
+
this.localPositions = new Map();
|
|
30305
|
+
// Entity ID -> how much higher the ground under it is than under the root, along the root's up.
|
|
30306
|
+
this.groundOffsets = new Map();
|
|
30307
|
+
// Entity ID -> its recorded poses within its parent, oldest first.
|
|
30308
|
+
this.jointSeries = new Map();
|
|
30309
|
+
// Drawn children that can move with the clock, so a tick places only these and not the whole Assembly.
|
|
30310
|
+
this.animatedIds = new Set();
|
|
29303
30311
|
// The trail through the root's own movement, which describes the whole Assembly.
|
|
29304
|
-
this.
|
|
30312
|
+
this.trail = null;
|
|
30313
|
+
this.simulationRemoval = null;
|
|
30314
|
+
this.FollowsSimulation = true;
|
|
30315
|
+
// Entity ID -> the record the API gave, so a cleared simulation falls back to it without a refetch.
|
|
30316
|
+
this.apiEntities = new Map();
|
|
30317
|
+
// Re-reads history and re-applies it, eg. after simulated records change. Set while the clock is followed.
|
|
30318
|
+
this.regather = null;
|
|
30319
|
+
this.followingClock = false;
|
|
29305
30320
|
// Callback to dispose the link between scene time and the root's historic position.
|
|
29306
30321
|
this.viewerDateTimeChangeRemoval = null;
|
|
29307
30322
|
this.historicGatherer = null;
|
|
29308
30323
|
this.historicAnimation = null;
|
|
29309
30324
|
const { viewer, register: visualsManager, getters, item } = params;
|
|
30325
|
+
this.simulation = params.simulation;
|
|
29310
30326
|
this.viewer = viewer;
|
|
29311
30327
|
this.getters = getters;
|
|
29312
30328
|
this.item = item;
|
|
@@ -29330,10 +30346,10 @@ var AssemblyRenderManager;
|
|
|
29330
30346
|
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"]);
|
|
29331
30347
|
}
|
|
29332
30348
|
/*
|
|
29333
|
-
* The root's frame: east-north-up at its position, turned by its heading.
|
|
30349
|
+
* The root's frame: east-north-up at its position, turned by its heading, pitch and roll.
|
|
29334
30350
|
*/
|
|
29335
|
-
static rootFrame(rootPos3d, headingDegrees) {
|
|
29336
|
-
const hpr = new HeadingPitchRoll(Math$1.toRadians(headingDegrees || 0), 0, 0);
|
|
30351
|
+
static rootFrame(rootPos3d, headingDegrees, pitchDegrees = 0, rollDegrees = 0) {
|
|
30352
|
+
const hpr = new HeadingPitchRoll(Math$1.toRadians(headingDegrees || 0), Math$1.toRadians(pitchDegrees || 0), Math$1.toRadians(rollDegrees || 0));
|
|
29337
30353
|
return Transforms.headingPitchRollToFixedFrame(rootPos3d, hpr);
|
|
29338
30354
|
}
|
|
29339
30355
|
/**
|
|
@@ -29356,28 +30372,553 @@ var AssemblyRenderManager;
|
|
|
29356
30372
|
return Matrix4.multiplyByPoint(Manager.rootFrame(rootPos3d, headingDegrees), offset, new Cartesian3());
|
|
29357
30373
|
}
|
|
29358
30374
|
/**
|
|
29359
|
-
* Moves the
|
|
30375
|
+
* Moves where the root sits outside its history, without refetching children; recorded poses still win.
|
|
29360
30376
|
* @param params
|
|
29361
30377
|
*/
|
|
29362
30378
|
ApplyRootPosition(params) {
|
|
29363
|
-
var _a, _b;
|
|
30379
|
+
var _a, _b, _c, _d, _e, _f;
|
|
29364
30380
|
if (this.disposed || !(params === null || params === void 0 ? void 0 : params.pos3d)) {
|
|
29365
30381
|
return;
|
|
29366
30382
|
}
|
|
29367
30383
|
this.rootPos3d = params.pos3d;
|
|
29368
30384
|
this.rootHeading = (_b = (_a = params.heading) !== null && _a !== void 0 ? _a : this.rootHeading) !== null && _b !== void 0 ? _b : 0;
|
|
30385
|
+
this.rootPitch = (_d = (_c = params.pitch) !== null && _c !== void 0 ? _c : this.rootPitch) !== null && _d !== void 0 ? _d : 0;
|
|
30386
|
+
this.rootRoll = (_f = (_e = params.roll) !== null && _e !== void 0 ? _e : this.rootRoll) !== null && _f !== void 0 ? _f : 0;
|
|
30387
|
+
this.repose(true);
|
|
30388
|
+
}
|
|
30389
|
+
/*
|
|
30390
|
+
* Drops every placement worked out so far, after the root or a joint's records change.
|
|
30391
|
+
* @param everyChild re-place the parts that cannot move as well, because where they rest has changed.
|
|
30392
|
+
*/
|
|
30393
|
+
repose(everyChild = false) {
|
|
30394
|
+
this.pose = null;
|
|
29369
30395
|
for (const child of this.children.values()) {
|
|
29370
|
-
|
|
29371
|
-
|
|
30396
|
+
if (everyChild || Boolean(child.moving) != this.canMove(child.entityId)) {
|
|
30397
|
+
this.bindPlacement(child);
|
|
30398
|
+
}
|
|
30399
|
+
}
|
|
30400
|
+
this.viewer.scene.requestRender();
|
|
30401
|
+
}
|
|
30402
|
+
/*
|
|
30403
|
+
* Takes a node's pose outside its history from its record, and for the root where it stands and faces.
|
|
30404
|
+
*/
|
|
30405
|
+
absorbNode(entity) {
|
|
30406
|
+
var _a, _b, _c, _d, _e;
|
|
30407
|
+
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
30408
|
+
const local = Manager.MatrixFromRows((_b = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _b === void 0 ? void 0 : _b.AssemblyPosition);
|
|
30409
|
+
if (local) {
|
|
30410
|
+
this.localPositions.set(id, local);
|
|
30411
|
+
}
|
|
30412
|
+
// Anchored on the root, which is usually never drawn; everything under it is placed from the hierarchy.
|
|
30413
|
+
if (id === this.rootId || (!this.rootId && !this.rootPos3d)) {
|
|
30414
|
+
const rootPos3d = EntityUtils.GetPos({
|
|
30415
|
+
viewer: this.viewer,
|
|
30416
|
+
entity,
|
|
30417
|
+
recordHeightRef: Manager.GetRecordHeightRef(this.item),
|
|
30418
|
+
returnHeightRef: HeightReference.NONE,
|
|
30419
|
+
allowRendered: false
|
|
30420
|
+
});
|
|
30421
|
+
if (rootPos3d) {
|
|
30422
|
+
this.rootPos3d = rootPos3d;
|
|
30423
|
+
this.rootHeading = EnsureNumber((_c = entity.Bruce.Transform) === null || _c === void 0 ? void 0 : _c.heading, 0);
|
|
30424
|
+
this.rootPitch = EnsureNumber((_d = entity.Bruce.Transform) === null || _d === void 0 ? void 0 : _d.pitch, 0);
|
|
30425
|
+
this.rootRoll = EnsureNumber((_e = entity.Bruce.Transform) === null || _e === void 0 ? void 0 : _e.roll, 0);
|
|
30426
|
+
}
|
|
30427
|
+
}
|
|
30428
|
+
}
|
|
30429
|
+
/*
|
|
30430
|
+
* A node's record with its simulation laid over it, keeping what a stand-in leaves out, eg. its model.
|
|
30431
|
+
*/
|
|
30432
|
+
withSimulation(entity) {
|
|
30433
|
+
var _a;
|
|
30434
|
+
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
30435
|
+
if (!this.simulation || !id) {
|
|
30436
|
+
return entity;
|
|
30437
|
+
}
|
|
30438
|
+
const standIn = this.simulation.GetEntity(id);
|
|
30439
|
+
if (!standIn) {
|
|
30440
|
+
return this.simulation.Overlay(entity);
|
|
30441
|
+
}
|
|
30442
|
+
return { ...entity, ...standIn, Bruce: { ...entity.Bruce, ...standIn.Bruce } };
|
|
30443
|
+
}
|
|
30444
|
+
/*
|
|
30445
|
+
* Brings the Assembly in line with a change to what is simulated.
|
|
30446
|
+
*/
|
|
30447
|
+
onSimulationChanged(change) {
|
|
30448
|
+
var _a;
|
|
30449
|
+
if (this.disposed || !this.hierarchyNodeByEntityId) {
|
|
30450
|
+
return;
|
|
30451
|
+
}
|
|
30452
|
+
const ids = change.entityIds.filter(id => this.hierarchyNodeByEntityId[id]);
|
|
30453
|
+
if (!ids.length) {
|
|
30454
|
+
return;
|
|
30455
|
+
}
|
|
30456
|
+
if (change.entities) {
|
|
30457
|
+
for (const id of ids) {
|
|
30458
|
+
const api = this.apiEntities.get(id);
|
|
30459
|
+
if (!api) {
|
|
30460
|
+
// Not loaded yet, and it will be drawn from its simulation when it is.
|
|
30461
|
+
continue;
|
|
30462
|
+
}
|
|
30463
|
+
const entity = this.withSimulation(api);
|
|
30464
|
+
// A cleared blob leaves the node's own matrix where the API has none, so it is reset.
|
|
30465
|
+
if (!((_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.AssemblyPosition)) {
|
|
30466
|
+
this.localPositions.delete(id);
|
|
30467
|
+
}
|
|
30468
|
+
this.absorbNode(entity);
|
|
30469
|
+
const child = this.children.get(id);
|
|
30470
|
+
if (child) {
|
|
30471
|
+
child.entity = entity;
|
|
30472
|
+
}
|
|
30473
|
+
}
|
|
30474
|
+
this.repose(true);
|
|
30475
|
+
}
|
|
30476
|
+
if (change.records) {
|
|
30477
|
+
if (this.regather) {
|
|
30478
|
+
this.regather(true);
|
|
30479
|
+
}
|
|
30480
|
+
else {
|
|
30481
|
+
this.viewerDateTimeSub();
|
|
30482
|
+
}
|
|
30483
|
+
}
|
|
30484
|
+
}
|
|
30485
|
+
/*
|
|
30486
|
+
* Nodes of this Assembly with simulated history.
|
|
30487
|
+
*/
|
|
30488
|
+
simulatedNodeIds() {
|
|
30489
|
+
if (!this.simulation || !this.hierarchyNodeByEntityId) {
|
|
30490
|
+
return [];
|
|
30491
|
+
}
|
|
30492
|
+
return this.simulation.GetRecordEntityIds().filter(id => this.hierarchyNodeByEntityId[id]);
|
|
30493
|
+
}
|
|
30494
|
+
/*
|
|
30495
|
+
* Whether a node can move with time: the root has history, or it or an ancestor does.
|
|
30496
|
+
*/
|
|
30497
|
+
canMove(entityId) {
|
|
30498
|
+
return this.rootSeries.length > 0 || this.rootAttitude.length > 0 || this.animatedIds.has(entityId);
|
|
30499
|
+
}
|
|
30500
|
+
/*
|
|
30501
|
+
* Gives a child its position and orientation, as functions of scene time only when it can move.
|
|
30502
|
+
*/
|
|
30503
|
+
bindPlacement(child) {
|
|
30504
|
+
const id = child.entityId;
|
|
30505
|
+
const moving = this.canMove(id);
|
|
30506
|
+
if (moving) {
|
|
30507
|
+
if (!child.moving) {
|
|
30508
|
+
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);
|
|
30509
|
+
child.cEntity.orientation = new CallbackProperty((time, result) => {
|
|
30510
|
+
var _a;
|
|
30511
|
+
const orient = (_a = this.placementAt(id, time)) === null || _a === void 0 ? void 0 : _a.orient;
|
|
30512
|
+
return orient ? Quaternion.clone(orient, result) : undefined;
|
|
30513
|
+
}, false);
|
|
30514
|
+
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);
|
|
30515
|
+
}
|
|
30516
|
+
}
|
|
30517
|
+
else {
|
|
30518
|
+
const placed = this.placementAt(id, this.viewer.clock.currentTime);
|
|
30519
|
+
if (placed) {
|
|
30520
|
+
child.cEntity.position = new ConstantPositionProperty(placed.pos3d);
|
|
30521
|
+
if (placed.orient) {
|
|
30522
|
+
child.cEntity.orientation = new ConstantProperty(placed.orient);
|
|
30523
|
+
}
|
|
30524
|
+
child.cEntity.model.scale = new ConstantProperty(placed.scale);
|
|
30525
|
+
}
|
|
30526
|
+
}
|
|
30527
|
+
if (Boolean(child.moving) != moving) {
|
|
30528
|
+
child.moving = moving;
|
|
30529
|
+
this.visualsManager.SetMoving({ moving, entityIds: [id], menuItemId: this.item.id });
|
|
30530
|
+
}
|
|
30531
|
+
}
|
|
30532
|
+
/*
|
|
30533
|
+
* The one scale a model takes from its part's composed matrix, the largest when they are uneven.
|
|
30534
|
+
*/
|
|
30535
|
+
static uniformScale(world) {
|
|
30536
|
+
return Cartesian3.maximumComponent(Matrix4.getScale(world, new Cartesian3()));
|
|
30537
|
+
}
|
|
30538
|
+
static cloneOrUndefined(pos3d, result) {
|
|
30539
|
+
return pos3d ? Cartesian3.clone(pos3d, result) : undefined;
|
|
30540
|
+
}
|
|
30541
|
+
/*
|
|
30542
|
+
* Where a node draws at a scene time, from one composition shared by every part asked about at that time.
|
|
30543
|
+
*/
|
|
30544
|
+
placementAt(entityId, time) {
|
|
30545
|
+
if (this.disposed || !time) {
|
|
30546
|
+
return null;
|
|
30547
|
+
}
|
|
30548
|
+
const timeMs = JulianDate.toDate(time).getTime();
|
|
30549
|
+
if (!this.pose || this.pose.timeMs !== timeMs) {
|
|
30550
|
+
const root = this.rootAt(timeMs);
|
|
30551
|
+
this.pose = {
|
|
30552
|
+
timeMs,
|
|
30553
|
+
rootFrame: root ? Manager.rootFrame(root.pos3d, root.heading, root.pitch, root.roll) : null,
|
|
30554
|
+
worlds: new Map(),
|
|
30555
|
+
placements: new Map()
|
|
30556
|
+
};
|
|
30557
|
+
}
|
|
30558
|
+
const pose = this.pose;
|
|
30559
|
+
if (!pose.rootFrame) {
|
|
30560
|
+
return null;
|
|
30561
|
+
}
|
|
30562
|
+
let placed = pose.placements.get(entityId);
|
|
30563
|
+
if (!placed) {
|
|
30564
|
+
const world = this.composeWorld(entityId, timeMs, pose.worlds);
|
|
30565
|
+
const offset = world
|
|
30566
|
+
? Matrix4.getTranslation(world, new Cartesian3())
|
|
30567
|
+
: new Cartesian3(0, 0, 0);
|
|
30568
|
+
const ground = this.groundOffsets.get(entityId);
|
|
30569
|
+
if (ground) {
|
|
30570
|
+
Cartesian3.add(offset, ground, offset);
|
|
30571
|
+
}
|
|
30572
|
+
placed = {
|
|
30573
|
+
pos3d: Matrix4.multiplyByPoint(pose.rootFrame, offset, new Cartesian3()),
|
|
30574
|
+
// Without a matrix, eg. the root itself, there is no orientation of its own to apply.
|
|
30575
|
+
orient: world ? EntityUtils.GetAssemblyOrientationInFrame(pose.rootFrame, world) : null,
|
|
30576
|
+
scale: world ? Manager.uniformScale(world) : 1
|
|
30577
|
+
};
|
|
30578
|
+
pose.placements.set(entityId, placed);
|
|
30579
|
+
}
|
|
30580
|
+
return placed;
|
|
30581
|
+
}
|
|
30582
|
+
/*
|
|
30583
|
+
* The root's pose at a time, position and attitude each following their own records as a joint's do.
|
|
30584
|
+
*/
|
|
30585
|
+
rootAt(timeMs) {
|
|
30586
|
+
const pos3d = this.rootPositionAt(timeMs);
|
|
30587
|
+
if (!pos3d) {
|
|
30588
|
+
return null;
|
|
30589
|
+
}
|
|
30590
|
+
const live = { heading: this.rootHeading, pitch: this.rootPitch, roll: this.rootRoll };
|
|
30591
|
+
const series = this.rootAttitude;
|
|
30592
|
+
if (!series.length || timeMs < series[0].timeMs) {
|
|
30593
|
+
return { pos3d, ...live };
|
|
30594
|
+
}
|
|
30595
|
+
let i = 0;
|
|
30596
|
+
while (i < series.length - 1 && series[i + 1].timeMs <= timeMs) {
|
|
30597
|
+
i++;
|
|
30598
|
+
}
|
|
30599
|
+
const a = series[i];
|
|
30600
|
+
const b = series[i + 1];
|
|
30601
|
+
const t = b ? (timeMs - a.timeMs) / (b.timeMs - a.timeMs) : 0;
|
|
30602
|
+
const turn = (from, to, fallback) => {
|
|
30603
|
+
var _a, _b, _c;
|
|
30604
|
+
const x = (_a = from !== null && from !== void 0 ? from : fallback) !== null && _a !== void 0 ? _a : 0;
|
|
30605
|
+
const y = (_c = (_b = (b ? to : from)) !== null && _b !== void 0 ? _b : fallback) !== null && _c !== void 0 ? _c : 0;
|
|
30606
|
+
// The short way round, so 350 to 10 degrees turns through north rather than all the way back.
|
|
30607
|
+
return x + (Math$1.negativePiToPi(Math$1.toRadians(y - x)) * 180 / Math.PI) * t;
|
|
30608
|
+
};
|
|
30609
|
+
return {
|
|
30610
|
+
pos3d,
|
|
30611
|
+
heading: turn(a.heading, b === null || b === void 0 ? void 0 : b.heading, live.heading),
|
|
30612
|
+
pitch: turn(a.pitch, b === null || b === void 0 ? void 0 : b.pitch, live.pitch),
|
|
30613
|
+
roll: turn(a.roll, b === null || b === void 0 ? void 0 : b.roll, live.roll)
|
|
30614
|
+
};
|
|
30615
|
+
}
|
|
30616
|
+
/*
|
|
30617
|
+
* Where the root is at a time, from its recorded positions.
|
|
30618
|
+
*/
|
|
30619
|
+
rootPositionAt(timeMs) {
|
|
30620
|
+
const series = this.rootSeries;
|
|
30621
|
+
if (!series.length || timeMs < series[0].timeMs) {
|
|
30622
|
+
return this.rootPos3d;
|
|
30623
|
+
}
|
|
30624
|
+
let i = 0;
|
|
30625
|
+
while (i < series.length - 1 && series[i + 1].timeMs <= timeMs) {
|
|
30626
|
+
i++;
|
|
30627
|
+
}
|
|
30628
|
+
const a = series[i];
|
|
30629
|
+
const b = series[i + 1];
|
|
30630
|
+
if (!b) {
|
|
30631
|
+
return a.pos3d;
|
|
30632
|
+
}
|
|
30633
|
+
const t = (timeMs - a.timeMs) / (b.timeMs - a.timeMs);
|
|
30634
|
+
// A straight line between orbit samples cuts up to a kilometre inside the path, so it is lifted back out.
|
|
30635
|
+
const chord = Cartesian3.lerp(a.pos3d, b.pos3d, t, new Cartesian3());
|
|
30636
|
+
const carto = Cartographic.fromCartesian(chord);
|
|
30637
|
+
return carto
|
|
30638
|
+
? Cartesian3.fromRadians(carto.longitude, carto.latitude, Math$1.lerp(a.height, b.height, t))
|
|
30639
|
+
: chord;
|
|
30640
|
+
}
|
|
30641
|
+
/*
|
|
30642
|
+
* Takes the root's records into its series.
|
|
30643
|
+
* @param replace the records are everything held for the root, so the series becomes exactly them.
|
|
30644
|
+
* @returns whether the series changed.
|
|
30645
|
+
*/
|
|
30646
|
+
absorbRootRecords(posses, replace) {
|
|
30647
|
+
if (!(posses === null || posses === void 0 ? void 0 : posses.length) && !(replace && this.rootSeries.length)) {
|
|
30648
|
+
return false;
|
|
30649
|
+
}
|
|
30650
|
+
const byTime = new Map(replace ? [] : this.rootSeries.map(k => [k.timeMs, k]));
|
|
30651
|
+
for (const pos of posses) {
|
|
30652
|
+
const carto = Cartographic.fromCartesian(pos.pos3d);
|
|
30653
|
+
if (!carto) {
|
|
29372
30654
|
continue;
|
|
29373
30655
|
}
|
|
29374
|
-
|
|
29375
|
-
|
|
29376
|
-
|
|
29377
|
-
|
|
30656
|
+
byTime.set(pos.dateTime.getTime(), {
|
|
30657
|
+
timeMs: pos.dateTime.getTime(),
|
|
30658
|
+
pos3d: pos.pos3d,
|
|
30659
|
+
height: carto.height
|
|
30660
|
+
});
|
|
30661
|
+
}
|
|
30662
|
+
const series = Array.from(byTime.values()).sort((x, y) => x.timeMs - y.timeMs);
|
|
30663
|
+
const changed = (series.length !== this.rootSeries.length ||
|
|
30664
|
+
series.some((k, i) => !Cartesian3.equals(k.pos3d, this.rootSeries[i].pos3d)));
|
|
30665
|
+
this.rootSeries = series;
|
|
30666
|
+
return changed;
|
|
30667
|
+
}
|
|
30668
|
+
/*
|
|
30669
|
+
* Takes the angles the root's records name into its attitude series, apart from where it is.
|
|
30670
|
+
* @param replace the records are everything held for the root, as for absorbRootRecords.
|
|
30671
|
+
* @returns whether the series changed.
|
|
30672
|
+
*/
|
|
30673
|
+
absorbRootAttitude(records, replace) {
|
|
30674
|
+
const angle = (transform, key) => {
|
|
30675
|
+
var _a;
|
|
30676
|
+
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)];
|
|
30677
|
+
return value == null || isNaN(+value) ? null : +value;
|
|
30678
|
+
};
|
|
30679
|
+
const byTime = new Map(replace ? [] : this.rootAttitude.map(k => [k.timeMs, k]));
|
|
30680
|
+
for (const record of records || []) {
|
|
30681
|
+
const timeMs = (record === null || record === void 0 ? void 0 : record.dateTime) ? new Date(record.dateTime).getTime() : NaN;
|
|
30682
|
+
const key = {
|
|
30683
|
+
timeMs,
|
|
30684
|
+
heading: angle(record === null || record === void 0 ? void 0 : record.transform, "heading"),
|
|
30685
|
+
pitch: angle(record === null || record === void 0 ? void 0 : record.transform, "pitch"),
|
|
30686
|
+
roll: angle(record === null || record === void 0 ? void 0 : record.transform, "roll")
|
|
30687
|
+
};
|
|
30688
|
+
if (isNaN(timeMs) || (key.heading == null && key.pitch == null && key.roll == null)) {
|
|
30689
|
+
continue;
|
|
29378
30690
|
}
|
|
30691
|
+
byTime.set(timeMs, key);
|
|
29379
30692
|
}
|
|
29380
|
-
|
|
30693
|
+
const series = Array.from(byTime.values()).sort((x, y) => x.timeMs - y.timeMs);
|
|
30694
|
+
const held = this.rootAttitude;
|
|
30695
|
+
const differs = (k, i) => (k.timeMs !== held[i].timeMs ||
|
|
30696
|
+
k.heading !== held[i].heading ||
|
|
30697
|
+
k.pitch !== held[i].pitch ||
|
|
30698
|
+
k.roll !== held[i].roll);
|
|
30699
|
+
const changed = series.length !== held.length || series.some(differs);
|
|
30700
|
+
this.rootAttitude = series;
|
|
30701
|
+
return changed;
|
|
30702
|
+
}
|
|
30703
|
+
/*
|
|
30704
|
+
* A node's matrix in the root's frame at a time, from each ancestor's pose within its parent.
|
|
30705
|
+
*/
|
|
30706
|
+
composeWorld(entityId, timeMs, memo, localOf = (id) => this.localAt(id, timeMs)) {
|
|
30707
|
+
var _a, _b, _c, _d;
|
|
30708
|
+
if (memo === null || memo === void 0 ? void 0 : memo.has(entityId)) {
|
|
30709
|
+
return memo.get(entityId);
|
|
30710
|
+
}
|
|
30711
|
+
let world = null;
|
|
30712
|
+
const local = localOf(entityId);
|
|
30713
|
+
if (local) {
|
|
30714
|
+
const parentId = (_b = (_a = this.hierarchyNodeByEntityId) === null || _a === void 0 ? void 0 : _a[entityId]) === null || _b === void 0 ? void 0 : _b.parentId;
|
|
30715
|
+
const parent = parentId ? this.composeWorld(parentId, timeMs, memo, localOf) : null;
|
|
30716
|
+
world = parent ? Matrix4.multiply(parent, local, new Matrix4()) : Matrix4.clone(local);
|
|
30717
|
+
}
|
|
30718
|
+
else if (entityId !== this.rootId) {
|
|
30719
|
+
// A node whose own position was not fetched falls back to the API's composed matrix.
|
|
30720
|
+
const child = this.children.get(entityId);
|
|
30721
|
+
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);
|
|
30722
|
+
}
|
|
30723
|
+
memo === null || memo === void 0 ? void 0 : memo.set(entityId, world);
|
|
30724
|
+
return world;
|
|
30725
|
+
}
|
|
30726
|
+
/*
|
|
30727
|
+
* Under a clamped or relative style, lifts a part by how much higher its ground is than the root's.
|
|
30728
|
+
*/
|
|
30729
|
+
measureGroundOffset(entity) {
|
|
30730
|
+
var _a;
|
|
30731
|
+
const entityId = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
30732
|
+
this.groundOffsets.delete(entityId);
|
|
30733
|
+
const root = this.apiEntities.get(this.rootId);
|
|
30734
|
+
if (!entityId ||
|
|
30735
|
+
entityId === this.rootId ||
|
|
30736
|
+
!root ||
|
|
30737
|
+
!this.rootPos3d ||
|
|
30738
|
+
Manager.GetRecordHeightRef(this.item) === HeightReference.NONE) {
|
|
30739
|
+
return;
|
|
30740
|
+
}
|
|
30741
|
+
const rootFrame = Manager.rootFrame(this.rootPos3d, this.rootHeading, this.rootPitch, this.rootRoll);
|
|
30742
|
+
const toRoot = Matrix4.inverse(rootFrame, new Matrix4());
|
|
30743
|
+
const groundUp = (record) => {
|
|
30744
|
+
const pos3d = EntityUtils.GetPos({
|
|
30745
|
+
viewer: this.viewer,
|
|
30746
|
+
entity: record,
|
|
30747
|
+
recordHeightRef: HeightReference.CLAMP_TO_GROUND,
|
|
30748
|
+
returnHeightRef: HeightReference.NONE,
|
|
30749
|
+
allowRendered: false
|
|
30750
|
+
});
|
|
30751
|
+
return pos3d ? Matrix4.multiplyByPoint(toRoot, pos3d, new Cartesian3()).z : null;
|
|
30752
|
+
};
|
|
30753
|
+
const part = groundUp(entity);
|
|
30754
|
+
const under = groundUp(root);
|
|
30755
|
+
if (part == null || under == null || Math.abs(part - under) < 1e-6) {
|
|
30756
|
+
return;
|
|
30757
|
+
}
|
|
30758
|
+
this.groundOffsets.set(entityId, new Cartesian3(0, 0, part - under));
|
|
30759
|
+
}
|
|
30760
|
+
/*
|
|
30761
|
+
* The rigid Earth-fixed motion from where a part's record places it to where it is drawn at a time.
|
|
30762
|
+
*/
|
|
30763
|
+
motionAt(entityId, time) {
|
|
30764
|
+
if (this.disposed || !time || !this.rootPos3d) {
|
|
30765
|
+
return null;
|
|
30766
|
+
}
|
|
30767
|
+
const timeMs = JulianDate.toDate(time).getTime();
|
|
30768
|
+
const root = this.rootAt(timeMs);
|
|
30769
|
+
const drawn = this.composeWorld(entityId, timeMs, new Map());
|
|
30770
|
+
const stored = this.composeWorld(entityId, timeMs, new Map(), (id) => {
|
|
30771
|
+
var _a, _b, _c, _d;
|
|
30772
|
+
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);
|
|
30773
|
+
});
|
|
30774
|
+
if (!root || !drawn || !stored) {
|
|
30775
|
+
return null;
|
|
30776
|
+
}
|
|
30777
|
+
const drawnFixed = Matrix4.multiply(Manager.rootFrame(root.pos3d, root.heading, root.pitch, root.roll), drawn, new Matrix4());
|
|
30778
|
+
const storedFixed = Matrix4.multiply(Manager.rootFrame(this.rootPos3d, this.rootHeading, this.rootPitch, this.rootRoll), stored, new Matrix4());
|
|
30779
|
+
return Matrix4.multiply(drawnFixed, Matrix4.inverse(storedFixed, new Matrix4()), new Matrix4());
|
|
30780
|
+
}
|
|
30781
|
+
/*
|
|
30782
|
+
* A node's pose within its parent at a time, interpolated between the records either side.
|
|
30783
|
+
*/
|
|
30784
|
+
localAt(entityId, timeMs) {
|
|
30785
|
+
var _a;
|
|
30786
|
+
// The live pose stands before the first record and the last record holds after it, as in an API read.
|
|
30787
|
+
const live = (_a = this.localPositions.get(entityId)) !== null && _a !== void 0 ? _a : null;
|
|
30788
|
+
const series = this.jointSeries.get(entityId);
|
|
30789
|
+
if (!(series === null || series === void 0 ? void 0 : series.length) || timeMs == null || timeMs < series[0].timeMs) {
|
|
30790
|
+
return live;
|
|
30791
|
+
}
|
|
30792
|
+
let i = 0;
|
|
30793
|
+
while (i < series.length - 1 && series[i + 1].timeMs <= timeMs) {
|
|
30794
|
+
i++;
|
|
30795
|
+
}
|
|
30796
|
+
const a = series[i];
|
|
30797
|
+
const b = series[i + 1];
|
|
30798
|
+
if (!b) {
|
|
30799
|
+
return Matrix4.fromTranslationQuaternionRotationScale(a.translation, a.rotation, a.scale);
|
|
30800
|
+
}
|
|
30801
|
+
const t = (timeMs - a.timeMs) / (b.timeMs - a.timeMs);
|
|
30802
|
+
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()));
|
|
30803
|
+
}
|
|
30804
|
+
/*
|
|
30805
|
+
* Rebuilds each node's keyframes from the historic records held so far.
|
|
30806
|
+
* @returns whether any node has keyframes.
|
|
30807
|
+
*/
|
|
30808
|
+
absorbJointRecords(recordsByIds) {
|
|
30809
|
+
var _a;
|
|
30810
|
+
// Everything held is given, so a node with nothing left, eg. its simulated records cleared, stops moving.
|
|
30811
|
+
for (const entityId of Array.from(this.jointSeries.keys())) {
|
|
30812
|
+
if (!((_a = recordsByIds === null || recordsByIds === void 0 ? void 0 : recordsByIds[entityId]) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
30813
|
+
this.jointSeries.delete(entityId);
|
|
30814
|
+
}
|
|
30815
|
+
}
|
|
30816
|
+
for (const entityId of Object.keys(recordsByIds || {})) {
|
|
30817
|
+
const keyframes = [];
|
|
30818
|
+
for (const record of recordsByIds[entityId] || []) {
|
|
30819
|
+
const matrix = Manager.MatrixFromRows(record.assemblyPosition);
|
|
30820
|
+
const timeMs = new Date(record.dateTime).getTime();
|
|
30821
|
+
if (!matrix || isNaN(timeMs)) {
|
|
30822
|
+
continue;
|
|
30823
|
+
}
|
|
30824
|
+
const scale = Matrix4.getScale(matrix, new Cartesian3());
|
|
30825
|
+
const rotation = Matrix4.getRotation(matrix, new Matrix3());
|
|
30826
|
+
keyframes.push({
|
|
30827
|
+
timeMs,
|
|
30828
|
+
translation: Matrix4.getTranslation(matrix, new Cartesian3()),
|
|
30829
|
+
rotation: Quaternion.fromRotationMatrix(rotation),
|
|
30830
|
+
scale
|
|
30831
|
+
});
|
|
30832
|
+
}
|
|
30833
|
+
if (keyframes.length) {
|
|
30834
|
+
keyframes.sort((x, y) => x.timeMs - y.timeMs);
|
|
30835
|
+
this.jointSeries.set(entityId, keyframes);
|
|
30836
|
+
}
|
|
30837
|
+
}
|
|
30838
|
+
this.refreshAnimated();
|
|
30839
|
+
return this.jointSeries.size > 0;
|
|
30840
|
+
}
|
|
30841
|
+
/*
|
|
30842
|
+
* Rebuilds which drawn children can move with the clock, by walking each one up to the root.
|
|
30843
|
+
*/
|
|
30844
|
+
refreshAnimated() {
|
|
30845
|
+
this.animatedIds.clear();
|
|
30846
|
+
if (!this.jointSeries.size) {
|
|
30847
|
+
return;
|
|
30848
|
+
}
|
|
30849
|
+
for (const entityId of this.children.keys()) {
|
|
30850
|
+
if (this.hasAnimatedAncestry(entityId)) {
|
|
30851
|
+
this.animatedIds.add(entityId);
|
|
30852
|
+
}
|
|
30853
|
+
}
|
|
30854
|
+
}
|
|
30855
|
+
/*
|
|
30856
|
+
* Whether a node or anything above it has keyframes, so the clock can move it.
|
|
30857
|
+
*/
|
|
30858
|
+
hasAnimatedAncestry(entityId) {
|
|
30859
|
+
var _a, _b;
|
|
30860
|
+
let at = entityId;
|
|
30861
|
+
while (at && this.jointSeries.size) {
|
|
30862
|
+
if (this.jointSeries.has(at)) {
|
|
30863
|
+
return true;
|
|
30864
|
+
}
|
|
30865
|
+
at = (_b = (_a = this.hierarchyNodeByEntityId) === null || _a === void 0 ? void 0 : _a[at]) === null || _b === void 0 ? void 0 : _b.parentId;
|
|
30866
|
+
}
|
|
30867
|
+
return false;
|
|
30868
|
+
}
|
|
30869
|
+
/*
|
|
30870
|
+
* Which nodes to ask history for.
|
|
30871
|
+
*/
|
|
30872
|
+
async historicEntityIds(api) {
|
|
30873
|
+
var _a, _b;
|
|
30874
|
+
// Through the Assembly when there is one, so the hierarchy follows the relation type on its record.
|
|
30875
|
+
const assemblyId = this.item["Assembly.ID"];
|
|
30876
|
+
const root = assemblyId ? { key: "root", AssemblyID: assemblyId } : { key: "root", RootID: this.rootId };
|
|
30877
|
+
const historic = {
|
|
30878
|
+
key: "historic",
|
|
30879
|
+
Historic: { HistoricKey: ((_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey) || undefined }
|
|
30880
|
+
};
|
|
30881
|
+
const query = {
|
|
30882
|
+
[DataLab.EReqKey.Primary]: { Items: [root, historic], Select: { Type: DataLab.ESelectType.Id } }
|
|
30883
|
+
};
|
|
30884
|
+
const load = 1000;
|
|
30885
|
+
try {
|
|
30886
|
+
const ids = [];
|
|
30887
|
+
for (let skip = 0;; skip += load) {
|
|
30888
|
+
const { items } = await DataLab.Run({ api, query, skip, load });
|
|
30889
|
+
ids.push(...(items !== null && items !== void 0 ? items : []));
|
|
30890
|
+
if (!items || items.length < load) {
|
|
30891
|
+
return ids;
|
|
30892
|
+
}
|
|
30893
|
+
}
|
|
30894
|
+
}
|
|
30895
|
+
catch (e) {
|
|
30896
|
+
// An API without the historic criterion gets asked about every node, as before it existed.
|
|
30897
|
+
console.warn("AssemblyRenderManager.historicEntityIds()", e);
|
|
30898
|
+
}
|
|
30899
|
+
return Object.keys((_b = this.hierarchyNodeByEntityId) !== null && _b !== void 0 ? _b : { [this.rootId]: null });
|
|
30900
|
+
}
|
|
30901
|
+
/**
|
|
30902
|
+
* Builds a matrix from the row-major rows that Bruce/AssemblyPosition and AssemblyWorldPosition use.
|
|
30903
|
+
* @param rows
|
|
30904
|
+
*/
|
|
30905
|
+
static MatrixFromRows(rows) {
|
|
30906
|
+
if (!Array.isArray(rows) || rows.length !== 4 || rows.some(r => !Array.isArray(r) || r.length !== 4)) {
|
|
30907
|
+
return null;
|
|
30908
|
+
}
|
|
30909
|
+
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]);
|
|
30910
|
+
}
|
|
30911
|
+
/**
|
|
30912
|
+
* The inverse of MatrixFromRows.
|
|
30913
|
+
* @param matrix
|
|
30914
|
+
*/
|
|
30915
|
+
static RowsFromMatrix(matrix) {
|
|
30916
|
+
const rows = [];
|
|
30917
|
+
for (let r = 0; r < 4; r++) {
|
|
30918
|
+
const row = Matrix4.getRow(matrix, r, new Cartesian4());
|
|
30919
|
+
rows.push([row.x, row.y, row.z, row.w]);
|
|
30920
|
+
}
|
|
30921
|
+
return rows;
|
|
29381
30922
|
}
|
|
29382
30923
|
Init() {
|
|
29383
30924
|
this.renderPriority = this.item.renderPriority;
|
|
@@ -29385,6 +30926,7 @@ var AssemblyRenderManager;
|
|
|
29385
30926
|
this.renderPriority = 1;
|
|
29386
30927
|
}
|
|
29387
30928
|
(async () => {
|
|
30929
|
+
var _a, _b;
|
|
29388
30930
|
if (this.disposed) {
|
|
29389
30931
|
return;
|
|
29390
30932
|
}
|
|
@@ -29400,6 +30942,8 @@ var AssemblyRenderManager;
|
|
|
29400
30942
|
this.hierarchyUpdate.Trigger(hierarchy);
|
|
29401
30943
|
// Build hierarchy node cache for quick lookups
|
|
29402
30944
|
this.buildHierarchyNodes(hierarchy);
|
|
30945
|
+
// A set for membership, since searching the list took minutes at 200k nodes.
|
|
30946
|
+
const seenIds = new Set();
|
|
29403
30947
|
const traverseHierarchy = (node, leavesOnly) => {
|
|
29404
30948
|
var _a;
|
|
29405
30949
|
if (node.Children) {
|
|
@@ -29408,7 +30952,8 @@ var AssemblyRenderManager;
|
|
|
29408
30952
|
}
|
|
29409
30953
|
}
|
|
29410
30954
|
const addNode = !leavesOnly || !((_a = node.Children) === null || _a === void 0 ? void 0 : _a.length);
|
|
29411
|
-
if (addNode && node.ID && !
|
|
30955
|
+
if (addNode && node.ID && !seenIds.has(node.ID)) {
|
|
30956
|
+
seenIds.add(node.ID);
|
|
29412
30957
|
flatEntityIds.push(node.ID);
|
|
29413
30958
|
}
|
|
29414
30959
|
};
|
|
@@ -29427,17 +30972,17 @@ var AssemblyRenderManager;
|
|
|
29427
30972
|
}
|
|
29428
30973
|
}
|
|
29429
30974
|
this.rootId = rootId;
|
|
30975
|
+
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;
|
|
29430
30976
|
if (this.disposed) {
|
|
29431
30977
|
return;
|
|
29432
30978
|
}
|
|
29433
30979
|
else if (flatEntityIds.length === 0) {
|
|
29434
30980
|
return;
|
|
29435
30981
|
}
|
|
30982
|
+
// Followed while the parts load: in a large Assembly loading takes far longer than anyone waits.
|
|
30983
|
+
const following = this.viewerDateTimeSub();
|
|
29436
30984
|
await this.processEntityIds(flatEntityIds);
|
|
29437
|
-
|
|
29438
|
-
return;
|
|
29439
|
-
}
|
|
29440
|
-
this.viewerDateTimeSub();
|
|
30985
|
+
await following;
|
|
29441
30986
|
}
|
|
29442
30987
|
catch (e) {
|
|
29443
30988
|
console.error("AssemblyRenderManager.Manager.Init()", e);
|
|
@@ -29464,7 +31009,7 @@ var AssemblyRenderManager;
|
|
|
29464
31009
|
if (!batch.length) {
|
|
29465
31010
|
continue;
|
|
29466
31011
|
}
|
|
29467
|
-
const { entities:
|
|
31012
|
+
const { entities: apiEntities } = await Entity$1.GetListByIds({
|
|
29468
31013
|
entityIds: batch,
|
|
29469
31014
|
api: this.getters.GetBruceApi(),
|
|
29470
31015
|
expandLODs: true,
|
|
@@ -29476,6 +31021,16 @@ var AssemblyRenderManager;
|
|
|
29476
31021
|
if (this.disposed) {
|
|
29477
31022
|
return;
|
|
29478
31023
|
}
|
|
31024
|
+
const fetched = apiEntities.map((entity) => {
|
|
31025
|
+
var _a;
|
|
31026
|
+
this.apiEntities.set((_a = entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID, entity);
|
|
31027
|
+
return this.withSimulation(entity);
|
|
31028
|
+
});
|
|
31029
|
+
for (const entity of fetched) {
|
|
31030
|
+
this.absorbNode(entity);
|
|
31031
|
+
}
|
|
31032
|
+
// Placements already worked out did not know about this batch's positions.
|
|
31033
|
+
this.pose = null;
|
|
29479
31034
|
for (const entity of fetched) {
|
|
29480
31035
|
// Filter for valid LODs then take the highest quality one (lowest level).
|
|
29481
31036
|
let lods = entity.Bruce.LOD || [];
|
|
@@ -29498,57 +31053,46 @@ var AssemblyRenderManager;
|
|
|
29498
31053
|
// Won't bother with vector data for this experiment.
|
|
29499
31054
|
continue;
|
|
29500
31055
|
}
|
|
29501
|
-
const
|
|
29502
|
-
|
|
29503
|
-
|
|
29504
|
-
|
|
29505
|
-
|
|
29506
|
-
returnHeightRef: HeightReference.NONE,
|
|
29507
|
-
allowRendered: false
|
|
29508
|
-
});
|
|
29509
|
-
if (!recordPos3d) {
|
|
31056
|
+
const entityId = entity.Bruce.ID;
|
|
31057
|
+
this.measureGroundOffset(entity);
|
|
31058
|
+
// A placement cached before the offset was known would leave the part off its ground.
|
|
31059
|
+
(_a = this.pose) === null || _a === void 0 ? void 0 : _a.placements.delete(entityId);
|
|
31060
|
+
if (!this.canMove(entityId) && !this.placementAt(entityId, this.viewer.clock.currentTime)) {
|
|
29510
31061
|
continue;
|
|
29511
31062
|
}
|
|
29512
|
-
const entityId = entity.Bruce.ID;
|
|
29513
|
-
if (entityId === this.rootId || !this.rootPos3d) {
|
|
29514
|
-
// Nothing has a frame to be relative to until the root has one.
|
|
29515
|
-
this.rootPos3d = recordPos3d;
|
|
29516
|
-
this.rootHeading = EnsureNumber((_a = entity.Bruce.Transform) === null || _a === void 0 ? void 0 : _a.heading, 0);
|
|
29517
|
-
}
|
|
29518
|
-
// Held as an offset in the root's frame, so a root move places it again without
|
|
29519
|
-
// anything being fetched. Where the root already moved, that is where it goes.
|
|
29520
|
-
const offset = Manager.ChildOffsetIn(this.rootPos3d, this.rootHeading, recordPos3d);
|
|
29521
|
-
const pos3d = Manager.ChildPositionFrom(this.rootPos3d, this.rootHeading, offset);
|
|
29522
|
-
// Optional: a child with no world matrix is still worth drawing, it just has no
|
|
29523
|
-
// orientation of its own to apply.
|
|
29524
|
-
const orient = EntityUtils.GetAssemblyOrientation(entity, pos3d);
|
|
29525
31063
|
const cEntity = this.viewer.entities.add({
|
|
29526
31064
|
model: {
|
|
29527
31065
|
uri: lod["ClientFile"].URL,
|
|
29528
31066
|
...ViewUtils.DefaultLightingProps(),
|
|
29529
31067
|
heightReference: HeightReference.NONE
|
|
29530
|
-
}
|
|
29531
|
-
position: pos3d,
|
|
29532
|
-
orientation: orient ? new ConstantProperty(orient) : undefined
|
|
31068
|
+
}
|
|
29533
31069
|
});
|
|
29534
31070
|
const prior = this.children.get(entityId);
|
|
29535
31071
|
if (prior && prior.cEntity !== cEntity) {
|
|
29536
31072
|
RemoveCEntityFromScene(this.viewer, prior.cEntity);
|
|
29537
31073
|
}
|
|
29538
|
-
|
|
31074
|
+
const child = {
|
|
29539
31075
|
entityId: entityId,
|
|
29540
31076
|
entity: entity,
|
|
29541
|
-
cEntity: cEntity
|
|
29542
|
-
|
|
29543
|
-
|
|
31077
|
+
cEntity: cEntity
|
|
31078
|
+
};
|
|
31079
|
+
this.children.set(entityId, child);
|
|
31080
|
+
// Joins the animated set by its own ancestry, so a late part never re-walks the rest.
|
|
31081
|
+
if (this.hasAnimatedAncestry(entityId)) {
|
|
31082
|
+
this.animatedIds.add(entityId);
|
|
31083
|
+
}
|
|
29544
31084
|
const geometryRadius = Entity$1.GetValue({
|
|
29545
31085
|
entity: entity,
|
|
29546
31086
|
path: ["Bruce", "GeometryRadius"]
|
|
29547
31087
|
});
|
|
29548
31088
|
cEntity.model["_radius"] = geometryRadius;
|
|
29549
31089
|
cEntity.model["_radiusLoaded"] = true;
|
|
31090
|
+
// Placed before it is registered, so the register never measures a visual with no position.
|
|
31091
|
+
this.bindPlacement(child);
|
|
29550
31092
|
this.visualsManager.AddRego({
|
|
29551
31093
|
rego: {
|
|
31094
|
+
moving: child.moving ? true : null,
|
|
31095
|
+
motion: (time) => this.motionAt(entity.Bruce.ID, time),
|
|
29552
31096
|
canEdit: true,
|
|
29553
31097
|
entityId: entity.Bruce.ID,
|
|
29554
31098
|
menuItemId: this.item.id,
|
|
@@ -29568,47 +31112,89 @@ var AssemblyRenderManager;
|
|
|
29568
31112
|
}
|
|
29569
31113
|
}
|
|
29570
31114
|
/*
|
|
29571
|
-
* Follows the scene clock
|
|
29572
|
-
* Only the root is fetched: everything under it is placed through ApplyRootPosition.
|
|
31115
|
+
* Follows the scene clock, moving the Assembly along the root's history and each joint along its own.
|
|
29573
31116
|
*/
|
|
29574
|
-
viewerDateTimeSub() {
|
|
29575
|
-
|
|
31117
|
+
async viewerDateTimeSub() {
|
|
31118
|
+
var _a;
|
|
31119
|
+
const historic = Manager.IsHistoric(this.item);
|
|
31120
|
+
if (this.followingClock || !this.rootId || (!historic && !this.simulatedNodeIds().length)) {
|
|
29576
31121
|
return;
|
|
29577
31122
|
}
|
|
31123
|
+
this.followingClock = true;
|
|
29578
31124
|
const api = this.getters.GetBruceApi();
|
|
29579
|
-
const
|
|
31125
|
+
const historicIds = historic ? await this.historicEntityIds(api) : [];
|
|
31126
|
+
if (this.disposed) {
|
|
31127
|
+
return;
|
|
31128
|
+
}
|
|
31129
|
+
const attrKey = (_a = this.item.BruceEntity) === null || _a === void 0 ? void 0 : _a.historicAttrKey;
|
|
29580
31130
|
const recordHeightRef = Manager.GetRecordHeightRef(this.item);
|
|
29581
31131
|
const toPosses = (records) => {
|
|
29582
31132
|
return CesiumAnimatedProperty.GetSeriesPossesForHistoricEntity(this.viewer, recordHeightRef, HeightReference.NONE, records);
|
|
29583
31133
|
};
|
|
29584
|
-
|
|
29585
|
-
|
|
29586
|
-
|
|
29587
|
-
|
|
29588
|
-
|
|
29589
|
-
|
|
29590
|
-
|
|
29591
|
-
|
|
29592
|
-
|
|
29593
|
-
|
|
31134
|
+
if (historicIds.length) {
|
|
31135
|
+
this.historicGatherer = new HistoricGatherer({
|
|
31136
|
+
viewer: this.viewer,
|
|
31137
|
+
getApi: () => api,
|
|
31138
|
+
getAttrKey: () => attrKey,
|
|
31139
|
+
// For clock desync between whatever wrote the record and this client.
|
|
31140
|
+
paddingMs: 15000,
|
|
31141
|
+
simulation: this.simulation,
|
|
31142
|
+
onRecords: (recordsByIds) => {
|
|
31143
|
+
var _a;
|
|
31144
|
+
const records = recordsByIds[this.rootId];
|
|
31145
|
+
if (records === null || records === void 0 ? void 0 : records.length) {
|
|
31146
|
+
const posses = toPosses(records);
|
|
31147
|
+
(_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.SupplementSeries(posses);
|
|
31148
|
+
const moved = this.absorbRootRecords(posses, false);
|
|
31149
|
+
if (this.absorbRootAttitude(records, false) || moved) {
|
|
31150
|
+
this.repose();
|
|
31151
|
+
}
|
|
31152
|
+
}
|
|
31153
|
+
// Joint records go in together once the gather lands, so parents never draw apart from children.
|
|
29594
31154
|
}
|
|
29595
|
-
}
|
|
29596
|
-
}
|
|
31155
|
+
});
|
|
31156
|
+
}
|
|
31157
|
+
// The nodes with history: what the API has records for, and whatever has been simulated since.
|
|
31158
|
+
const nodes = () => Array.from(new Set([...historicIds, ...this.simulatedNodeIds()]));
|
|
29597
31159
|
let gathering = false;
|
|
29598
|
-
|
|
31160
|
+
// Set when what is held changed without a fetch, eg. a simulated record arriving.
|
|
31161
|
+
let stale = true;
|
|
31162
|
+
const gather = async (force) => {
|
|
31163
|
+
var _a, _b;
|
|
31164
|
+
stale = stale || Boolean(force);
|
|
29599
31165
|
if (this.disposed || gathering) {
|
|
29600
31166
|
return;
|
|
29601
31167
|
}
|
|
29602
31168
|
gathering = true;
|
|
29603
31169
|
try {
|
|
29604
|
-
const
|
|
31170
|
+
const ids = nodes();
|
|
31171
|
+
let fetched = false;
|
|
31172
|
+
let recordsByIds;
|
|
31173
|
+
if (this.historicGatherer) {
|
|
31174
|
+
({ fetched, recordsByIds } = await this.historicGatherer.Gather(ids.map(id => ({ Bruce: { ID: id } }))));
|
|
31175
|
+
}
|
|
31176
|
+
else {
|
|
31177
|
+
recordsByIds = (_b = (_a = this.simulation) === null || _a === void 0 ? void 0 : _a.MergeRecords({}, attrKey, ids)) !== null && _b !== void 0 ? _b : {};
|
|
31178
|
+
}
|
|
29605
31179
|
if (this.disposed) {
|
|
29606
31180
|
return;
|
|
29607
31181
|
}
|
|
31182
|
+
// A gather served from what is held changes nothing and runs every tick, so it stops here.
|
|
31183
|
+
if (!fetched && !stale && this.jointSeries.size) {
|
|
31184
|
+
return;
|
|
31185
|
+
}
|
|
31186
|
+
stale = false;
|
|
31187
|
+
let changed = this.absorbJointRecords(recordsByIds);
|
|
29608
31188
|
const posses = toPosses(recordsByIds[this.rootId] || []);
|
|
31189
|
+
changed = this.absorbRootRecords(posses, true) || changed;
|
|
31190
|
+
changed = this.absorbRootAttitude(recordsByIds[this.rootId] || [], true) || changed;
|
|
31191
|
+
if (changed) {
|
|
31192
|
+
this.repose();
|
|
31193
|
+
}
|
|
29609
31194
|
if (!posses.length) {
|
|
29610
31195
|
return;
|
|
29611
31196
|
}
|
|
31197
|
+
// Held for the trail alone; where the root is drawn comes from rootAt(), never from its smoothing.
|
|
29612
31198
|
if (!this.historicAnimation) {
|
|
29613
31199
|
this.historicAnimation = new CesiumAnimatedProperty.AnimatePositionSeries({
|
|
29614
31200
|
posses: posses,
|
|
@@ -29622,15 +31208,21 @@ var AssemblyRenderManager;
|
|
|
29622
31208
|
}
|
|
29623
31209
|
catch (e) {
|
|
29624
31210
|
console.error("AssemblyRenderManager.viewerDateTimeSub()", e);
|
|
31211
|
+
// A gather that throws would throw again straight away, so the retry waits for the next tick.
|
|
31212
|
+
stale = false;
|
|
29625
31213
|
}
|
|
29626
31214
|
finally {
|
|
29627
31215
|
gathering = false;
|
|
31216
|
+
// A change that landed mid-gather is not left for a tick that may never come on a paused clock.
|
|
31217
|
+
if (stale && !this.disposed) {
|
|
31218
|
+
gather();
|
|
31219
|
+
}
|
|
29628
31220
|
}
|
|
29629
31221
|
};
|
|
31222
|
+
this.regather = gather;
|
|
29630
31223
|
gather();
|
|
29631
31224
|
let lastTime = null;
|
|
29632
31225
|
const tickRemoval = this.viewer.clock.onTick.addEventListener(() => {
|
|
29633
|
-
var _a;
|
|
29634
31226
|
if (this.disposed) {
|
|
29635
31227
|
return;
|
|
29636
31228
|
}
|
|
@@ -29640,15 +31232,9 @@ var AssemblyRenderManager;
|
|
|
29640
31232
|
}
|
|
29641
31233
|
lastTime = now;
|
|
29642
31234
|
gather();
|
|
29643
|
-
|
|
29644
|
-
|
|
29645
|
-
|
|
29646
|
-
const pos3d = this.historicAnimation.GetValue();
|
|
29647
|
-
if (pos3d) {
|
|
29648
|
-
this.ApplyRootPosition({
|
|
29649
|
-
pos3d: pos3d,
|
|
29650
|
-
heading: (_a = this.historicAnimation.GetHeadingDegrees()) !== null && _a !== void 0 ? _a : this.rootHeading
|
|
29651
|
-
});
|
|
31235
|
+
// Moving parts read the clock themselves when drawn, so the scene only needs a new frame.
|
|
31236
|
+
if (this.rootSeries.length || this.rootAttitude.length || this.animatedIds.size) {
|
|
31237
|
+
this.viewer.scene.requestRender();
|
|
29652
31238
|
}
|
|
29653
31239
|
});
|
|
29654
31240
|
this.viewerDateTimeChangeRemoval = () => {
|
|
@@ -29657,6 +31243,10 @@ var AssemblyRenderManager;
|
|
|
29657
31243
|
(_a = this.historicGatherer) === null || _a === void 0 ? void 0 : _a.Dispose();
|
|
29658
31244
|
this.historicGatherer = null;
|
|
29659
31245
|
this.historicAnimation = null;
|
|
31246
|
+
this.regather = null;
|
|
31247
|
+
this.rootSeries = [];
|
|
31248
|
+
this.rootAttitude = [];
|
|
31249
|
+
this.pose = null;
|
|
29660
31250
|
};
|
|
29661
31251
|
}
|
|
29662
31252
|
/*
|
|
@@ -29664,7 +31254,7 @@ var AssemblyRenderManager;
|
|
|
29664
31254
|
*/
|
|
29665
31255
|
applyRootTrack() {
|
|
29666
31256
|
var _a;
|
|
29667
|
-
if (!this.item.historicDrawTrack || !this.historicAnimation || this.
|
|
31257
|
+
if (!this.item.historicDrawTrack || !this.historicAnimation || this.trail) {
|
|
29668
31258
|
return;
|
|
29669
31259
|
}
|
|
29670
31260
|
const trackStyle = EntityRenderEngine.GetTrackStyle({
|
|
@@ -29674,41 +31264,35 @@ var AssemblyRenderManager;
|
|
|
29674
31264
|
if (!trackStyle) {
|
|
29675
31265
|
return;
|
|
29676
31266
|
}
|
|
29677
|
-
this.
|
|
29678
|
-
id: ObjectUtils.UId(15),
|
|
29679
|
-
polyline: {
|
|
29680
|
-
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),
|
|
29681
|
-
width: trackStyle.width,
|
|
29682
|
-
material: trackStyle.color,
|
|
29683
|
-
clampToGround: EntityRenderEngine.GetHeightRefPolyline(Manager.GetRecordHeightRef(this.item))
|
|
29684
|
-
== HeightReference.CLAMP_TO_GROUND,
|
|
29685
|
-
zIndex: 0,
|
|
29686
|
-
classificationType: ClassificationType.BOTH
|
|
29687
|
-
}
|
|
29688
|
-
});
|
|
29689
|
-
this.trackEntity._noEdit = true;
|
|
29690
|
-
this.trackEntity._noSelect = true;
|
|
29691
|
-
CesiumEntityStyler.SetDefaultColor({
|
|
29692
|
-
color: trackStyle.color,
|
|
29693
|
-
entity: this.trackEntity,
|
|
31267
|
+
this.trail = new HistoricTrail.Trail({
|
|
29694
31268
|
viewer: this.viewer,
|
|
29695
|
-
|
|
29696
|
-
|
|
31269
|
+
color: trackStyle.color,
|
|
31270
|
+
width: trackStyle.width,
|
|
31271
|
+
clampToGround: EntityRenderEngine.GetHeightRefPolyline(Manager.GetRecordHeightRef(this.item))
|
|
31272
|
+
== HeightReference.CLAMP_TO_GROUND,
|
|
31273
|
+
getSeries: () => { var _a, _b; return (_b = (_a = this.historicAnimation) === null || _a === void 0 ? void 0 : _a.GetSeries()) !== null && _b !== void 0 ? _b : []; },
|
|
31274
|
+
trailSeconds: HistoricTrail.GetTrailSeconds(this.item),
|
|
31275
|
+
// Where the root is drawn, so the trail ends on the model; nothing before the first record held.
|
|
31276
|
+
positionAt: (timeMs) => (this.rootSeries.length && timeMs >= this.rootSeries[0].timeMs ? this.rootPositionAt(timeMs) : null)
|
|
29697
31277
|
});
|
|
29698
31278
|
}
|
|
29699
31279
|
Dispose() {
|
|
29700
|
-
var _a;
|
|
31280
|
+
var _a, _b, _c;
|
|
29701
31281
|
if (this.disposed) {
|
|
29702
31282
|
return;
|
|
29703
31283
|
}
|
|
29704
31284
|
this.disposed = true;
|
|
29705
31285
|
(_a = this.viewerDateTimeChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
29706
31286
|
this.viewerDateTimeChangeRemoval = null;
|
|
29707
|
-
|
|
29708
|
-
|
|
29709
|
-
|
|
29710
|
-
|
|
31287
|
+
(_b = this.simulationRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
31288
|
+
this.simulationRemoval = null;
|
|
31289
|
+
this.apiEntities.clear();
|
|
31290
|
+
(_c = this.trail) === null || _c === void 0 ? void 0 : _c.Dispose();
|
|
31291
|
+
this.trail = null;
|
|
29711
31292
|
this.children.clear();
|
|
31293
|
+
this.localPositions.clear();
|
|
31294
|
+
this.jointSeries.clear();
|
|
31295
|
+
this.animatedIds.clear();
|
|
29712
31296
|
this.visualsManager.RemoveRegos({
|
|
29713
31297
|
menuItemId: this.item.id
|
|
29714
31298
|
});
|
|
@@ -30166,6 +31750,9 @@ var MenuItemManager;
|
|
|
30166
31750
|
this.OnSeriesUpdated.Trigger({ itemId, segments: [] });
|
|
30167
31751
|
}
|
|
30168
31752
|
}
|
|
31753
|
+
get Simulation() {
|
|
31754
|
+
return this.simulation;
|
|
31755
|
+
}
|
|
30169
31756
|
get Monitor() {
|
|
30170
31757
|
return this.sharedMonitor;
|
|
30171
31758
|
}
|
|
@@ -30191,6 +31778,7 @@ var MenuItemManager;
|
|
|
30191
31778
|
this.visualsRegister = visualsRegister;
|
|
30192
31779
|
this.sharedGetters = new SharedGetters.Cache();
|
|
30193
31780
|
this.sharedHistoric = new SharedHistoricGetters.Cache();
|
|
31781
|
+
this.simulation = EntitySimulation.Get(this.viewer);
|
|
30194
31782
|
this.sharedMonitor = new CesiumViewMonitor.Monitor(this.viewer);
|
|
30195
31783
|
this.tilesetInitQueue = new InitQueueTileset(this.getters);
|
|
30196
31784
|
}
|
|
@@ -30404,7 +31992,8 @@ var MenuItemManager;
|
|
|
30404
31992
|
monitor: this.sharedMonitor,
|
|
30405
31993
|
item: params.item,
|
|
30406
31994
|
sharedGetters: this.sharedGetters,
|
|
30407
|
-
onSeriesDiscovered: (segment) => this.RecordSeriesSegment(rItem.id, segment)
|
|
31995
|
+
onSeriesDiscovered: (segment) => this.RecordSeriesSegment(rItem.id, segment),
|
|
31996
|
+
simulation: this.simulation
|
|
30408
31997
|
});
|
|
30409
31998
|
break;
|
|
30410
31999
|
case MenuItem.EType.EntitiesLoaded:
|
|
@@ -30413,7 +32002,8 @@ var MenuItemManager;
|
|
|
30413
32002
|
register: this.visualsRegister,
|
|
30414
32003
|
apiGetter: params.apiGetter,
|
|
30415
32004
|
monitor: this.sharedMonitor,
|
|
30416
|
-
item: params.item
|
|
32005
|
+
item: params.item,
|
|
32006
|
+
simulation: this.simulation
|
|
30417
32007
|
});
|
|
30418
32008
|
break;
|
|
30419
32009
|
case MenuItem.EType.EntitiesIds:
|
|
@@ -30423,7 +32013,8 @@ var MenuItemManager;
|
|
|
30423
32013
|
apiGetter: params.apiGetter,
|
|
30424
32014
|
monitor: this.sharedMonitor,
|
|
30425
32015
|
item: params.item,
|
|
30426
|
-
sharedHistoric: this.sharedHistoric
|
|
32016
|
+
sharedHistoric: this.sharedHistoric,
|
|
32017
|
+
simulation: this.simulation
|
|
30427
32018
|
});
|
|
30428
32019
|
break;
|
|
30429
32020
|
case MenuItem.EType.Entity:
|
|
@@ -30432,7 +32023,8 @@ var MenuItemManager;
|
|
|
30432
32023
|
register: this.visualsRegister,
|
|
30433
32024
|
apiGetter: params.apiGetter,
|
|
30434
32025
|
monitor: this.sharedMonitor,
|
|
30435
|
-
item: params.item
|
|
32026
|
+
item: params.item,
|
|
32027
|
+
simulation: this.simulation
|
|
30436
32028
|
});
|
|
30437
32029
|
break;
|
|
30438
32030
|
case MenuItem.EType.CadTileset:
|
|
@@ -30442,7 +32034,8 @@ var MenuItemManager;
|
|
|
30442
32034
|
getters: this.getters,
|
|
30443
32035
|
item: params.item,
|
|
30444
32036
|
modelSpace: params.modelSpace,
|
|
30445
|
-
initQueue: this.tilesetInitQueue
|
|
32037
|
+
initQueue: this.tilesetInitQueue,
|
|
32038
|
+
simulation: this.simulation
|
|
30446
32039
|
});
|
|
30447
32040
|
break;
|
|
30448
32041
|
case MenuItem.EType.Assembly:
|
|
@@ -30452,6 +32045,7 @@ var MenuItemManager;
|
|
|
30452
32045
|
getters: params.getters,
|
|
30453
32046
|
item: params.item,
|
|
30454
32047
|
modelSpace: params.modelSpace,
|
|
32048
|
+
simulation: this.simulation
|
|
30455
32049
|
});
|
|
30456
32050
|
break;
|
|
30457
32051
|
case MenuItem.EType.Osm:
|
|
@@ -30479,7 +32073,8 @@ var MenuItemManager;
|
|
|
30479
32073
|
getters: this.getters,
|
|
30480
32074
|
monitor: this.sharedMonitor,
|
|
30481
32075
|
item: params.item,
|
|
30482
|
-
initQueue: this.tilesetInitQueue
|
|
32076
|
+
initQueue: this.tilesetInitQueue,
|
|
32077
|
+
simulation: this.simulation
|
|
30483
32078
|
});
|
|
30484
32079
|
break;
|
|
30485
32080
|
case MenuItem.EType.Kml:
|
|
@@ -30503,7 +32098,8 @@ var MenuItemManager;
|
|
|
30503
32098
|
getters: params.getters,
|
|
30504
32099
|
item: params.item,
|
|
30505
32100
|
viewer: this.viewer,
|
|
30506
|
-
register: this.visualsRegister
|
|
32101
|
+
register: this.visualsRegister,
|
|
32102
|
+
simulation: this.simulation
|
|
30507
32103
|
});
|
|
30508
32104
|
break;
|
|
30509
32105
|
// Deprecated to support a few demos until new one is phased in.
|
|
@@ -30513,7 +32109,8 @@ var MenuItemManager;
|
|
|
30513
32109
|
apiGetter: params.apiGetter,
|
|
30514
32110
|
item: params.item,
|
|
30515
32111
|
register: this.visualsRegister,
|
|
30516
|
-
viewer: this.viewer
|
|
32112
|
+
viewer: this.viewer,
|
|
32113
|
+
simulation: this.simulation
|
|
30517
32114
|
});
|
|
30518
32115
|
break;
|
|
30519
32116
|
case MenuItem.EType.Relationships:
|
|
@@ -30521,7 +32118,8 @@ var MenuItemManager;
|
|
|
30521
32118
|
apiGetter: params.apiGetter,
|
|
30522
32119
|
item: params.item,
|
|
30523
32120
|
register: this.visualsRegister,
|
|
30524
|
-
viewer: this.viewer
|
|
32121
|
+
viewer: this.viewer,
|
|
32122
|
+
simulation: this.simulation
|
|
30525
32123
|
});
|
|
30526
32124
|
break;
|
|
30527
32125
|
case MenuItem.EType.GooglePhotoTileset:
|
|
@@ -30553,7 +32151,8 @@ var MenuItemManager;
|
|
|
30553
32151
|
item: params.item,
|
|
30554
32152
|
apiGetter: params.apiGetter,
|
|
30555
32153
|
monitor: this.sharedMonitor,
|
|
30556
|
-
visualsRegister: this.visualsRegister
|
|
32154
|
+
visualsRegister: this.visualsRegister,
|
|
32155
|
+
simulation: this.simulation
|
|
30557
32156
|
});
|
|
30558
32157
|
break;
|
|
30559
32158
|
// Any "none" type can be ignored. These are just containers for other items.
|
|
@@ -30766,6 +32365,63 @@ var MenuItemManager;
|
|
|
30766
32365
|
}
|
|
30767
32366
|
}
|
|
30768
32367
|
}
|
|
32368
|
+
/**
|
|
32369
|
+
* Draws Entities from data given here as well as, or instead of, the API's, until ClearSimulation is called.
|
|
32370
|
+
* @param params.set the simulation this belongs to, so it can be cleared apart from others. Default "default".
|
|
32371
|
+
* @param params.entities stand-ins that replace each Entity's record; API data for them is ignored.
|
|
32372
|
+
* @param params.patches partial Entities laid over each Entity; live API data shows where a patch is silent.
|
|
32373
|
+
* @param params.records historic records naming entityId, dateTime and only the data they change.
|
|
32374
|
+
* @param params.menuItemIds the items to redraw. By default every item already drawing one of the Entities.
|
|
32375
|
+
*/
|
|
32376
|
+
async Simulate(params) {
|
|
32377
|
+
const { set, entities, patches, records, menuItemIds } = params;
|
|
32378
|
+
this.simulation.SetEntities(entities, set);
|
|
32379
|
+
this.simulation.SetPatches(patches, set);
|
|
32380
|
+
this.simulation.SetRecords(records, set);
|
|
32381
|
+
const entityIds = [
|
|
32382
|
+
...(entities || []).map(x => { var _a; return (_a = x === null || x === void 0 ? void 0 : x.Bruce) === null || _a === void 0 ? void 0 : _a.ID; }),
|
|
32383
|
+
...(patches || []).map(x => { var _a; return (_a = x === null || x === void 0 ? void 0 : x.Bruce) === null || _a === void 0 ? void 0 : _a.ID; }),
|
|
32384
|
+
...(records || []).map(x => x === null || x === void 0 ? void 0 : x.entityId)
|
|
32385
|
+
];
|
|
32386
|
+
await this.reRenderSimulated(entityIds, menuItemIds);
|
|
32387
|
+
}
|
|
32388
|
+
/**
|
|
32389
|
+
* Stops simulating these Entities, or every Entity when none are named, and redraws them.
|
|
32390
|
+
* @param params.set the simulation to clear. By default every one.
|
|
32391
|
+
* @param params.entities clear the stand-ins and patches. Default true.
|
|
32392
|
+
* @param params.records clear the historic records. Default true.
|
|
32393
|
+
*/
|
|
32394
|
+
async ClearSimulation(params) {
|
|
32395
|
+
var _a;
|
|
32396
|
+
const entityIds = (_a = params === null || params === void 0 ? void 0 : params.entityIds) !== null && _a !== void 0 ? _a : [
|
|
32397
|
+
...this.simulation.GetEntityIds(),
|
|
32398
|
+
...this.simulation.GetRecordEntityIds()
|
|
32399
|
+
];
|
|
32400
|
+
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 });
|
|
32401
|
+
await this.reRenderSimulated(entityIds, params === null || params === void 0 ? void 0 : params.menuItemIds);
|
|
32402
|
+
}
|
|
32403
|
+
/*
|
|
32404
|
+
* Redraws simulated Entities only in the items holding a visual for them, unless the caller names the items.
|
|
32405
|
+
*/
|
|
32406
|
+
async reRenderSimulated(entityIds, menuItemIds) {
|
|
32407
|
+
const ids = Array.from(new Set(entityIds.filter(x => !!x)));
|
|
32408
|
+
if (!ids.length) {
|
|
32409
|
+
return;
|
|
32410
|
+
}
|
|
32411
|
+
const items = (menuItemIds === null || menuItemIds === void 0 ? void 0 : menuItemIds.length) ? this.items.filter(x => menuItemIds.includes(x.id)) : this.items;
|
|
32412
|
+
for (const item of items) {
|
|
32413
|
+
// Some managers follow the store themselves, and redrawing them here would only repeat that.
|
|
32414
|
+
if (!item.renderManager || item.renderManager.FollowsSimulation) {
|
|
32415
|
+
continue;
|
|
32416
|
+
}
|
|
32417
|
+
const drawn = (menuItemIds === null || menuItemIds === void 0 ? void 0 : menuItemIds.length)
|
|
32418
|
+
? ids
|
|
32419
|
+
: ids.filter(id => this.visualsRegister.GetRego({ entityId: id, menuItemId: item.id }));
|
|
32420
|
+
if (drawn.length) {
|
|
32421
|
+
await item.renderManager.ReRender({ entityIds: drawn, force: true });
|
|
32422
|
+
}
|
|
32423
|
+
}
|
|
32424
|
+
}
|
|
30769
32425
|
}
|
|
30770
32426
|
MenuItemManager.Manager = Manager;
|
|
30771
32427
|
})(MenuItemManager || (MenuItemManager = {}));
|
|
@@ -39325,6 +40981,7 @@ function groupAttributes(paths, attributes) {
|
|
|
39325
40981
|
}
|
|
39326
40982
|
class WidgetInfoView extends Widget.AWidget {
|
|
39327
40983
|
constructor(params) {
|
|
40984
|
+
var _a;
|
|
39328
40985
|
super(params);
|
|
39329
40986
|
this.STYLESHEET_ID = "nextspace-info-view-stylesheet";
|
|
39330
40987
|
this._generateStyles();
|
|
@@ -39334,10 +40991,19 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39334
40991
|
this._updateInfoView();
|
|
39335
40992
|
}
|
|
39336
40993
|
});
|
|
40994
|
+
// The selected Entity is read once per selection, so a change to its simulation reads it again.
|
|
40995
|
+
this._simulationRemoval = (_a = this._manager.Simulation) === null || _a === void 0 ? void 0 : _a.OnChanged.Subscribe((change) => {
|
|
40996
|
+
if (this._lastSelectedId && change.entityIds.includes(this._lastSelectedId)) {
|
|
40997
|
+
this._lastSelectedId = null;
|
|
40998
|
+
this._updateInfoView();
|
|
40999
|
+
}
|
|
41000
|
+
});
|
|
39337
41001
|
}
|
|
39338
41002
|
Dispose() {
|
|
41003
|
+
var _a;
|
|
39339
41004
|
super.Dispose();
|
|
39340
41005
|
this._updateRemoval();
|
|
41006
|
+
(_a = this._simulationRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
39341
41007
|
}
|
|
39342
41008
|
_generateStyles() {
|
|
39343
41009
|
if (document.getElementById(this.STYLESHEET_ID)) {
|
|
@@ -39799,7 +41465,7 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39799
41465
|
}
|
|
39800
41466
|
}
|
|
39801
41467
|
async _updateInfoView() {
|
|
39802
|
-
var
|
|
41468
|
+
var _a, _c, _d, _e, _f;
|
|
39803
41469
|
const selectedIds = this._manager.VisualsRegister.GetSelected();
|
|
39804
41470
|
if (selectedIds.length <= 0) {
|
|
39805
41471
|
this._element.style.display = "none";
|
|
@@ -39821,17 +41487,20 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39821
41487
|
this._summary.innerHTML = "";
|
|
39822
41488
|
this._imageContainer.style.display = "none";
|
|
39823
41489
|
const api = this._apiGetters.GetBruceApi();
|
|
39824
|
-
|
|
41490
|
+
// A simulated Entity is shown as simulated: a stand-in as is, a patch over what the API has.
|
|
41491
|
+
const simulation = this._manager.Simulation;
|
|
41492
|
+
let entity = (_a = simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(firstId)) !== null && _a !== void 0 ? _a : (await Entity$1.Get({
|
|
39825
41493
|
entityId: firstId,
|
|
39826
41494
|
api: api,
|
|
39827
41495
|
migrated: true,
|
|
39828
41496
|
expandLocation: DISPLAY_ASSEMBLY_INFO
|
|
39829
|
-
});
|
|
41497
|
+
})).entity;
|
|
41498
|
+
entity = entity && simulation ? simulation.Resolve(firstId, entity) : entity;
|
|
39830
41499
|
if (!entity) {
|
|
39831
41500
|
throw (new Error("Could not get entity."));
|
|
39832
41501
|
}
|
|
39833
41502
|
const { entityType } = await EntityType.Get({
|
|
39834
|
-
entityTypeId: (
|
|
41503
|
+
entityTypeId: (_c = entity.Bruce) === null || _c === void 0 ? void 0 : _c["EntityType.ID"],
|
|
39835
41504
|
api: api
|
|
39836
41505
|
});
|
|
39837
41506
|
let name = Entity$1.CalculateName({
|
|
@@ -39854,7 +41523,7 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39854
41523
|
const defaultImage = images.length ? images[0] : null;
|
|
39855
41524
|
if (defaultImage) {
|
|
39856
41525
|
this._imageContainer.style.display = "flex";
|
|
39857
|
-
const url = (
|
|
41526
|
+
const url = (_d = defaultImage.URL) !== null && _d !== void 0 ? _d : ClientFile.GetUrl({
|
|
39858
41527
|
fileId: defaultImage["ClientFile.ID"],
|
|
39859
41528
|
api: api,
|
|
39860
41529
|
viaCdn: true
|
|
@@ -39867,7 +41536,7 @@ class WidgetInfoView extends Widget.AWidget {
|
|
|
39867
41536
|
this._summary.appendChild(detailsTitle);
|
|
39868
41537
|
// TODO: Selection for what mode instead of always doing "all".
|
|
39869
41538
|
const attributes = gatherAttributes(EMode.ShowAll, entity, entityType);
|
|
39870
|
-
const groups = groupAttributes(attributes, (
|
|
41539
|
+
const groups = groupAttributes(attributes, (_f = (_e = entityType.DataSchema) === null || _e === void 0 ? void 0 : _e.Structure) !== null && _f !== void 0 ? _f : []);
|
|
39871
41540
|
for (const group of groups) {
|
|
39872
41541
|
this._generateAttrGroup(entityType, entity, group);
|
|
39873
41542
|
}
|
|
@@ -42464,7 +44133,7 @@ var EntityUtils;
|
|
|
42464
44133
|
* @param params
|
|
42465
44134
|
*/
|
|
42466
44135
|
async function GetLocation(params) {
|
|
42467
|
-
var _a, _b, _c, _d;
|
|
44136
|
+
var _a, _b, _c, _d, _e;
|
|
42468
44137
|
let { api, viewer, samples, visualRegister, minimumAlt, paddingAlt } = params;
|
|
42469
44138
|
if (!paddingAlt) {
|
|
42470
44139
|
paddingAlt = 0;
|
|
@@ -43012,6 +44681,13 @@ var EntityUtils;
|
|
|
43012
44681
|
recordSamples.push(sample);
|
|
43013
44682
|
}
|
|
43014
44683
|
}
|
|
44684
|
+
// A simulated Entity is where its blob says, never where the API has it.
|
|
44685
|
+
const simulation = EntitySimulation.Get(viewer);
|
|
44686
|
+
for (const sample of recordSamples) {
|
|
44687
|
+
if (!sample.entity && sample.entityId) {
|
|
44688
|
+
sample.entity = (_e = simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(sample.entityId)) !== null && _e !== void 0 ? _e : sample.entity;
|
|
44689
|
+
}
|
|
44690
|
+
}
|
|
43015
44691
|
// Bulk requesting Entity records.
|
|
43016
44692
|
try {
|
|
43017
44693
|
const toSearchIds = recordSamples.filter(x => !x.entity && x.entityId).map(x => x.entityId);
|
|
@@ -43032,7 +44708,8 @@ var EntityUtils;
|
|
|
43032
44708
|
for (let i = 0; i < recordSamples.length; i++) {
|
|
43033
44709
|
const sample = recordSamples[i];
|
|
43034
44710
|
if (!sample.entity && sample.entityId) {
|
|
43035
|
-
|
|
44711
|
+
const read = entitiesMap.get(sample.entityId);
|
|
44712
|
+
sample.entity = read && simulation ? simulation.Overlay(read) : read;
|
|
43036
44713
|
}
|
|
43037
44714
|
}
|
|
43038
44715
|
}
|
|
@@ -43046,6 +44723,11 @@ var EntityUtils;
|
|
|
43046
44723
|
// We have to detect whatever is an Assembly Entity and expand it.
|
|
43047
44724
|
try {
|
|
43048
44725
|
const needsExpansion = recordSamples.filter(x => {
|
|
44726
|
+
var _a;
|
|
44727
|
+
// Expanding reads the API's record, which would replace the stand-in or undo the patch.
|
|
44728
|
+
if (simulation === null || simulation === void 0 ? void 0 : simulation.HasBlob((_a = x.entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID)) {
|
|
44729
|
+
return false;
|
|
44730
|
+
}
|
|
43049
44731
|
const assemblyPos = Entity$1.GetValue({
|
|
43050
44732
|
entity: x.entity,
|
|
43051
44733
|
path: ["Bruce", "AssemblyPosition"]
|
|
@@ -43404,6 +45086,21 @@ var EntityUtils;
|
|
|
43404
45086
|
return Quaternion.multiply(combined, _assemblyAxisShift, new Quaternion());
|
|
43405
45087
|
}
|
|
43406
45088
|
EntityUtils.GetAssemblyOrientation = GetAssemblyOrientation;
|
|
45089
|
+
/**
|
|
45090
|
+
* Returns the orientation a part's model is drawn with, for its world matrix within the root's frame.
|
|
45091
|
+
* @param rootFrame the root's frame in the world, eg. from Transforms.headingPitchRollToFixedFrame.
|
|
45092
|
+
* @param world the part's matrix within the root's frame.
|
|
45093
|
+
*/
|
|
45094
|
+
function GetAssemblyOrientationInFrame(rootFrame, world) {
|
|
45095
|
+
if (!rootFrame || !world) {
|
|
45096
|
+
return null;
|
|
45097
|
+
}
|
|
45098
|
+
const combined = Matrix4.multiply(rootFrame, world, new Matrix4());
|
|
45099
|
+
const rotation = Matrix4.getRotation(combined, new Matrix3());
|
|
45100
|
+
const q = Quaternion.fromRotationMatrix(rotation);
|
|
45101
|
+
return Quaternion.multiply(q, _assemblyAxisShift, new Quaternion());
|
|
45102
|
+
}
|
|
45103
|
+
EntityUtils.GetAssemblyOrientationInFrame = GetAssemblyOrientationInFrame;
|
|
43407
45104
|
/**
|
|
43408
45105
|
* Returns the position of the entity.
|
|
43409
45106
|
* This is an async variant that checks for related assemblies.
|
|
@@ -43413,6 +45110,18 @@ var EntityUtils;
|
|
|
43413
45110
|
*/
|
|
43414
45111
|
async function GetPosAsync(params) {
|
|
43415
45112
|
let { viewer, entityId, entity, visualRegister, returnHeightRef, recordHeightRef, api } = params;
|
|
45113
|
+
// A simulated Entity is where its stand-in says, or where its patch puts the API's record.
|
|
45114
|
+
const simulation = EntitySimulation.Get(viewer);
|
|
45115
|
+
entity = entity !== null && entity !== void 0 ? entity : simulation === null || simulation === void 0 ? void 0 : simulation.GetEntity(entityId);
|
|
45116
|
+
if (!entity && entityId && (simulation === null || simulation === void 0 ? void 0 : simulation.HasBlob(entityId))) {
|
|
45117
|
+
try {
|
|
45118
|
+
const read = (await Entity$1.Get({ api, entityId, expandLocation: false, migrated: true })).entity;
|
|
45119
|
+
entity = read ? simulation.Overlay(read) : null;
|
|
45120
|
+
}
|
|
45121
|
+
catch (e) {
|
|
45122
|
+
console.error(e);
|
|
45123
|
+
}
|
|
45124
|
+
}
|
|
43416
45125
|
// We have issues where imported BRZ files have improper expandLocation=true info.
|
|
43417
45126
|
// As a result we'll double-request the data.
|
|
43418
45127
|
// If there is a location then we won't bother using expanded information.
|
|
@@ -53413,7 +55122,7 @@ var StyleUtils;
|
|
|
53413
55122
|
StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
|
|
53414
55123
|
})(StyleUtils || (StyleUtils = {}));
|
|
53415
55124
|
|
|
53416
|
-
const VERSION = "7.6.
|
|
55125
|
+
const VERSION = "7.6.2";
|
|
53417
55126
|
/**
|
|
53418
55127
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
53419
55128
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|
|
@@ -53430,5 +55139,5 @@ const getENVIRONMENT = () => {
|
|
|
53430
55139
|
return ENVIRONMENT;
|
|
53431
55140
|
};
|
|
53432
55141
|
|
|
53433
|
-
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 };
|
|
55142
|
+
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, 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 };
|
|
53434
55143
|
//# sourceMappingURL=bruce-cesium.es5.js.map
|