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/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index b4c34adffd7..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 */ @@ -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, + entityView.boundingSphere ?? boundingSphereScratch, ); if (trackedState === BoundingSphereState.DONE) { - entityView.update(time, entityView.boundingSphere); + entityView.update(time); } } }; diff --git a/packages/engine/Specs/DataSources/EntityViewSpec.js b/packages/engine/Specs/DataSources/EntityViewSpec.js index 61223cc1dd0..687e6124588 100644 --- a/packages/engine/Specs/DataSources/EntityViewSpec.js +++ b/packages/engine/Specs/DataSources/EntityViewSpec.js @@ -89,43 +89,74 @@ 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), + view.update(JulianDate.now(), bs); + 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), ); - expect(view.scene.camera.position).toEqualEpsilon(sampleOffset, 1e-10); + 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(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 = bs2; + view.update(JulianDate.now()); + expect(scene.camera.positionWC).toEqualEpsilon(positionWC2, 1e-10); }); it("uses entity viewFrom if available and boundingsphere is supplied", function () {