From 4e3b1f75905d21dd96270723514c6fe54c43de32 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Fri, 7 Feb 2025 11:32:57 +0100 Subject: [PATCH 1/6] fix: fixes #12465 --- .../engine/Source/DataSources/EntityView.js | 13 +------ packages/engine/Source/Widget/CesiumWidget.js | 8 ++-- .../Specs/DataSources/EntityViewSpec.js | 39 +++++++------------ 3 files changed, 19 insertions(+), 41 deletions(-) diff --git a/packages/engine/Source/DataSources/EntityView.js b/packages/engine/Source/DataSources/EntityView.js index 9e7ae33234b..904134b5bbf 100644 --- a/packages/engine/Source/DataSources/EntityView.js +++ b/packages/engine/Source/DataSources/EntityView.js @@ -43,7 +43,7 @@ function updateTransform( ellipsoid, ) { const mode = that.scene.mode; - let cartesian = positionProperty.getValue(time, that._lastCartesian); + const cartesian = positionProperty.getValue(time, that._lastCartesian); if (defined(cartesian)) { let hasBasis = false; let invertVelocity = false; @@ -216,10 +216,6 @@ function updateTransform( } } - if (defined(that.boundingSphere)) { - cartesian = that.boundingSphere.center; - } - let position; let direction; let up; @@ -346,12 +342,6 @@ function EntityView(entity, scene, ellipsoid) { */ this.ellipsoid = defaultValue(ellipsoid, Ellipsoid.default); - /** - * The bounding sphere of the object. - * @type {BoundingSphere} - */ - this.boundingSphere = undefined; - // Shadow copies of the objects so we can detect changes. this._lastEntity = undefined; this._mode = undefined; @@ -445,7 +435,6 @@ EntityView.prototype.update = function (time, boundingSphere) { } camera.viewBoundingSphere(boundingSphere, scratchHeadingPitchRange); - this.boundingSphere = boundingSphere; updateLookAt = false; saveCamera = false; } else if ( diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index b4c34adffd7..29f8d960810 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -1134,6 +1134,8 @@ CesiumWidget.prototype._updateCanAnimate = function (isUpdated) { this._clock.canAnimate = isUpdated; }; +const boundingSphereScratch = new BoundingSphere(); + /** * @private */ @@ -1146,15 +1148,15 @@ CesiumWidget.prototype._onTick = function (clock) { } const entityView = this._entityView; - if (defined(entityView) && defined(entityView.boundingSphere)) { + if (defined(entityView)) { const trackedEntity = this._trackedEntity; const trackedState = this._dataSourceDisplay.getBoundingSphere( trackedEntity, false, - entityView.boundingSphere, + boundingSphereScratch, ); if (trackedState === BoundingSphereState.DONE) { - entityView.update(time, entityView.boundingSphere); + entityView.update(time, boundingSphereScratch); } } }; diff --git a/packages/engine/Specs/DataSources/EntityViewSpec.js b/packages/engine/Specs/DataSources/EntityViewSpec.js index 61223cc1dd0..7b83c3017e4 100644 --- a/packages/engine/Specs/DataSources/EntityViewSpec.js +++ b/packages/engine/Specs/DataSources/EntityViewSpec.js @@ -89,43 +89,30 @@ describe( expect(view.scene.camera.position).toEqualEpsilon(sampleOffset, 1e-10); }); - it("uses entity bounding sphere", function () { - const sampleOffset = new Cartesian3( - -1.3322676295501878e-15, - -7.348469228349534, - 7.3484692283495345, - ); + it("uses provided bounding sphere", function () { + const bs = new BoundingSphere(new Cartesian3(3, 4, 5), 6); + scene.camera.viewBoundingSphere(bs); + const positionWC = scene.camera.positionWC.clone(); + const entity = new Entity(); entity.position = new ConstantPositionProperty( Cartesian3.fromDegrees(0.0, 0.0), ); const view = new EntityView(entity, scene, undefined); - view.update( - JulianDate.now(), - new BoundingSphere(new Cartesian3(3, 4, 5), 6), - ); - expect(view.scene.camera.position).toEqualEpsilon(sampleOffset, 1e-10); + view.update(JulianDate.now(), bs); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC, 1e-10); entity.trackingReferenceFrame = TrackingReferenceFrame.INERTIAL; - view.update( - JulianDate.now(), - new BoundingSphere(new Cartesian3(3, 4, 5), 6), - ); - expect(view.scene.camera.position).toEqualEpsilon(sampleOffset, 1e-10); + view.update(JulianDate.now(), bs); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC, 1e-10); entity.trackingReferenceFrame = TrackingReferenceFrame.VELOCITY; - view.update( - JulianDate.now(), - new BoundingSphere(new Cartesian3(3, 4, 5), 6), - ); - expect(view.scene.camera.position).toEqualEpsilon(sampleOffset, 1e-10); + view.update(JulianDate.now(), bs); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC, 1e-10); entity.trackingReferenceFrame = TrackingReferenceFrame.ENU; - view.update( - JulianDate.now(), - new BoundingSphere(new Cartesian3(3, 4, 5), 6), - ); - expect(view.scene.camera.position).toEqualEpsilon(sampleOffset, 1e-10); + view.update(JulianDate.now(), bs); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC, 1e-10); }); it("uses entity viewFrom if available and boundingsphere is supplied", function () { From d8e6868e966f19b636cb089f08bcdb6c8eca7ef0 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Fri, 28 Feb 2025 18:13:46 +0100 Subject: [PATCH 2/6] fix: added deprecation warning on EntityView.boundingSphere --- .../Source/DataSources/DataSourceDisplay.js | 8 +++-- .../engine/Source/DataSources/EntityView.js | 30 +++++++++++++++++++ packages/engine/Source/Widget/CesiumWidget.js | 5 +--- .../DataSources/DataSourceDisplaySpec.js | 7 ++--- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/packages/engine/Source/DataSources/DataSourceDisplay.js b/packages/engine/Source/DataSources/DataSourceDisplay.js index ce405cf9b84..1d98541720c 100644 --- a/packages/engine/Source/DataSources/DataSourceDisplay.js +++ b/packages/engine/Source/DataSources/DataSourceDisplay.js @@ -372,7 +372,8 @@ const getBoundingSphereBoundingSphereScratch = new BoundingSphere(); * @param {Entity} entity The entity whose bounding sphere to compute. * @param {boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data. * If false, the the function will halt and return pending if any of the bounding spheres are pending. - * @param {BoundingSphere} result The bounding sphere onto which to store the result. + * @param {BoundingSphere} [result] The bounding sphere onto which to store the result. + * Result parameter may not be provided if one is only interested into the bounding sphere state. * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, * BoundingSphereState.PENDING if the result is still being computed, or * BoundingSphereState.FAILED if the entity has no visualization in the current scene. @@ -386,7 +387,6 @@ DataSourceDisplay.prototype.getBoundingSphere = function ( //>>includeStart('debug', pragmas.debug); Check.defined("entity", entity); Check.typeOf.bool("allowPartial", allowPartial); - Check.defined("result", result); //>>includeEnd('debug'); if (!this._ready) { @@ -443,7 +443,9 @@ DataSourceDisplay.prototype.getBoundingSphere = function ( } boundingSpheres.length = count; - BoundingSphere.fromBoundingSpheres(boundingSpheres, result); + if (defined(result)) { + BoundingSphere.fromBoundingSpheres(boundingSpheres, result); + } return BoundingSphereState.DONE; }; diff --git a/packages/engine/Source/DataSources/EntityView.js b/packages/engine/Source/DataSources/EntityView.js index 904134b5bbf..56abb923a11 100644 --- a/packages/engine/Source/DataSources/EntityView.js +++ b/packages/engine/Source/DataSources/EntityView.js @@ -2,6 +2,7 @@ import Cartesian3 from "../Core/Cartesian3.js"; import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import HeadingPitchRange from "../Core/HeadingPitchRange.js"; import JulianDate from "../Core/JulianDate.js"; @@ -348,12 +349,40 @@ function EntityView(entity, scene, ellipsoid) { this._lastCartesian = new Cartesian3(); this._defaultOffset3D = undefined; + this._boundingSphere = undefined; this._velocityProperty = new VelocityVectorProperty(entity.position, true); this._offset3D = new Cartesian3(); } +// Per instance properties +Object.defineProperties(EntityView.prototype, { + /** + * The bounding sphere of the object. + * @memberof EntityView.prototype + * + * @type {BoundingSphere} + * @deprecated This property has been deprecated and will be removed in Cesium 1.130 + */ + boundingSphere: { + get: function () { + deprecationWarning( + "EntityView.boundingSphere", + "EntityView.boundingSphere has been deprecated and will be removed in Cesium 1.130", + ); + return this._boundingSphere; + }, + set: function (boundingSphere) { + deprecationWarning( + "EntityView.boundingSphere", + "EntityView.boundingSphere has been deprecated and will be removed in Cesium 1.130", + ); + this._boundingSphere = boundingSphere; + }, + }, +}); + // STATIC properties defined here, not per-instance. Object.defineProperties(EntityView, { /** @@ -435,6 +464,7 @@ EntityView.prototype.update = function (time, boundingSphere) { } camera.viewBoundingSphere(boundingSphere, scratchHeadingPitchRange); + this._boundingSphere = boundingSphere; updateLookAt = false; saveCamera = false; } else if ( diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index 29f8d960810..41d4b549cbf 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -1134,8 +1134,6 @@ CesiumWidget.prototype._updateCanAnimate = function (isUpdated) { this._clock.canAnimate = isUpdated; }; -const boundingSphereScratch = new BoundingSphere(); - /** * @private */ @@ -1153,10 +1151,9 @@ CesiumWidget.prototype._onTick = function (clock) { const trackedState = this._dataSourceDisplay.getBoundingSphere( trackedEntity, false, - boundingSphereScratch, ); if (trackedState === BoundingSphereState.DONE) { - entityView.update(time, boundingSphereScratch); + entityView.update(time); } } }; diff --git a/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js b/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js index 045cf0a57f9..78568aba2f5 100644 --- a/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js +++ b/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js @@ -291,15 +291,14 @@ describe( }).toThrowDeveloperError(); }); - it("Compute bounding sphere throws without result.", function () { + it("Compute bounding sphere doesn't throw without result.", function () { display = new DataSourceDisplay({ dataSourceCollection: dataSourceCollection, scene: scene, }); const entity = new Entity(); - expect(function () { - display.getBoundingSphere(entity, false, undefined); - }).toThrowDeveloperError(); + const state = display.getBoundingSphere(entity, false); + expect(state).toBe(BoundingSphereState.PENDING); }); it("Compute bounding sphere throws without allowPartial.", function () { From 610a5ae1fa5221b9ea7445a94e45e2d658763036 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Sat, 1 Mar 2025 04:18:09 +0100 Subject: [PATCH 3/6] fix: created DataSourceDisplay.getBoundingSphereState to match convention that when a result is undefined, a new object is created --- .../Source/DataSources/DataSourceDisplay.js | 82 +++++++++++++++++-- packages/engine/Source/Widget/CesiumWidget.js | 2 +- .../DataSources/DataSourceDisplaySpec.js | 25 +++++- 3 files changed, 99 insertions(+), 10 deletions(-) diff --git a/packages/engine/Source/DataSources/DataSourceDisplay.js b/packages/engine/Source/DataSources/DataSourceDisplay.js index 1d98541720c..067d7e0b1c2 100644 --- a/packages/engine/Source/DataSources/DataSourceDisplay.js +++ b/packages/engine/Source/DataSources/DataSourceDisplay.js @@ -362,9 +362,81 @@ DataSourceDisplay.prototype._postRender = function () { } }; -const getBoundingSphereArrayScratch = []; const getBoundingSphereBoundingSphereScratch = new BoundingSphere(); +/** + * Computes a bounding sphere state. + * + * @param {Entity} entity The entity whose bounding sphere to compute. + * @param {boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data. + * If false, the the function will halt and return pending if any of the bounding spheres are pending. + * @returns {BoundingSphereState} BoundingSphereState.DONE if the bounding sphere could be returned, + * BoundingSphereState.PENDING if the bounding sphere is still being computed, or + * BoundingSphereState.FAILED if the entity has no visualization in the current scene. + * @private + */ +DataSourceDisplay.prototype.getBoundingSphereState = function ( + entity, + allowPartial, +) { + //>>includeStart('debug', pragmas.debug); + Check.defined("entity", entity); + Check.typeOf.bool("allowPartial", allowPartial); + //>>includeEnd('debug'); + + if (!this._ready) { + return BoundingSphereState.PENDING; + } + + let i; + let length; + let dataSource = this._defaultDataSource; + if (!dataSource.entities.contains(entity)) { + dataSource = undefined; + + const dataSources = this._dataSourceCollection; + length = dataSources.length; + for (i = 0; i < length; i++) { + const d = dataSources.get(i); + if (d.entities.contains(entity)) { + dataSource = d; + break; + } + } + } + + if (!defined(dataSource)) { + return BoundingSphereState.FAILED; + } + + const tmp = getBoundingSphereBoundingSphereScratch; + + let count = 0; + let state = BoundingSphereState.DONE; + const visualizers = dataSource._visualizers; + const visualizersLength = visualizers.length; + + for (i = 0; i < visualizersLength; i++) { + const visualizer = visualizers[i]; + if (defined(visualizer.getBoundingSphere)) { + state = visualizers[i].getBoundingSphere(entity, tmp); + if (!allowPartial && state === BoundingSphereState.PENDING) { + return BoundingSphereState.PENDING; + } else if (state === BoundingSphereState.DONE) { + count++; + } + } + } + + if (count === 0) { + return BoundingSphereState.FAILED; + } + + return BoundingSphereState.DONE; +}; + +const getBoundingSphereArrayScratch = []; + /** * Computes a bounding sphere which encloses the visualization produced for the specified entity. * The bounding sphere is in the fixed frame of the scene's globe. @@ -372,8 +444,7 @@ const getBoundingSphereBoundingSphereScratch = new BoundingSphere(); * @param {Entity} entity The entity whose bounding sphere to compute. * @param {boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data. * If false, the the function will halt and return pending if any of the bounding spheres are pending. - * @param {BoundingSphere} [result] The bounding sphere onto which to store the result. - * Result parameter may not be provided if one is only interested into the bounding sphere state. + * @param {BoundingSphere} result The bounding sphere onto which to store the result. * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, * BoundingSphereState.PENDING if the result is still being computed, or * BoundingSphereState.FAILED if the entity has no visualization in the current scene. @@ -387,6 +458,7 @@ DataSourceDisplay.prototype.getBoundingSphere = function ( //>>includeStart('debug', pragmas.debug); Check.defined("entity", entity); Check.typeOf.bool("allowPartial", allowPartial); + Check.defined("result", result); //>>includeEnd('debug'); if (!this._ready) { @@ -443,9 +515,7 @@ DataSourceDisplay.prototype.getBoundingSphere = function ( } boundingSpheres.length = count; - if (defined(result)) { - BoundingSphere.fromBoundingSpheres(boundingSpheres, result); - } + BoundingSphere.fromBoundingSpheres(boundingSpheres, result); return BoundingSphereState.DONE; }; diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index 41d4b549cbf..5f394c780bc 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -1148,7 +1148,7 @@ CesiumWidget.prototype._onTick = function (clock) { const entityView = this._entityView; if (defined(entityView)) { const trackedEntity = this._trackedEntity; - const trackedState = this._dataSourceDisplay.getBoundingSphere( + const trackedState = this._dataSourceDisplay.getBoundingSphereState( trackedEntity, false, ); diff --git a/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js b/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js index 78568aba2f5..522f37e44cd 100644 --- a/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js +++ b/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js @@ -132,6 +132,7 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, true, result); + const stateOnly = display.getBoundingSphereState(entity, true, result); const expected = BoundingSphere.union( visualizer1.getBoundingSphereResult, @@ -139,6 +140,7 @@ describe( ); expect(state).toBe(BoundingSphereState.DONE); + expect(stateOnly).toEqual(state); expect(result).toEqual(expected); }); }); @@ -174,8 +176,10 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, true, result); + const stateOnly = display.getBoundingSphereState(entity, true, result); expect(state).toBe(BoundingSphereState.DONE); + expect(stateOnly).toEqual(state); }); }); @@ -210,8 +214,10 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, true, result); + const stateOnly = display.getBoundingSphereState(entity, true, result); expect(state).toBe(BoundingSphereState.DONE); + expect(stateOnly).toEqual(state); expect(result).toEqual(visualizer2.getBoundingSphereResult); }); }); @@ -244,8 +250,10 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, false, result); + const stateOnly = display.getBoundingSphereState(entity, false, result); expect(state).toBe(BoundingSphereState.PENDING); + expect(stateOnly).toEqual(state); }); it("Fails bounding sphere for entity without visualization.", function () { @@ -261,7 +269,9 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, false, result); + const stateOnly = display.getBoundingSphereState(entity, false, result); expect(state).toBe(BoundingSphereState.FAILED); + expect(stateOnly).toEqual(state); display.destroy(); }); }); @@ -276,7 +286,9 @@ describe( const entity = new Entity(); const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, false, result); + const stateOnly = display.getBoundingSphereState(entity, false, result); expect(state).toBe(BoundingSphereState.FAILED); + expect(stateOnly).toEqual(state); display.destroy(); }); @@ -289,16 +301,20 @@ describe( expect(function () { display.getBoundingSphere(undefined, false, result); }).toThrowDeveloperError(); + expect(function () { + display.getBoundingSphereState(undefined, false); + }).toThrowDeveloperError(); }); - it("Compute bounding sphere doesn't throw without result.", function () { + it("Compute bounding sphere throws without result.", function () { display = new DataSourceDisplay({ dataSourceCollection: dataSourceCollection, scene: scene, }); const entity = new Entity(); - const state = display.getBoundingSphere(entity, false); - expect(state).toBe(BoundingSphereState.PENDING); + expect(function () { + display.getBoundingSphere(entity, false, undefined); + }).toThrowDeveloperError(); }); it("Compute bounding sphere throws without allowPartial.", function () { @@ -311,6 +327,9 @@ describe( expect(function () { display.getBoundingSphere(entity, undefined, result); }).toThrowDeveloperError(); + expect(function () { + display.getBoundingSphereState(entity, undefined); + }).toThrowDeveloperError(); }); it("destroy does not destroy underlying data sources", function () { From 86e341735cc44c3dac86c504b1491b87fbbc6007 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Mon, 3 Mar 2025 18:06:32 +0100 Subject: [PATCH 4/6] fix: reverted EntityView.boundingSphere deprecation --- CHANGES.md | 8 ++ .../Source/DataSources/DataSourceDisplay.js | 74 +------------------ .../engine/Source/DataSources/EntityView.js | 43 +++-------- packages/engine/Source/Widget/CesiumWidget.js | 5 +- .../DataSources/DataSourceDisplaySpec.js | 18 ----- 5 files changed, 25 insertions(+), 123 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index db80b0ba1c9..81cf2d3999f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Change Log +## 1.128 - 2025-04-01 + +### @cesium/engine + +#### Fixes :wrench: + +- Fixed broken Entity Tracking [sandcastle](https://sandcastle.cesium.com/?src=Entity%20tracking.html). [#12467](https://github.com/CesiumGS/cesium/pull/12467) + ## 1.127 - 2025-03-03 ### @cesium/engine diff --git a/packages/engine/Source/DataSources/DataSourceDisplay.js b/packages/engine/Source/DataSources/DataSourceDisplay.js index 067d7e0b1c2..ce405cf9b84 100644 --- a/packages/engine/Source/DataSources/DataSourceDisplay.js +++ b/packages/engine/Source/DataSources/DataSourceDisplay.js @@ -362,80 +362,8 @@ DataSourceDisplay.prototype._postRender = function () { } }; -const getBoundingSphereBoundingSphereScratch = new BoundingSphere(); - -/** - * Computes a bounding sphere state. - * - * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data. - * If false, the the function will halt and return pending if any of the bounding spheres are pending. - * @returns {BoundingSphereState} BoundingSphereState.DONE if the bounding sphere could be returned, - * BoundingSphereState.PENDING if the bounding sphere is still being computed, or - * BoundingSphereState.FAILED if the entity has no visualization in the current scene. - * @private - */ -DataSourceDisplay.prototype.getBoundingSphereState = function ( - entity, - allowPartial, -) { - //>>includeStart('debug', pragmas.debug); - Check.defined("entity", entity); - Check.typeOf.bool("allowPartial", allowPartial); - //>>includeEnd('debug'); - - if (!this._ready) { - return BoundingSphereState.PENDING; - } - - let i; - let length; - let dataSource = this._defaultDataSource; - if (!dataSource.entities.contains(entity)) { - dataSource = undefined; - - const dataSources = this._dataSourceCollection; - length = dataSources.length; - for (i = 0; i < length; i++) { - const d = dataSources.get(i); - if (d.entities.contains(entity)) { - dataSource = d; - break; - } - } - } - - if (!defined(dataSource)) { - return BoundingSphereState.FAILED; - } - - const tmp = getBoundingSphereBoundingSphereScratch; - - let count = 0; - let state = BoundingSphereState.DONE; - const visualizers = dataSource._visualizers; - const visualizersLength = visualizers.length; - - for (i = 0; i < visualizersLength; i++) { - const visualizer = visualizers[i]; - if (defined(visualizer.getBoundingSphere)) { - state = visualizers[i].getBoundingSphere(entity, tmp); - if (!allowPartial && state === BoundingSphereState.PENDING) { - return BoundingSphereState.PENDING; - } else if (state === BoundingSphereState.DONE) { - count++; - } - } - } - - if (count === 0) { - return BoundingSphereState.FAILED; - } - - return BoundingSphereState.DONE; -}; - const getBoundingSphereArrayScratch = []; +const getBoundingSphereBoundingSphereScratch = new BoundingSphere(); /** * Computes a bounding sphere which encloses the visualization produced for the specified entity. diff --git a/packages/engine/Source/DataSources/EntityView.js b/packages/engine/Source/DataSources/EntityView.js index 56abb923a11..9e7ae33234b 100644 --- a/packages/engine/Source/DataSources/EntityView.js +++ b/packages/engine/Source/DataSources/EntityView.js @@ -2,7 +2,6 @@ import Cartesian3 from "../Core/Cartesian3.js"; import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import deprecationWarning from "../Core/deprecationWarning.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import HeadingPitchRange from "../Core/HeadingPitchRange.js"; import JulianDate from "../Core/JulianDate.js"; @@ -44,7 +43,7 @@ function updateTransform( ellipsoid, ) { const mode = that.scene.mode; - const cartesian = positionProperty.getValue(time, that._lastCartesian); + let cartesian = positionProperty.getValue(time, that._lastCartesian); if (defined(cartesian)) { let hasBasis = false; let invertVelocity = false; @@ -217,6 +216,10 @@ function updateTransform( } } + if (defined(that.boundingSphere)) { + cartesian = that.boundingSphere.center; + } + let position; let direction; let up; @@ -343,46 +346,24 @@ function EntityView(entity, scene, ellipsoid) { */ this.ellipsoid = defaultValue(ellipsoid, Ellipsoid.default); + /** + * The bounding sphere of the object. + * @type {BoundingSphere} + */ + this.boundingSphere = undefined; + // Shadow copies of the objects so we can detect changes. this._lastEntity = undefined; this._mode = undefined; this._lastCartesian = new Cartesian3(); this._defaultOffset3D = undefined; - this._boundingSphere = undefined; this._velocityProperty = new VelocityVectorProperty(entity.position, true); this._offset3D = new Cartesian3(); } -// Per instance properties -Object.defineProperties(EntityView.prototype, { - /** - * The bounding sphere of the object. - * @memberof EntityView.prototype - * - * @type {BoundingSphere} - * @deprecated This property has been deprecated and will be removed in Cesium 1.130 - */ - boundingSphere: { - get: function () { - deprecationWarning( - "EntityView.boundingSphere", - "EntityView.boundingSphere has been deprecated and will be removed in Cesium 1.130", - ); - return this._boundingSphere; - }, - set: function (boundingSphere) { - deprecationWarning( - "EntityView.boundingSphere", - "EntityView.boundingSphere has been deprecated and will be removed in Cesium 1.130", - ); - this._boundingSphere = boundingSphere; - }, - }, -}); - // STATIC properties defined here, not per-instance. Object.defineProperties(EntityView, { /** @@ -464,7 +445,7 @@ EntityView.prototype.update = function (time, boundingSphere) { } camera.viewBoundingSphere(boundingSphere, scratchHeadingPitchRange); - this._boundingSphere = boundingSphere; + this.boundingSphere = boundingSphere; updateLookAt = false; saveCamera = false; } else if ( diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index 5f394c780bc..d9a573675c5 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -1134,6 +1134,8 @@ CesiumWidget.prototype._updateCanAnimate = function (isUpdated) { this._clock.canAnimate = isUpdated; }; +const boundingSphereScratch = new BoundingSphere(); + /** * @private */ @@ -1148,9 +1150,10 @@ CesiumWidget.prototype._onTick = function (clock) { const entityView = this._entityView; if (defined(entityView)) { const trackedEntity = this._trackedEntity; - const trackedState = this._dataSourceDisplay.getBoundingSphereState( + const trackedState = this._dataSourceDisplay.getBoundingSphere( trackedEntity, false, + entityView.boundingSphere ?? boundingSphereScratch, ); if (trackedState === BoundingSphereState.DONE) { entityView.update(time); diff --git a/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js b/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js index 522f37e44cd..045cf0a57f9 100644 --- a/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js +++ b/packages/engine/Specs/DataSources/DataSourceDisplaySpec.js @@ -132,7 +132,6 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, true, result); - const stateOnly = display.getBoundingSphereState(entity, true, result); const expected = BoundingSphere.union( visualizer1.getBoundingSphereResult, @@ -140,7 +139,6 @@ describe( ); expect(state).toBe(BoundingSphereState.DONE); - expect(stateOnly).toEqual(state); expect(result).toEqual(expected); }); }); @@ -176,10 +174,8 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, true, result); - const stateOnly = display.getBoundingSphereState(entity, true, result); expect(state).toBe(BoundingSphereState.DONE); - expect(stateOnly).toEqual(state); }); }); @@ -214,10 +210,8 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, true, result); - const stateOnly = display.getBoundingSphereState(entity, true, result); expect(state).toBe(BoundingSphereState.DONE); - expect(stateOnly).toEqual(state); expect(result).toEqual(visualizer2.getBoundingSphereResult); }); }); @@ -250,10 +244,8 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, false, result); - const stateOnly = display.getBoundingSphereState(entity, false, result); expect(state).toBe(BoundingSphereState.PENDING); - expect(stateOnly).toEqual(state); }); it("Fails bounding sphere for entity without visualization.", function () { @@ -269,9 +261,7 @@ describe( const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, false, result); - const stateOnly = display.getBoundingSphereState(entity, false, result); expect(state).toBe(BoundingSphereState.FAILED); - expect(stateOnly).toEqual(state); display.destroy(); }); }); @@ -286,9 +276,7 @@ describe( const entity = new Entity(); const result = new BoundingSphere(); const state = display.getBoundingSphere(entity, false, result); - const stateOnly = display.getBoundingSphereState(entity, false, result); expect(state).toBe(BoundingSphereState.FAILED); - expect(stateOnly).toEqual(state); display.destroy(); }); @@ -301,9 +289,6 @@ describe( expect(function () { display.getBoundingSphere(undefined, false, result); }).toThrowDeveloperError(); - expect(function () { - display.getBoundingSphereState(undefined, false); - }).toThrowDeveloperError(); }); it("Compute bounding sphere throws without result.", function () { @@ -327,9 +312,6 @@ describe( expect(function () { display.getBoundingSphere(entity, undefined, result); }).toThrowDeveloperError(); - expect(function () { - display.getBoundingSphereState(entity, undefined); - }).toThrowDeveloperError(); }); it("destroy does not destroy underlying data sources", function () { From b52997cf87177c84b72dc564ea3c1bb483773171 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Wed, 5 Mar 2025 13:44:51 +0100 Subject: [PATCH 5/6] test: added new test 'jumps to new bounding sphere' --- .../Specs/DataSources/EntityViewSpec.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/engine/Specs/DataSources/EntityViewSpec.js b/packages/engine/Specs/DataSources/EntityViewSpec.js index 7b83c3017e4..dc9a13449f6 100644 --- a/packages/engine/Specs/DataSources/EntityViewSpec.js +++ b/packages/engine/Specs/DataSources/EntityViewSpec.js @@ -115,6 +115,28 @@ describe( expect(scene.camera.positionWC).toEqualEpsilon(positionWC, 1e-10); }); + it("jumps to new bounding sphere", function () { + const bs1 = new BoundingSphere(new Cartesian3(1, 2, 3), 4); + scene.camera.viewBoundingSphere(bs1); + const positionWC1 = scene.camera.positionWC.clone(); + + const bs2 = new BoundingSphere(new Cartesian3(1, 2, 3), 4); + scene.camera.viewBoundingSphere(bs2); + const positionWC2 = scene.camera.positionWC.clone(); + + const entity = new Entity(); + entity.position = new ConstantPositionProperty( + Cartesian3.fromDegrees(0.0, 0.0), + ); + const view = new EntityView(entity, scene, undefined); + view.update(JulianDate.now(), bs1); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC1, 1e-10); + + view.boundingSphere = bs2; + view.update(JulianDate.now()); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC2, 1e-10); + }); + it("uses entity viewFrom if available and boundingsphere is supplied", function () { const sampleOffset = new Cartesian3(1, 2, 3); const entity = new Entity(); From 6b0e50c71131cf22adde880d7c22939a75b67ae4 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Fri, 7 Mar 2025 09:04:39 +0100 Subject: [PATCH 6/6] test: added new test 'jumps to updated bouding sphere' --- .../Specs/DataSources/EntityViewSpec.js | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/engine/Specs/DataSources/EntityViewSpec.js b/packages/engine/Specs/DataSources/EntityViewSpec.js index dc9a13449f6..687e6124588 100644 --- a/packages/engine/Specs/DataSources/EntityViewSpec.js +++ b/packages/engine/Specs/DataSources/EntityViewSpec.js @@ -115,12 +115,34 @@ describe( expect(scene.camera.positionWC).toEqualEpsilon(positionWC, 1e-10); }); + it("jumps to updated bounding sphere", function () { + const bs1 = new BoundingSphere(new Cartesian3(1, 2, 3), 4); + scene.camera.viewBoundingSphere(bs1); + const positionWC1 = scene.camera.positionWC.clone(); + + const bs2 = new BoundingSphere(new Cartesian3(3, 4, 5), 4); + scene.camera.viewBoundingSphere(bs2); + const positionWC2 = scene.camera.positionWC.clone(); + + const entity = new Entity(); + entity.position = new ConstantPositionProperty( + Cartesian3.fromDegrees(0.0, 0.0), + ); + const view = new EntityView(entity, scene, undefined); + view.update(JulianDate.now(), bs1); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC1, 1e-10); + + view.boundingSphere.center = bs2.center; + view.update(JulianDate.now()); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC2, 1e-10); + }); + it("jumps to new bounding sphere", function () { const bs1 = new BoundingSphere(new Cartesian3(1, 2, 3), 4); scene.camera.viewBoundingSphere(bs1); const positionWC1 = scene.camera.positionWC.clone(); - const bs2 = new BoundingSphere(new Cartesian3(1, 2, 3), 4); + const bs2 = new BoundingSphere(new Cartesian3(3, 4, 5), 4); scene.camera.viewBoundingSphere(bs2); const positionWC2 = scene.camera.positionWC.clone();