From 587f65a2ab8b8111051a3f6a743f586b8045b2d1 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:08:03 -0500 Subject: [PATCH 01/41] create defined types, update Check types, update build --- gulpfile.js | 26 ++++++++++++++++++------ packages/engine/Source/Core/Check.d.ts | 3 ++- packages/engine/Source/Core/defined.d.ts | 11 ++++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 packages/engine/Source/Core/defined.d.ts diff --git a/gulpfile.js b/gulpfile.js index d8407215e9b6..60e92f428199 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1198,12 +1198,19 @@ function generateTypeScriptDefinitions( .replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4") // Replace JSDoc generation version of defined with an improved version using TS type predicates .replace( - /defined\(value: any\): boolean/gm, - "defined(value: Type): value is NonNullable", + /\n?export function defined\(value: any\): boolean;/gm, + `\n${readFileSync("./packages/engine/Source/Core/defined.d.ts") + .toString() + .replace(/\n*\/\*.*?\*\/\n*/gms, "") + .replace("export default", "export")}`, ) + // Replace JSDoc generation version of Check with one that asserts the type of variables after called .replace( /\/\*\*[\*\s\w]*?\*\/\nexport const Check: any;/m, - `\n${readFileSync("./packages/engine/Source/Core/Check.d.ts").toString()}`, + `\n${readFileSync("./packages/engine/Source/Core/Check.d.ts") + .toString() + .replace(/export default.*\n/, "") + .replace("const Check", "export const Check")}`, ) // Fix https://github.com/CesiumGS/cesium/issues/10498 so we can use the rest parameter expand tuple .replace( @@ -1405,12 +1412,19 @@ function createTypeScriptDefinitions() { .replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4") // Replace JSDoc generation version of defined with an improved version using TS type predicates .replace( - /defined\(value: any\): boolean/gm, - "defined(value: Type): value is NonNullable", + /\n?export function defined\(value: any\): boolean;/gm, + `\n${readFileSync("./packages/engine/Source/Core/defined.d.ts") + .toString() + .replace(/\n*\/\*.*?\*\/\n*/gms, "") + .replace("export default", "export")}`, ) + // Replace JSDoc generation version of Check with one that asserts the type of variables after called .replace( /\/\*\*[\*\s\w]*?\*\/\nexport const Check: any;/m, - `\n${readFileSync("./packages/engine/Source/Core/Check.d.ts").toString()}`, + `\n${readFileSync("./packages/engine/Source/Core/Check.d.ts") + .toString() + .replace(/export default.*\n/, "") + .replace("const Check", "export const Check")}`, ) // Fix https://github.com/CesiumGS/cesium/issues/10498 to have rest parameter expand tuple .replace( diff --git a/packages/engine/Source/Core/Check.d.ts b/packages/engine/Source/Core/Check.d.ts index 7930f5175152..35635b4dadd2 100644 --- a/packages/engine/Source/Core/Check.d.ts +++ b/packages/engine/Source/Core/Check.d.ts @@ -2,7 +2,7 @@ * Contains functions for checking that supplied arguments are of a specified type * or meet specified conditions */ -export const Check: { +const Check: { /** * Throws if test is not defined * @@ -125,3 +125,4 @@ export const Check: { }; }; }; +export default Check; diff --git a/packages/engine/Source/Core/defined.d.ts b/packages/engine/Source/Core/defined.d.ts new file mode 100644 index 000000000000..d4cfc604b352 --- /dev/null +++ b/packages/engine/Source/Core/defined.d.ts @@ -0,0 +1,11 @@ +/** + * @example + * if (Cesium.defined(positions)) { + * doSomething(); + * } else { + * doSomethingElse(); + * } + * @param value - The object. + * @returns Returns true if the object is defined, returns false otherwise. + */ +export default function defined(value: Type): value is NonNullable; From 5586cf1ab83c586fd1938ce29c24b12940a948de Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Fri, 22 Nov 2024 12:08:26 -0500 Subject: [PATCH 02/41] make newline optional --- gulpfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 60e92f428199..b1518b0d6258 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1209,7 +1209,7 @@ function generateTypeScriptDefinitions( /\/\*\*[\*\s\w]*?\*\/\nexport const Check: any;/m, `\n${readFileSync("./packages/engine/Source/Core/Check.d.ts") .toString() - .replace(/export default.*\n/, "") + .replace(/export default.*\n?/, "") .replace("const Check", "export const Check")}`, ) // Fix https://github.com/CesiumGS/cesium/issues/10498 so we can use the rest parameter expand tuple @@ -1423,7 +1423,7 @@ function createTypeScriptDefinitions() { /\/\*\*[\*\s\w]*?\*\/\nexport const Check: any;/m, `\n${readFileSync("./packages/engine/Source/Core/Check.d.ts") .toString() - .replace(/export default.*\n/, "") + .replace(/export default.*\n?/, "") .replace("const Check", "export const Check")}`, ) // Fix https://github.com/CesiumGS/cesium/issues/10498 to have rest parameter expand tuple From 76ec83811670ea9079dbcdd6aeb10f4be2226c78 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:08:50 -0500 Subject: [PATCH 03/41] allow DeveloperError matchers to accept regex for messages --- Specs/addDefaultMatchers.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/Specs/addDefaultMatchers.js b/Specs/addDefaultMatchers.js index 9ad56f65c30a..67079ed61042 100644 --- a/Specs/addDefaultMatchers.js +++ b/Specs/addDefaultMatchers.js @@ -46,7 +46,14 @@ function makeAsyncThrowFunction(debug, Type, name) { .catch((e) => { let result = e instanceof Type || e.name === name; if (defined(message)) { - result = result && util.equals(e.message, message); + if (typeof message === "string") { + result = result && e.message === message; + } else { + // if the expected message is a regular expression check it against the error message + // this matches how the builtin .toRejectWithError(Error, /message/) works + // https://github.com/jasmine/jasmine/blob/main/src/core/matchers/toThrowError.js + result = result && message.test(e.message); + } } return { pass: result, @@ -92,7 +99,7 @@ function makeThrowFunction(debug, Type, name) { if (debug) { return function (util) { return { - compare: function (actual, expected) { + compare: function (actual, message) { // based on the built-in Jasmine toThrow matcher let result = false; let exception; @@ -110,20 +117,29 @@ function makeThrowFunction(debug, Type, name) { if (exception) { result = exception instanceof Type || exception.name === name; } + if (defined(message)) { + if (typeof message === "string") { + result = result && exception.message === message; + } else { + // if the expected message is a regular expression check it against the error message + // this matches how the builtin .toRejectWithError(Error, /message/) works + // https://github.com/jasmine/jasmine/blob/main/src/core/matchers/toThrowError.js + result = result && message.test(exception.message); + } + } - let message; + let testMessage; if (result) { - message = [ - `Expected function not to throw ${name} , but it threw`, - exception.message || exception, - ].join(" "); + testMessage = `Expected function not to throw ${name} , but it threw ${exception.message || exception}`; } else { - message = `Expected function to throw ${name}.`; + testMessage = defined(message) + ? `Expected to throw with ${name}: ${message}, but it was thrown with ${exception}` + : `Expected function to throw with ${name}.`; } return { pass: result, - message: message, + message: testMessage, }; }, }; From 647c2e206ac81cc6f60fcbb85038349b217728b8 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:35:40 -0500 Subject: [PATCH 04/41] fix broken tests --- .../Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js | 2 +- packages/engine/Specs/Scene/ImageryLayerSpec.js | 2 +- packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js b/packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js index 416514c4a68e..8816594b228e 100644 --- a/packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js @@ -155,7 +155,7 @@ describe("Scene/GoogleEarthEnterpriseImageryProvider", function () { it("fromMetadata throws without metadata", function () { expect(() => GoogleEarthEnterpriseImageryProvider.fromMetadata(), - ).toThrowDeveloperError(""); + ).toThrowDeveloperError(/metadata is required/); }); it("fromMetadata throws if there isn't imagery", async function () { diff --git a/packages/engine/Specs/Scene/ImageryLayerSpec.js b/packages/engine/Specs/Scene/ImageryLayerSpec.js index 5ec56fae243d..506d3f9ad039 100644 --- a/packages/engine/Specs/Scene/ImageryLayerSpec.js +++ b/packages/engine/Specs/Scene/ImageryLayerSpec.js @@ -78,7 +78,7 @@ describe( it("fromProviderAsync throws without provider promise", function () { expect(() => ImageryLayer.fromProviderAsync()).toThrowDeveloperError( - "expected", + /Expected imageryProviderPromise to be typeof object/, ); }); diff --git a/packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js b/packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js index 2bd1728922d8..eb04cd0f84c3 100644 --- a/packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js @@ -31,7 +31,7 @@ describe("Scene/MapboxStyleImageryProvider", function () { it("requires the styleId to be specified", function () { expect(function () { return new MapboxStyleImageryProvider({ accessToken: "test-token" }); - }).toThrowDeveloperError("styleId is required"); + }).toThrowDeveloperError("options.styleId is required."); }); it("returns valid value for hasAlphaChannel", function () { From 8665d0f560e23402a0ca1071fc4ec1366a540eda Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:28:51 -0500 Subject: [PATCH 05/41] add support for iTwin reality geojson and kml files --- .../gallery/iTwin Feature Service.html | 126 ++++++++++++++++++ packages/engine/Source/Core/ITwinPlatform.js | 41 +----- packages/engine/Source/Scene/ITwinData.js | 70 ++++++++++ 3 files changed, 199 insertions(+), 38 deletions(-) create mode 100644 Apps/Sandcastle/gallery/iTwin Feature Service.html diff --git a/Apps/Sandcastle/gallery/iTwin Feature Service.html b/Apps/Sandcastle/gallery/iTwin Feature Service.html new file mode 100644 index 000000000000..6ec779436fe9 --- /dev/null +++ b/Apps/Sandcastle/gallery/iTwin Feature Service.html @@ -0,0 +1,126 @@ + + + + + + + + + iTwin Feature Service + + + + + +
+

Loading...

+
+
+
+ + + diff --git a/packages/engine/Source/Core/ITwinPlatform.js b/packages/engine/Source/Core/ITwinPlatform.js index c6e9e44ba4a5..fb05dafc377a 100644 --- a/packages/engine/Source/Core/ITwinPlatform.js +++ b/packages/engine/Source/Core/ITwinPlatform.js @@ -38,54 +38,19 @@ ITwinPlatform.ExportType = Object.freeze({ }); /** - * Types of Reality data + * Types of Reality data. This is a partial list of types we know we can support + * * @see https://developer.bentley.com/apis/reality-management/rm-rd-details/#types * @enum {string} */ ITwinPlatform.RealityDataType = Object.freeze({ Cesium3DTiles: "Cesium3DTiles", PNTS: "PNTS", - OPC: "OPC", RealityMesh3DTiles: "RealityMesh3DTiles", Terrain3DTiles: "Terrain3DTiles", - "3MX": "3MX", - "3SM": "3SM", - CCCloudProject: "CCCloudProject", - CCImageCollection: "CCImageCollection", - CCOrientations: "CCOrientations", - ContextCaptureInputs: "ContextCaptureInputs", - ContextDetector: "ContextDetector", - ContextScene: "ContextScene", - DAE: "DAE", - DGN: "DGN", - DSM: "DSM", - FBX: "FBX", - GLB: "GLB", - GLTF: "GLTF", KML: "KML", - LAS: "LAS", - LAZ: "LAZ", - LOD: "LOD", - LodTree: "LodTree", - OBJ: "OBJ", - OMI: "OMI", - OMR: "OMR", - Orthophoto: "Orthophoto", - OrthophotoDSM: "OrthophotoDSM", - OSGB: "OSGB", - OVF: "OVF", - OBT: "OBT", - PLY: "PLY", - PointCloud: "PointCloud", - S3C: "S3C", - ScanCollection: "ScanCollection", - SHP: "SHP", - SLPK: "SLPK", - SpaceEyes3D: "SpaceEyes3D", - STL: "STL", - TSM: "TSM", + GeoJSON: "GeoJSON", Unstructured: "Unstructured", - Other: "Other", }); /** diff --git a/packages/engine/Source/Scene/ITwinData.js b/packages/engine/Source/Scene/ITwinData.js index 1b53f27e4c9e..25fad57eb0aa 100644 --- a/packages/engine/Source/Scene/ITwinData.js +++ b/packages/engine/Source/Scene/ITwinData.js @@ -4,6 +4,8 @@ import Resource from "../Core/Resource.js"; import ITwinPlatform from "../Core/ITwinPlatform.js"; import RuntimeError from "../Core/RuntimeError.js"; import Check from "../Core/Check.js"; +import KmlDataSource from "../DataSources/KmlDataSource.js"; +import GeoJsonDataSource from "../DataSources/GeoJsonDataSource.js"; /** * Methods for loading iTwin platform data into CesiumJS @@ -86,6 +88,8 @@ ITwinData.createTilesetFromIModelId = async function (iModelId, options) { * @param {ITwinPlatform.RealityDataType} [type] The type of this reality data * @param {string} [rootDocument] The path of the root document for this reality data * @returns {Promise} + * + * @throws {RuntimeError} if the type of reality data is not supported by this function */ ITwinData.createTilesetForRealityDataId = async function ( iTwinId, @@ -135,4 +139,70 @@ ITwinData.createTilesetForRealityDataId = async function ( }); }; +/** + * Create a data source of the correct type for the specified reality data id. + * This function only works for KML and GeoJSON type data. + * + * If the type or rootDocument are not provided this function + * will first request the full metadata for the specified reality data to fill these values. + * + * @param {string} iTwinId The id of the iTwin to load data from + * @param {string} realityDataId The id of the reality data to load + * @param {ITwinPlatform.RealityDataType} [type] The type of this reality data + * @param {string} [rootDocument] The path of the root document for this reality data + * @returns {Promise} + * + * @throws {RuntimeError} if the type of reality data is not supported by this function + */ +ITwinData.createDataSourceForRealityDataId = async function loadRealityData( + iTwinId, + realityDataId, + type, + rootDocument, +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.string("iTwinId", iTwinId); + Check.typeOf.string("realityDataId", realityDataId); + if (defined(type)) { + Check.typeOf.string("type", type); + } + if (defined(rootDocument)) { + Check.typeOf.string("rootDocument", rootDocument); + } + //>>includeEnd('debug') + + if (!defined(type) || !defined(rootDocument)) { + const metadata = await ITwinPlatform.getRealityDataMetadata( + iTwinId, + realityDataId, + ); + rootDocument = metadata.rootDocument; + type = metadata.type; + } + + const supportedRealityDataTypes = [ + ITwinPlatform.RealityDataType.KML, + ITwinPlatform.RealityDataType.GeoJSON, + ]; + + if (!supportedRealityDataTypes.includes(type)) { + throw new RuntimeError( + `Reality data type is not a data source type: ${type}`, + ); + } + + const tilesetAccessUrl = await ITwinPlatform.getRealityDataURL( + iTwinId, + realityDataId, + rootDocument, + ); + + if (type === ITwinPlatform.RealityDataType.GeoJSON) { + return GeoJsonDataSource.load(tilesetAccessUrl); + } + + // If we get here it's guaranteed to be a KML type + return KmlDataSource.load(tilesetAccessUrl); +}; + export default ITwinData; From 19fdd8387de03abbc3a171295b80c02c98ecec63 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:57:12 -0500 Subject: [PATCH 06/41] fix and add tests --- packages/engine/Specs/Scene/ITwinDataSpec.js | 127 ++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/packages/engine/Specs/Scene/ITwinDataSpec.js b/packages/engine/Specs/Scene/ITwinDataSpec.js index 8eb4322c5778..25cb98cd2f32 100644 --- a/packages/engine/Specs/Scene/ITwinDataSpec.js +++ b/packages/engine/Specs/Scene/ITwinDataSpec.js @@ -3,6 +3,8 @@ import { RuntimeError, Cesium3DTileset, ITwinData, + GeoJsonDataSource, + KmlDataSource, } from "../../index.js"; function createMockExport( @@ -132,7 +134,7 @@ describe("ITwinData", () => { ITwinData.createTilesetForRealityDataId( "imodel-id-1", "reality-data-id-1", - ITwinPlatform.RealityDataType.DGN, + "DGN", "root/path.json", ), ).toBeRejectedWithError(RuntimeError, /type is not/); @@ -221,4 +223,127 @@ describe("ITwinData", () => { }); }); }); + + describe("createDataSourceForRealityDataId", () => { + let getMetadataSpy; + let getUrlSpy; + let geojsonSpy; + let kmlSpy; + beforeEach(() => { + getMetadataSpy = spyOn(ITwinPlatform, "getRealityDataMetadata"); + getUrlSpy = spyOn(ITwinPlatform, "getRealityDataURL"); + geojsonSpy = spyOn(GeoJsonDataSource, "load"); + kmlSpy = spyOn(KmlDataSource, "load"); + }); + + it("rejects if the type is not supported", async () => { + await expectAsync( + ITwinData.createDataSourceForRealityDataId( + "imodel-id-1", + "reality-data-id-1", + "DGN", + "root/path.json", + ), + ).toBeRejectedWithError(RuntimeError, /type is not/); + }); + + it("does not fetch metadata if type and rootDocument are defined", async () => { + await ITwinData.createDataSourceForRealityDataId( + "itwin-id-1", + "reality-data-id-1", + ITwinPlatform.RealityDataType.GeoJSON, + "root/document/path.json", + ); + + expect(getMetadataSpy).not.toHaveBeenCalled(); + expect(getUrlSpy).toHaveBeenCalledOnceWith( + "itwin-id-1", + "reality-data-id-1", + "root/document/path.json", + ); + expect(geojsonSpy).toHaveBeenCalled(); + }); + + it("fetches metadata if type is undefined", async () => { + getMetadataSpy.and.resolveTo({ + iModelId: "itwin-id-1", + id: "reality-data-id-1", + type: ITwinPlatform.RealityDataType.GeoJSON, + rootDocument: "root/document/path.json", + }); + await ITwinData.createDataSourceForRealityDataId( + "itwin-id-1", + "reality-data-id-1", + undefined, + "root/document/path.json", + ); + + expect(getMetadataSpy).toHaveBeenCalledOnceWith( + "itwin-id-1", + "reality-data-id-1", + ); + expect(getUrlSpy).toHaveBeenCalledOnceWith( + "itwin-id-1", + "reality-data-id-1", + "root/document/path.json", + ); + }); + + it("fetches metadata if rootDocument is undefined", async () => { + getMetadataSpy.and.resolveTo({ + iModelId: "itwin-id-1", + id: "reality-data-id-1", + type: ITwinPlatform.RealityDataType.GeoJSON, + rootDocument: "root/document/path.json", + }); + await ITwinData.createDataSourceForRealityDataId( + "itwin-id-1", + "reality-data-id-1", + ITwinPlatform.RealityDataType.Cesium3DTiles, + undefined, + ); + + expect(getMetadataSpy).toHaveBeenCalledOnceWith( + "itwin-id-1", + "reality-data-id-1", + ); + expect(getUrlSpy).toHaveBeenCalledOnceWith( + "itwin-id-1", + "reality-data-id-1", + "root/document/path.json", + ); + }); + + it("creates a GeoJsonDataSource from the constructed blob url if the type is GeoJSON", async () => { + const tilesetUrl = + "https://example.com/root/document/path.json?auth=token"; + getUrlSpy.and.resolveTo(tilesetUrl); + + await ITwinData.createDataSourceForRealityDataId( + "itwin-id-1", + "reality-data-id-1", + ITwinPlatform.RealityDataType.GeoJSON, + "root/document/path.json", + ); + + expect(geojsonSpy).toHaveBeenCalledOnceWith(tilesetUrl); + expect(kmlSpy).not.toHaveBeenCalled(); + }); + + it("creates a KmlDataSource from the constructed blob url if the type is KML", async () => { + const tilesetUrl = + "https://example.com/root/document/path.json?auth=token"; + getUrlSpy.and.resolveTo(tilesetUrl); + + await ITwinData.createDataSourceForRealityDataId( + "itwin-id-1", + "reality-data-id-1", + ITwinPlatform.RealityDataType.KML, + "root/document/path.json", + ); + + expect(kmlSpy).toHaveBeenCalledOnceWith(tilesetUrl); + expect(geojsonSpy).not.toHaveBeenCalled(); + }); + }); }); From ddd86d6532c6edb424260a3655e9b8068b81221b Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Thu, 28 Nov 2024 11:30:41 +0100 Subject: [PATCH 07/41] fix: fixes issue #11507 (JulianDate.toIso8601 builds a non compliant string with very small milliseconds) --- packages/engine/Source/Core/JulianDate.js | 21 ++++++++----- packages/engine/Specs/Core/JulianDateSpec.js | 32 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/packages/engine/Source/Core/JulianDate.js b/packages/engine/Source/Core/JulianDate.js index 092e4683e5a8..14942c78b64f 100644 --- a/packages/engine/Source/Core/JulianDate.js +++ b/packages/engine/Source/Core/JulianDate.js @@ -10,7 +10,7 @@ import TimeStandard from "./TimeStandard.js"; const gregorianDateScratch = new GregorianDate(); const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; -const daysInLeapFeburary = 29; +const daysInLeapFebruary = 29; function compareLeapSecondDates(leapSecond, dateToFind) { return JulianDate.compare(leapSecond.julianDate, dateToFind.julianDate); @@ -430,7 +430,7 @@ JulianDate.fromIso8601 = function (iso8601String, result) { month > 12 || day < 1 || ((month !== 2 || !inLeapYear) && day > daysInMonth[month - 1]) || - (inLeapYear && month === 2 && day > daysInLeapFeburary) + (inLeapYear && month === 2 && day > daysInLeapFebruary) ) { throw new DeveloperError(iso8601ErrorMessage); } @@ -542,7 +542,7 @@ JulianDate.fromIso8601 = function (iso8601String, result) { day++; } - tmp = inLeapYear && month === 2 ? daysInLeapFeburary : daysInMonth[month - 1]; + tmp = inLeapYear && month === 2 ? daysInLeapFebruary : daysInMonth[month - 1]; while (day > tmp) { day -= tmp; month++; @@ -553,7 +553,7 @@ JulianDate.fromIso8601 = function (iso8601String, result) { } tmp = - inLeapYear && month === 2 ? daysInLeapFeburary : daysInMonth[month - 1]; + inLeapYear && month === 2 ? daysInLeapFebruary : daysInMonth[month - 1]; } //If UTC offset is at the beginning/end of the day, minutes can be negative. @@ -575,7 +575,7 @@ JulianDate.fromIso8601 = function (iso8601String, result) { } tmp = - inLeapYear && month === 2 ? daysInLeapFeburary : daysInMonth[month - 1]; + inLeapYear && month === 2 ? daysInLeapFebruary : daysInMonth[month - 1]; day += tmp; } @@ -784,8 +784,15 @@ JulianDate.toIso8601 = function (julianDate, precision) { let millisecondStr; if (!defined(precision) && millisecond !== 0) { - //Forces milliseconds into a number with at least 3 digits to whatever the default toString() precision is. - millisecondStr = (millisecond * 0.01).toString().replace(".", ""); + //Forces milliseconds into a number with at least 3 digits. + const millisecondHundreds = millisecond * 0.01; + // Below 1e-6 toString uses scientific notation, so we need replace toString by toFixed. + // 20 digits is a trade-off choice guided by JavaScript's Number representation accuracy (15-17 decimal digits for most numbers). + // Using toFixed(20) ensures we capture enough precision while avoiding inaccuracies due to floating-point limitations. + millisecondStr = + millisecondHundreds < 1e-6 + ? millisecondHundreds.toFixed(20).replace(".", "").replace(/0+$/, "") + : millisecondHundreds.toString().replace(".", ""); return `${year.toString().padStart(4, "0")}-${month .toString() .padStart(2, "0")}-${day.toString().padStart(2, "0")}T${hour diff --git a/packages/engine/Specs/Core/JulianDateSpec.js b/packages/engine/Specs/Core/JulianDateSpec.js index 9bc22b32d88e..477270198020 100644 --- a/packages/engine/Specs/Core/JulianDateSpec.js +++ b/packages/engine/Specs/Core/JulianDateSpec.js @@ -877,6 +877,38 @@ describe("Core/JulianDate", function () { expect(date).toEqual("0950-01-02T03:04:05.0123450Z"); }); + it("toIso8601 works with very small milliseconds", function () { + let expectedDate, date; + + expectedDate = new JulianDate(2450630, 1e-3); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + expectedDate = new JulianDate(2450630, 1e-4); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + expectedDate = new JulianDate(2450630, 1e-6); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + expectedDate = new JulianDate(2450630, 1e-7); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + expectedDate = new JulianDate(2450630, 1e-8); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + expectedDate = new JulianDate(2450630, 1e-10); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + expectedDate = new JulianDate(2450630, 1e-15); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + expectedDate = new JulianDate(2450630, 1e-18); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + expectedDate = new JulianDate(2450630, 1e-21); + date = JulianDate.fromIso8601(JulianDate.toIso8601(expectedDate)); + expect(date).toEqual(expectedDate); + }); + it("can format Iso8601.MINIMUM_VALUE and MAXIMUM_VALUE to ISO strings", function () { const minString = Iso8601.MINIMUM_VALUE.toString(); expect(minString).toEqual("0000-01-01T00:00:00Z"); From 16dfdc84a5db8631b5ddf113633ba2aa7d139f6e Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Thu, 28 Nov 2024 11:40:32 +0100 Subject: [PATCH 08/41] doc: updated CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 6c6aca2d2063..b338807383cd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -26,6 +26,7 @@ - Fixed lag or crashes when loading many models in the same frame. [#12320](https://github.com/CesiumGS/cesium/pull/12320) - Updated WMS example URL in UrlTemplateImageryProvider documentation to use an active service. [#12323](https://github.com/CesiumGS/cesium/pull/12323) - Fix point cloud filtering performance on certain hardware [#12317](https://github.com/CesiumGS/cesium/pull/12317) +- Fixed JulianDate to always generate valid ISO strings for fractional milliseconds [#12345](https://github.com/CesiumGS/cesium/pull/12345) ##### Deprecated :hourglass_flowing_sand: From b97ce3093fbb0b3e2e8c636b608ab692f71ff220 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:56:06 -0500 Subject: [PATCH 09/41] update changes --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 6c6aca2d2063..61808466ebdc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ ##### Additions :tada: - Added an integration with the [iTwin Platform](https://developer.bentley.com/) to load iModels as 3D Tiles. Use `ITwinPlatform.defaultAccessToken` to set the access token. Use `ITwinData.createTilesetFromIModelId(iModelId)` to load the iModel as a `Cesium3DTileset`. [#12289](https://github.com/CesiumGS/cesium/pull/12289) +- Added an integration with the [iTwin Platform](https://developer.bentley.com/) to load Reality Data terrain meshes and GeoJSON. Use `ITwinPlatform.defaultAccessToken` to set the access token. Then use `ITwinData.createTilesetForRealityDataId(iTwinId, dataId)` to load terrain meshes as a `Cesium3DTileset` or `ITwinData.createDataSourceForRealityDataId(iTwinId, dataId)` to load GeoJSON or KML files as data sources. [#12344](https://github.com/CesiumGS/cesium/pull/12344) - Added `getSample` to `SampledProperty` to get the time of samples. [#12253](https://github.com/CesiumGS/cesium/pull/12253) - Added `Entity.trackingReferenceFrame` property to allow tracking entities in various reference frames. [#12194](https://github.com/CesiumGS/cesium/pull/12194), [#12314](https://github.com/CesiumGS/cesium/pull/12314) - `TrackingReferenceFrame.AUTODETECT` (default): uses either VVLH or ENU dependeding on entity's dynamic. Use `TrackingReferenceFrame.ENU` if your camera orientation flips abruptly from time to time. From ee72c10b87b922ffa83ebe01f7ad896db5452f6c Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:55:28 -0500 Subject: [PATCH 10/41] add label for prs that need a CLA signed --- .github/actions/check-for-CLA/index.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/actions/check-for-CLA/index.js b/.github/actions/check-for-CLA/index.js index 68684a92624a..7cd4ec1fa96b 100644 --- a/.github/actions/check-for-CLA/index.js +++ b/.github/actions/check-for-CLA/index.js @@ -142,6 +142,17 @@ const postCommentOnPullRequest = async (hasSignedCLA, errorFoundOnCLACheck) => { ); }; +const addLabelToPullRequest = async () => { + const octokit = new Octokit(); + + return octokit.request( + `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/${PULL_REQUST_INFO.id}/labels`, + { + labels: ["PR - Needs Signed CLA"], + }, + ); +}; + const main = async () => { let hasSignedCLA; let errorFoundOnCLACheck; @@ -153,6 +164,10 @@ const main = async () => { } await postCommentOnPullRequest(hasSignedCLA, errorFoundOnCLACheck); + // if (!hasSignedCLA) { + // TODO: make conditional + await addLabelToPullRequest(); + // } }; main(); From 7d9261a4e499954f42d0df2e882bb042e3797bfa Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:00:54 -0500 Subject: [PATCH 11/41] add auth header to label request --- .github/actions/check-for-CLA/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/actions/check-for-CLA/index.js b/.github/actions/check-for-CLA/index.js index 7cd4ec1fa96b..75495fc7049d 100644 --- a/.github/actions/check-for-CLA/index.js +++ b/.github/actions/check-for-CLA/index.js @@ -149,6 +149,11 @@ const addLabelToPullRequest = async () => { `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/${PULL_REQUST_INFO.id}/labels`, { labels: ["PR - Needs Signed CLA"], + headers: { + authorization: `bearer ${PULL_REQUST_INFO.gitHubToken}`, + accept: "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + }, }, ); }; From 99b9343bec559865161f5ca94d5cab29fb543eb1 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:03:25 -0500 Subject: [PATCH 12/41] add extra issue information --- .github/actions/check-for-CLA/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/actions/check-for-CLA/index.js b/.github/actions/check-for-CLA/index.js index 75495fc7049d..9991f82fcff3 100644 --- a/.github/actions/check-for-CLA/index.js +++ b/.github/actions/check-for-CLA/index.js @@ -148,6 +148,9 @@ const addLabelToPullRequest = async () => { return octokit.request( `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/${PULL_REQUST_INFO.id}/labels`, { + owner: PULL_REQUST_INFO.username, + repo: PULL_REQUST_INFO.repoName, + issue_number: PULL_REQUST_INFO.id, labels: ["PR - Needs Signed CLA"], headers: { authorization: `bearer ${PULL_REQUST_INFO.gitHubToken}`, From c40083f67c43e39eaff2a31b3d6244b273a8a1b7 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Tue, 3 Dec 2024 09:21:16 +0100 Subject: [PATCH 13/41] doc: comments improvements --- packages/engine/Source/Core/JulianDate.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Core/JulianDate.js b/packages/engine/Source/Core/JulianDate.js index 14942c78b64f..ec9bfe09da86 100644 --- a/packages/engine/Source/Core/JulianDate.js +++ b/packages/engine/Source/Core/JulianDate.js @@ -784,11 +784,11 @@ JulianDate.toIso8601 = function (julianDate, precision) { let millisecondStr; if (!defined(precision) && millisecond !== 0) { - //Forces milliseconds into a number with at least 3 digits. + // Forces milliseconds into a number with at least 3 digits. const millisecondHundreds = millisecond * 0.01; - // Below 1e-6 toString uses scientific notation, so we need replace toString by toFixed. + // Below 1e-6, toString returns scientific notation, so it should be replaced by toFixed with appropriate number of digits. // 20 digits is a trade-off choice guided by JavaScript's Number representation accuracy (15-17 decimal digits for most numbers). - // Using toFixed(20) ensures we capture enough precision while avoiding inaccuracies due to floating-point limitations. + // Using toFixed(20) ensures capturing enough precision while avoiding inaccuracies due to floating-point limitations. millisecondStr = millisecondHundreds < 1e-6 ? millisecondHundreds.toFixed(20).replace(".", "").replace(/0+$/, "") From c3e326414c06c4b5b0e64b35fd27fd9855e9184d Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Tue, 3 Dec 2024 09:25:25 +0100 Subject: [PATCH 14/41] doc: fixed misspelling --- packages/engine/Specs/Core/JulianDateSpec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/engine/Specs/Core/JulianDateSpec.js b/packages/engine/Specs/Core/JulianDateSpec.js index 477270198020..03842a7f335f 100644 --- a/packages/engine/Specs/Core/JulianDateSpec.js +++ b/packages/engine/Specs/Core/JulianDateSpec.js @@ -594,13 +594,13 @@ describe("Core/JulianDate", function () { }).toThrowDeveloperError(); }); - it("Fails to construct an ISO8601 Febuary date with more than 28 days", function () { + it("Fails to construct an ISO8601 February date with more than 28 days", function () { expect(function () { return JulianDate.fromIso8601("2009-02-29"); }).toThrowDeveloperError(); }); - it("Fails to construct an ISO8601 Febuary leap year date with more than 29 days", function () { + it("Fails to construct an ISO8601 February leap year date with more than 29 days", function () { expect(function () { return JulianDate.fromIso8601("2000-02-30"); }).toThrowDeveloperError(); From 6830637c92e70e17faa3cd8f7555fae550fcac4b Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:53:46 -0500 Subject: [PATCH 15/41] test on PR push --- .github/actions/check-for-CLA/index.js | 3 --- .github/workflows/cla.yml | 7 ++++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/actions/check-for-CLA/index.js b/.github/actions/check-for-CLA/index.js index 9991f82fcff3..75495fc7049d 100644 --- a/.github/actions/check-for-CLA/index.js +++ b/.github/actions/check-for-CLA/index.js @@ -148,9 +148,6 @@ const addLabelToPullRequest = async () => { return octokit.request( `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/${PULL_REQUST_INFO.id}/labels`, { - owner: PULL_REQUST_INFO.username, - repo: PULL_REQUST_INFO.repoName, - issue_number: PULL_REQUST_INFO.id, labels: ["PR - Needs Signed CLA"], headers: { authorization: `bearer ${PULL_REQUST_INFO.gitHubToken}`, diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 60ffd52516e6..9439635b2acb 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -1,5 +1,6 @@ name: check-cla on: + push: pull_request_target: types: [opened] @@ -23,7 +24,7 @@ jobs: run: node index.js env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PULL_REQUEST_ID: ${{ github.event.number }} + PULL_REQUEST_ID: ${{ github.event.number }} GOOGLE_KEYS: ${{ secrets.GOOGLE_KEYS }} - INDIVIDUAL_CLA_SHEET_ID: ${{ secrets.INDIVIDUAL_CLA_SHEET_ID }} - CORPORATE_CLA_SHEET_ID: ${{ secrets.CORPORATE_CLA_SHEET_ID }} \ No newline at end of file + INDIVIDUAL_CLA_SHEET_ID: ${{ secrets.INDIVIDUAL_CLA_SHEET_ID }} + CORPORATE_CLA_SHEET_ID: ${{ secrets.CORPORATE_CLA_SHEET_ID }} From d50b39af1e8e15f88daf976411fbabac942be187 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:56:12 -0500 Subject: [PATCH 16/41] hardcode pr id for testing --- .github/actions/check-for-CLA/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/check-for-CLA/index.js b/.github/actions/check-for-CLA/index.js index 75495fc7049d..63df0398c834 100644 --- a/.github/actions/check-for-CLA/index.js +++ b/.github/actions/check-for-CLA/index.js @@ -146,7 +146,8 @@ const addLabelToPullRequest = async () => { const octokit = new Octokit(); return octokit.request( - `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/${PULL_REQUST_INFO.id}/labels`, + // `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/${PULL_REQUST_INFO.id}/labels`, + `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/12354/labels`, { labels: ["PR - Needs Signed CLA"], headers: { From f445d2e885f79dcffec3a18eded2c9908273de45 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:59:35 -0500 Subject: [PATCH 17/41] testing this sucks --- .github/actions/check-for-CLA/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/check-for-CLA/index.js b/.github/actions/check-for-CLA/index.js index 63df0398c834..f4f817c224ad 100644 --- a/.github/actions/check-for-CLA/index.js +++ b/.github/actions/check-for-CLA/index.js @@ -5,6 +5,8 @@ import fs from "fs-extra"; import { dirname, join } from "path"; import { fileURLToPath } from "url"; +/* eslint-disable no-unused-vars */ + const PULL_REQUST_INFO = { id: process.env.PULL_REQUEST_ID, owner: process.env.GITHUB_REPOSITORY.split("/")[0], @@ -169,7 +171,7 @@ const main = async () => { errorFoundOnCLACheck = error.toString(); } - await postCommentOnPullRequest(hasSignedCLA, errorFoundOnCLACheck); + // await postCommentOnPullRequest(hasSignedCLA, errorFoundOnCLACheck); // if (!hasSignedCLA) { // TODO: make conditional await addLabelToPullRequest(); From 29db63c5657f3fcd3d11e44891f5d8d5545baf94 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:00:55 -0500 Subject: [PATCH 18/41] fix up code --- .github/actions/check-for-CLA/index.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/actions/check-for-CLA/index.js b/.github/actions/check-for-CLA/index.js index f4f817c224ad..bb39551976a1 100644 --- a/.github/actions/check-for-CLA/index.js +++ b/.github/actions/check-for-CLA/index.js @@ -5,8 +5,6 @@ import fs from "fs-extra"; import { dirname, join } from "path"; import { fileURLToPath } from "url"; -/* eslint-disable no-unused-vars */ - const PULL_REQUST_INFO = { id: process.env.PULL_REQUEST_ID, owner: process.env.GITHUB_REPOSITORY.split("/")[0], @@ -148,8 +146,7 @@ const addLabelToPullRequest = async () => { const octokit = new Octokit(); return octokit.request( - // `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/${PULL_REQUST_INFO.id}/labels`, - `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/12354/labels`, + `POST /repos/${PULL_REQUST_INFO.owner}/${PULL_REQUST_INFO.repoName}/issues/${PULL_REQUST_INFO.id}/labels`, { labels: ["PR - Needs Signed CLA"], headers: { @@ -171,11 +168,10 @@ const main = async () => { errorFoundOnCLACheck = error.toString(); } - // await postCommentOnPullRequest(hasSignedCLA, errorFoundOnCLACheck); - // if (!hasSignedCLA) { - // TODO: make conditional - await addLabelToPullRequest(); - // } + await postCommentOnPullRequest(hasSignedCLA, errorFoundOnCLACheck); + if (!hasSignedCLA) { + await addLabelToPullRequest(); + } }; main(); From fa722f9eaa6816c0f81b9d1eb411b01588e3dcb7 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:02:00 -0500 Subject: [PATCH 19/41] only run job on prs --- .github/workflows/cla.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 9439635b2acb..d4ed22242754 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -1,6 +1,5 @@ name: check-cla on: - push: pull_request_target: types: [opened] From 6a36391ac7fca683ba794580f2a48bed3e327fe9 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:07:01 -0500 Subject: [PATCH 20/41] update sandcastle with new itwin and add styling --- .vscode/cspell.json | 1 + .../gallery/iTwin Feature Service.html | 113 +++++++++++++----- 2 files changed, 82 insertions(+), 32 deletions(-) diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 4f3c6c7cb984..e247f0c4a285 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -62,6 +62,7 @@ "iife", "lerp", "Lilli", + "maki", "MAXAR", "minifiers", "mipmapped", diff --git a/Apps/Sandcastle/gallery/iTwin Feature Service.html b/Apps/Sandcastle/gallery/iTwin Feature Service.html index 6ec779436fe9..f7c922661ca9 100644 --- a/Apps/Sandcastle/gallery/iTwin Feature Service.html +++ b/Apps/Sandcastle/gallery/iTwin Feature Service.html @@ -34,37 +34,98 @@ Cesium.ITwinPlatform.defaultAccessToken = token; - const iTwinId = "535a24a3-9b29-4e23-bb5d-9cedb524c743"; + const iTwinId = "04ba725f-f3c0-4f30-8014-a4488cbd612d"; const viewer = new Cesium.Viewer("cesiumContainer"); + const birdsEyeView = { + destination: new Cesium.Cartesian3( + -1525359.4318772827, + 6191643.528984093, + 148851.5321709012, + ), + orientation: new Cesium.HeadingPitchRoll( + 0.16657338935967037, + -0.7943050121851765, + 6.283180723449992, + ), + duration: 0, + easingFunction: Cesium.EasingFunction.LINEAR_NONE, + }; + viewer.scene.camera.flyTo(birdsEyeView); - const featureServiceBaseUrl = "https://featureservice-eus.bentley.com"; - const proxyUrl = "http://localhost:3000/proxy"; - + // Load feature service geojson files const points = await Cesium.ITwinData.createDataSourceForRealityDataId( iTwinId, - "60976bd9-3176-4017-974a-4fcea76346db", + "57b975f6-fd92-42ba-8014-79911ed606d1", ); const lines = await Cesium.ITwinData.createDataSourceForRealityDataId( iTwinId, - "5af22b93-cf7e-4879-9305-4c6bdda7987f", + "1099c53f-c568-48a3-a57c-0230a6f37229", ); const areas = await Cesium.ITwinData.createDataSourceForRealityDataId( iTwinId, - "ebec69b5-0b5f-49d8-9081-e29bcd517f6b", + "21eaf0d0-ab90-400f-97cf-adc455b29a78", ); + + // Add some styling to the lines and points to differentiate types + const pinBuilder = new Cesium.PinBuilder(); + points.entities.values.forEach(async (entity) => { + const styleByType = { + Tree: { color: Cesium.Color.GREEN, icon: "park2" }, + Lamp_post: { color: Cesium.Color.WHITE, icon: "lighthouse" }, + Traffic_light: { color: Cesium.Color.CRIMSON, icon: "circle-stroked" }, + Arrow_Marking: { color: Cesium.Color.YELLOW, icon: "car" }, + Road_Sign: { color: Cesium.Color.ORANGE, icon: "triangle" }, + }; + const type = entity.properties.Type?.getValue(); + if (Cesium.defined(type) && Cesium.defined(styleByType[type])) { + const { color, icon } = styleByType[type]; + const canvas = await pinBuilder.fromMakiIconId(icon, color, 48); + entity.billboard.image = canvas.toDataURL(); + entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM; + } + }); + lines.entities.values.forEach((entity) => { + const lineColorsByType = { + Contours: Cesium.Color.CRIMSON, + Lane_Marking: Cesium.Color.WHITE, + Kerb: Cesium.Color.BLUEVIOLET, + Chevron_marking: Cesium.Color.DARKORANGE, + Turning_pocket: Cesium.Color.DEEPPINK, + Yellow_Box: Cesium.Color.GOLD, + }; + const type = entity.properties.Type?.getValue(); + if (Cesium.defined(type) && Cesium.defined(lineColorsByType[type])) { + entity.polyline.material = lineColorsByType[type]; + } + }); + + // add the geojsons to the viewer viewer.dataSources.add(points); viewer.dataSources.add(lines); viewer.dataSources.add(areas); - // Create tileset of the reality data mesh - // TODO: swap this out with a different mesh - const realityMeshId = "85897090-3bcc-470b-bec7-20bb639cc1b9"; + // Create tileset of the reality data mesh and pointcloud + const realityMeshId = "62e4432d-621d-489a-87ff-1fc56a2b5369"; const realityMesh = await Cesium.ITwinData.createTilesetForRealityDataId( iTwinId, realityMeshId, ); viewer.scene.primitives.add(realityMesh); + const pointcloudId = "ebf2ee74-f0de-4cd6-a311-19a169c55fdc"; + const pointcloud = await Cesium.ITwinData.createTilesetForRealityDataId( + iTwinId, + pointcloudId, + ); + // increase the size of the pointcloud points and turn on attenuation to + // make them more visible in the viewer + pointcloud.maximumScreenSpaceError = 1; + pointcloud.pointCloudShading.attenuation = true; + pointcloud.style = new Cesium.Cesium3DTileStyle({ + pointSize: 5.0, + }); + pointcloud.show = false; + viewer.scene.primitives.add(pointcloud); Sandcastle.addToolbarButton( "Toggle Points", @@ -86,31 +147,19 @@ () => (realityMesh.show = !realityMesh.show), "layers", ); + Sandcastle.addToolbarButton( + "Toggle Pointcloud", + () => (pointcloud.show = !pointcloud.show), + "layers", + ); - Sandcastle.addToolbarButton("Zoom to Lines", () => { - lines.show = true; - viewer.zoomTo(lines); + Sandcastle.addToolbarButton("Birdseye View", () => { + viewer.scene.camera.flyTo(birdsEyeView); }); - Sandcastle.addToolbarButton("Zoom to Reality Mesh", () => { - realityMesh.show = true; - viewer.zoomTo(realityMesh); + Sandcastle.addToolbarButton("Zoom to Pointcloud", () => { + pointcloud.show = true; + viewer.zoomTo(pointcloud); }); - - const birdsEyeView = { - destination: new Cesium.Cartesian3( - -1525452.5685833949, - 6191771.429542403, - 148747.35086195532, - ), - orientation: new Cesium.HeadingPitchRoll( - 3.552713678800501e-15, - -0.7854791130671286, - 6.283185307179583, - ), - duration: 0, - easingFunction: Cesium.EasingFunction.LINEAR_NONE, - }; - viewer.scene.camera.flyTo(birdsEyeView); //Sandcastle_End Sandcastle.finishedLoading(); }; From b27251bf59e107f540092f855a8af7a82107a716 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Wed, 4 Dec 2024 12:34:28 -0500 Subject: [PATCH 21/41] adjust viewer in sandcastle --- .../gallery/iTwin Feature Service.html | 13 +++++++++++-- .../gallery/iTwin Feature Service.jpg | Bin 0 -> 14590 bytes 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 Apps/Sandcastle/gallery/iTwin Feature Service.jpg diff --git a/Apps/Sandcastle/gallery/iTwin Feature Service.html b/Apps/Sandcastle/gallery/iTwin Feature Service.html index f7c922661ca9..d12f117ec3d4 100644 --- a/Apps/Sandcastle/gallery/iTwin Feature Service.html +++ b/Apps/Sandcastle/gallery/iTwin Feature Service.html @@ -36,7 +36,16 @@ const iTwinId = "04ba725f-f3c0-4f30-8014-a4488cbd612d"; - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + geocoder: false, + sceneModePicker: false, + homeButton: false, + timeline: false, + animation: false, + }); + viewer.baseLayerPicker.viewModel.selectedImagery = + viewer.baseLayerPicker.viewModel.imageryProviderViewModels[2]; + const birdsEyeView = { destination: new Cesium.Cartesian3( -1525359.4318772827, @@ -88,7 +97,7 @@ lines.entities.values.forEach((entity) => { const lineColorsByType = { Contours: Cesium.Color.CRIMSON, - Lane_Marking: Cesium.Color.WHITE, + Lane_Marking: Cesium.Color.CYAN, Kerb: Cesium.Color.BLUEVIOLET, Chevron_marking: Cesium.Color.DARKORANGE, Turning_pocket: Cesium.Color.DEEPPINK, diff --git a/Apps/Sandcastle/gallery/iTwin Feature Service.jpg b/Apps/Sandcastle/gallery/iTwin Feature Service.jpg new file mode 100644 index 0000000000000000000000000000000000000000..899bd961ab297c6e003835e8aad40b841d14f87e GIT binary patch literal 14590 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 literal 0 HcmV?d00001 From 3896aea7a59b9b7736e015d7369a19993cfc3c4a Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Fri, 6 Dec 2024 23:07:52 +0100 Subject: [PATCH 22/41] Change toBeCloseTo to toEqualEpsilon --- packages/engine/Specs/Scene/I3SNodeSpec.js | 12 ++++++------ .../Scene/OpenStreetMapImageryProviderSpec.js | 8 ++++---- .../Scene/TileMapServiceImageryProviderSpec.js | 14 +++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/engine/Specs/Scene/I3SNodeSpec.js b/packages/engine/Specs/Scene/I3SNodeSpec.js index 8cdf6e51e6a2..bc5e1114c626 100644 --- a/packages/engine/Specs/Scene/I3SNodeSpec.js +++ b/packages/engine/Specs/Scene/I3SNodeSpec.js @@ -698,17 +698,17 @@ describe("Scene/I3SNode", function () { expectedHeight, ); - expect(cartographicOrigin.longitude).toBeCloseTo( + expect(cartographicOrigin.longitude).toEqualEpsilon( expectedPosition.longitude, - -3, + CesiumMath.EPSILON3, ); - expect(cartographicOrigin.latitude).toBeCloseTo( + expect(cartographicOrigin.latitude).toEqualEpsilon( expectedPosition.latitude, - -3, + CesiumMath.EPSILON3, ); - expect(cartographicOrigin.height).toBeCloseTo( + expect(cartographicOrigin.height).toEqualEpsilon( expectedPosition.height, - -3, + CesiumMath.EPSILON3, ); }); }); diff --git a/packages/engine/Specs/Scene/OpenStreetMapImageryProviderSpec.js b/packages/engine/Specs/Scene/OpenStreetMapImageryProviderSpec.js index 238e58b117cf..08ae7a5127d9 100644 --- a/packages/engine/Specs/Scene/OpenStreetMapImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/OpenStreetMapImageryProviderSpec.js @@ -168,19 +168,19 @@ describe("Scene/OpenStreetMapImageryProvider", function () { expect(provider.tileHeight).toEqual(256); expect(provider.maximumLevel).toBeUndefined(); expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.rectangle.west).toBeCloseTo( + expect(provider.rectangle.west).toEqualEpsilon( rectangle.west, CesiumMath.EPSILON10, ); - expect(provider.rectangle.south).toBeCloseTo( + expect(provider.rectangle.south).toEqualEpsilon( rectangle.south, CesiumMath.EPSILON10, ); - expect(provider.rectangle.east).toBeCloseTo( + expect(provider.rectangle.east).toEqualEpsilon( rectangle.east, CesiumMath.EPSILON10, ); - expect(provider.rectangle.north).toBeCloseTo( + expect(provider.rectangle.north).toEqualEpsilon( rectangle.north, CesiumMath.EPSILON10, ); diff --git a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js index 0e766f18b399..38e3604edc72 100644 --- a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js @@ -586,7 +586,7 @@ describe("Scene/TileMapServiceImageryProvider", function () { expect(provider.rectangle.west).toEqual(expectedSW.longitude); expect(provider.rectangle.south).toEqual(expectedSW.latitude); - expect(provider.rectangle.east).toBeCloseTo( + expect(provider.rectangle.east).toEqualEpsilon( expectedNE.longitude, CesiumMath.EPSILON14, ); @@ -620,12 +620,12 @@ describe("Scene/TileMapServiceImageryProvider", function () { const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); - expect(provider.rectangle.west).toBeCloseTo( + expect(provider.rectangle.west).toEqualEpsilon( expectedSW.longitude, CesiumMath.EPSILON14, ); expect(provider.rectangle.south).toEqual(expectedSW.latitude); - expect(provider.rectangle.east).toBeCloseTo( + expect(provider.rectangle.east).toEqualEpsilon( expectedNE.longitude, CesiumMath.EPSILON14, ); @@ -663,12 +663,12 @@ describe("Scene/TileMapServiceImageryProvider", function () { const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); - expect(provider.rectangle.west).toBeCloseTo( + expect(provider.rectangle.west).toEqualEpsilon( expectedSW.longitude, CesiumMath.EPSILON14, ); expect(provider.rectangle.south).toEqual(expectedSW.latitude); - expect(provider.rectangle.east).toBeCloseTo( + expect(provider.rectangle.east).toEqualEpsilon( expectedNE.longitude, CesiumMath.EPSILON14, ); @@ -706,12 +706,12 @@ describe("Scene/TileMapServiceImageryProvider", function () { const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); - expect(provider.rectangle.west).toBeCloseTo( + expect(provider.rectangle.west).toEqualEpsilon( expectedSW.longitude, CesiumMath.EPSILON14, ); expect(provider.rectangle.south).toEqual(expectedSW.latitude); - expect(provider.rectangle.east).toBeCloseTo( + expect(provider.rectangle.east).toEqualEpsilon( expectedNE.longitude, CesiumMath.EPSILON14, ); From c4a89483eee3989951469a57c64d511f6ff13d5f Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Wed, 4 Dec 2024 19:43:45 +0100 Subject: [PATCH 23/41] fix: fixes issue #12356 performance drop --- .../engine/Source/DataSources/ModelGraphics.js | 16 ++++++++++++++++ .../engine/Source/DataSources/ModelVisualizer.js | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/packages/engine/Source/DataSources/ModelGraphics.js b/packages/engine/Source/DataSources/ModelGraphics.js index 8320768fa319..c5f33788ae41 100644 --- a/packages/engine/Source/DataSources/ModelGraphics.js +++ b/packages/engine/Source/DataSources/ModelGraphics.js @@ -46,6 +46,7 @@ function createArticulationStagePropertyBag(value) { * @property {PropertyBag | Object} [articulations] An object, where keys are composed of an articulation name, a single space, and a stage name, and the values are numeric properties. * @property {Property | ClippingPlaneCollection} [clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @property {Property | CustomShader} [customShader] A property specifying the {@link CustomShader} to apply to this model. + * @property {Property | boolean} [enableEnvironmentMap=true] A boolean Property specifying if the model has {@link DynamicEnvironmentMapManager} enabled. */ /** @@ -113,6 +114,8 @@ function ModelGraphics(options) { this._clippingPlanesSubscription = undefined; this._customShader = undefined; this._customShaderSubscription = undefined; + this._enableEnvironmentMap = undefined; + this._enableEnvironmentMapSubscription = undefined; this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); } @@ -333,6 +336,14 @@ Object.defineProperties(ModelGraphics.prototype, { * @type {Property|undefined} */ customShader: createPropertyDescriptor("customShader"), + + /** + * Gets or sets the boolean Property specifying if the model has {@link DynamicEnvironmentMapManager} enabled. + * @memberof ModelGraphics.prototype + * @type {Property|undefined} + * @default true + */ + enableEnvironmentMap: createPropertyDescriptor("enableEnvironmentMap"), }); /** @@ -367,6 +378,7 @@ ModelGraphics.prototype.clone = function (result) { result.articulations = this.articulations; result.clippingPlanes = this.clippingPlanes; result.customShader = this.customShader; + result.enableEnvironmentMap = this.enableEnvironmentMap; return result; }; @@ -441,6 +453,10 @@ ModelGraphics.prototype.merge = function (source) { source.clippingPlanes, ); this.customShader = defaultValue(this.customShader, source.customShader); + this.enableEnvironmentMap = defaultValue( + this.enableEnvironmentMap, + source.enableEnvironmentMap, + ); const sourceNodeTransformations = source.nodeTransformations; if (defined(sourceNodeTransformations)) { diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index 42d1bd177592..9c8fa3d6749f 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -35,6 +35,7 @@ const defaultColor = Color.WHITE; const defaultColorBlendMode = ColorBlendMode.HIGHLIGHT; const defaultColorBlendAmount = 0.5; const defaultImageBasedLightingFactor = new Cartesian2(1.0, 1.0); +const defaultEnableEnvironmentMap = true; const modelMatrixScratch = new Matrix4(); const nodeMatrixScratch = new Matrix4(); @@ -289,6 +290,12 @@ ModelVisualizer.prototype.update = function (time) { time, ); + model.environmentMapManager.enabled = Property.getValueOrDefault( + modelGraphics._enableEnvironmentMap, + time, + defaultEnableEnvironmentMap, + ); + // It's possible for getBoundingSphere to run before // model becomes ready and these properties are updated modelHash[entity.id].modelUpdated = true; From ded622be536054a962115af14d58f51ae1e73ac1 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Wed, 4 Dec 2024 20:03:20 +0100 Subject: [PATCH 24/41] doc: updated CHANGES.md --- CHANGES.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 698829a9cbd4..a3c564a08a85 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Change Log +### 1.125 - 2025-01-02 + +#### @cesium/engine + +##### Fixes :wrench: + +- Added `enableEnvironmentMap` to `ModelGraphics` constructor options to allow long distance `Entity` movements without performance drop. [#12358](https://github.com/CesiumGS/cesium/pull/12358) + ### 1.124 - 2024-12-02 #### @cesium/engine @@ -90,9 +98,6 @@ - Fix flickering issue caused by bounding sphere retrieval being blocked by the bounding sphere of another entity. [#12230](https://github.com/CesiumGS/cesium/pull/12230) - Fixed `ImageBasedLighting.imageBasedLightingFactor` not affecting lighting. [#12129](https://github.com/CesiumGS/cesium/pull/12129) - Fix error with normalization of corner points for lines and corridors with collinear points. [#12255](https://github.com/CesiumGS/cesium/pull/12255) - -##### Fixes :wrench: - - Properly handle `offset` and `scale` properties when picking metadata from property textures. [#12237](https://github.com/CesiumGS/cesium/pull/12237) ### 1.122 - 2024-10-01 From 83c92a1ffa22a684c65e0dff5d15ff173399ee43 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Thu, 5 Dec 2024 10:15:53 +0100 Subject: [PATCH 25/41] test: updated unit tests --- .../engine/Specs/DataSources/ModelGraphicsSpec.js | 12 ++++++++++++ .../engine/Specs/DataSources/ModelVisualizerSpec.js | 3 +++ 2 files changed, 15 insertions(+) diff --git a/packages/engine/Specs/DataSources/ModelGraphicsSpec.js b/packages/engine/Specs/DataSources/ModelGraphicsSpec.js index 3f49259bd9f6..4a4158742c07 100644 --- a/packages/engine/Specs/DataSources/ModelGraphicsSpec.js +++ b/packages/engine/Specs/DataSources/ModelGraphicsSpec.js @@ -49,6 +49,7 @@ describe("DataSources/ModelGraphics", function () { articulations: { "articulation1 stage1": 45, }, + enableEnvironmentMap: false, }; const model = new ModelGraphics(options); @@ -104,6 +105,9 @@ describe("DataSources/ModelGraphics", function () { expect(model.lightColor.getValue()).toEqual(options.lightColor); expect(model.runAnimations.getValue()).toEqual(options.runAnimations); expect(model.clampAnimations.getValue()).toEqual(options.clampAnimations); + expect(model.enableEnvironmentMap.getValue()).toEqual( + options.enableEnvironmentMap, + ); let actualNodeTransformations = model.nodeTransformations.getValue( new JulianDate(), @@ -172,6 +176,7 @@ describe("DataSources/ModelGraphics", function () { "a1 s1": 10, "a2 s2": 20, }; + source.enableEnvironmentMap = new ConstantProperty(true); const target = new ModelGraphics(); target.merge(source); @@ -204,6 +209,7 @@ describe("DataSources/ModelGraphics", function () { expect(target.clampAnimations).toBe(source.clampAnimations); expect(target.nodeTransformations).toEqual(source.nodeTransformations); expect(target.articulations).toEqual(source.articulations); + expect(target.enableEnvironmentMap).toBe(source.enableEnvironmentMap); }); it("merge does not assign assigned properties", function () { @@ -241,6 +247,7 @@ describe("DataSources/ModelGraphics", function () { "a1 s1": 10, "a2 s2": 20, }; + source.enableEnvironmentMap = new ConstantProperty(true); const uri = new ConstantProperty(""); const show = new ConstantProperty(true); @@ -275,6 +282,7 @@ describe("DataSources/ModelGraphics", function () { "a1 s1": 10, "a2 s2": 20, }); + const enableEnvironmentMap = new ConstantProperty(true); const target = new ModelGraphics(); target.uri = uri; @@ -299,6 +307,7 @@ describe("DataSources/ModelGraphics", function () { target.clampAnimations = clampAnimations; target.nodeTransformations = nodeTransformations; target.articulations = articulations; + target.enableEnvironmentMap = enableEnvironmentMap; target.merge(source); @@ -324,6 +333,7 @@ describe("DataSources/ModelGraphics", function () { expect(target.clampAnimations).toBe(clampAnimations); expect(target.nodeTransformations).toBe(nodeTransformations); expect(target.articulations).toBe(articulations); + expect(target.enableEnvironmentMap).toBe(enableEnvironmentMap); }); it("clone works", function () { @@ -362,6 +372,7 @@ describe("DataSources/ModelGraphics", function () { "a1 s1": 10, "a2 s2": 20, }; + source.enableEnvironmentMap = new ConstantProperty(true); const result = source.clone(); expect(result.uri).toBe(source.uri); @@ -392,6 +403,7 @@ describe("DataSources/ModelGraphics", function () { expect(result.clampAnimations).toBe(source.clampAnimations); expect(result.nodeTransformations).toEqual(source.nodeTransformations); expect(result.articulations).toEqual(source.articulations); + expect(result.enableEnvironmentMap).toEqual(source.enableEnvironmentMap); }); it("merge throws if source undefined", function () { diff --git a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js index 738d0db51195..385a4f754064 100644 --- a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js @@ -146,6 +146,7 @@ describe( new Cartesian2(0.5, 0.5), ); model.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0)); + model.enableEnvironmentMap = new ConstantProperty(false); const testObject = entityCollection.getOrCreateEntity("test"); testObject.position = new ConstantPositionProperty( @@ -196,6 +197,8 @@ describe( expect(primitive.lightColor).toEqual(new Cartesian3(1.0, 1.0, 0.0)); + expect(primitive.environmentMapManager.enabled).toEqual(false); + // wait till the model is loaded before we can check node transformations await pollToPromise(function () { scene.render(); From 3e617cdf22b3a3c510cd73aa554f8bae81a79e02 Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Thu, 5 Dec 2024 10:26:17 +0100 Subject: [PATCH 26/41] doc: fixed spelling --- .vscode/cspell.json | 2 ++ packages/engine/Source/Scene/Model/Model.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.vscode/cspell.json b/.vscode/cspell.json index e247f0c4a285..e6c151802a4c 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -36,6 +36,7 @@ "3DTILES", "aabb", "Amato", + "basisu", "bathymetric", "bitangent", "bitangents", @@ -43,6 +44,7 @@ "Bourke", "brdf", "cartesians", + "carto", "cartographics", "cesiumjs", "comms", diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index 1e76382b423c..d1aae816fd2a 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -1823,7 +1823,7 @@ Model.prototype.applyArticulations = function () { * * The given name may be the name of a glTF extension, like `"EXT_example_extension"`. * If the specified extension was present in the root of the underlying glTF asset, - * and a loder for the specified extension has processed the extension data, then + * and a loader for the specified extension has processed the extension data, then * this will return the model representation of the extension. * * @param {string} extensionName The name of the extension From 110e57f90a6fe1b05af48020a0bf3f49669093cd Mon Sep 17 00:00:00 2001 From: "jerome.fayot" Date: Mon, 9 Dec 2024 17:19:24 +0100 Subject: [PATCH 27/41] feat: moved environmentMapOptions to Entity --- .vscode/cspell.json | 1 + CHANGES.md | 2 +- .../DataSources/Cesium3DTilesetVisualizer.js | 4 +++- packages/engine/Source/DataSources/Entity.js | 4 ++++ .../engine/Source/DataSources/ModelGraphics.js | 16 ---------------- .../engine/Source/DataSources/ModelVisualizer.js | 8 +------- packages/engine/Source/Scene/Cesium3DTileset.js | 2 +- .../DataSources/Cesium3DTilesetVisualizerSpec.js | 1 + .../Specs/DataSources/ModelGraphicsSpec.js | 12 ------------ .../Specs/DataSources/ModelVisualizerSpec.js | 1 - 10 files changed, 12 insertions(+), 39 deletions(-) diff --git a/.vscode/cspell.json b/.vscode/cspell.json index e6c151802a4c..f8083d9b09d2 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -95,6 +95,7 @@ "unregisters", "unrenderable", "voxel", + "VVLH", "WEBG", "xdescribe" ] diff --git a/CHANGES.md b/CHANGES.md index a3c564a08a85..d9488882d033 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ ##### Fixes :wrench: -- Added `enableEnvironmentMap` to `ModelGraphics` constructor options to allow long distance `Entity` movements without performance drop. [#12358](https://github.com/CesiumGS/cesium/pull/12358) +- Added `environmentMapOptions` to `Entity`'s constructor options with EnvironmentMap disabled by default to allow long distance `Entity` jumps without performance drop. If EnvironmentMap needs to be enabled, ensure to provide a `maximumPositionEpsilon` threshold value large enough with your entity movements use case. [#12358](https://github.com/CesiumGS/cesium/pull/12358) ### 1.124 - 2024-12-02 diff --git a/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js b/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js index 314edf37e1c1..7317cd97d59b 100644 --- a/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js +++ b/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js @@ -243,7 +243,9 @@ async function createTileset(resource, tilesetHash, entity, primitives) { }; try { - const tileset = await Cesium3DTileset.fromUrl(resource); + const tileset = await Cesium3DTileset.fromUrl(resource, { + environmentMapOptions: entity._environmentMapOptions, + }); tileset.id = entity; primitives.add(tileset); diff --git a/packages/engine/Source/DataSources/Entity.js b/packages/engine/Source/DataSources/Entity.js index d8c9fab17f9e..2d308b022a1e 100644 --- a/packages/engine/Source/DataSources/Entity.js +++ b/packages/engine/Source/DataSources/Entity.js @@ -98,6 +98,7 @@ function createPropertyTypeDescriptor(name, Type) { * @property {PolylineVolumeGraphics | PolylineVolumeGraphics.ConstructorOptions} [polylineVolume] A polylineVolume to associate with this entity. * @property {RectangleGraphics | RectangleGraphics.ConstructorOptions} [rectangle] A rectangle to associate with this entity. * @property {WallGraphics | WallGraphics.ConstructorOptions} [wall] A wall to associate with this entity. + * @property {DynamicEnvironmentMapManager.ConstructorOptions} [environmentMapOptions={enabled: false}] The properties for managing dynamic environment maps on this entity. */ /** @@ -122,6 +123,9 @@ function Entity(options) { this._availability = undefined; this._id = id; this._definitionChanged = new Event(); + this._environmentMapOptions = defaultValue(options.environmentMapOptions, { + enabled: false, + }); this._name = options.name; this._show = defaultValue(options.show, true); this._trackingReferenceFrame = defaultValue( diff --git a/packages/engine/Source/DataSources/ModelGraphics.js b/packages/engine/Source/DataSources/ModelGraphics.js index c5f33788ae41..8320768fa319 100644 --- a/packages/engine/Source/DataSources/ModelGraphics.js +++ b/packages/engine/Source/DataSources/ModelGraphics.js @@ -46,7 +46,6 @@ function createArticulationStagePropertyBag(value) { * @property {PropertyBag | Object} [articulations] An object, where keys are composed of an articulation name, a single space, and a stage name, and the values are numeric properties. * @property {Property | ClippingPlaneCollection} [clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @property {Property | CustomShader} [customShader] A property specifying the {@link CustomShader} to apply to this model. - * @property {Property | boolean} [enableEnvironmentMap=true] A boolean Property specifying if the model has {@link DynamicEnvironmentMapManager} enabled. */ /** @@ -114,8 +113,6 @@ function ModelGraphics(options) { this._clippingPlanesSubscription = undefined; this._customShader = undefined; this._customShaderSubscription = undefined; - this._enableEnvironmentMap = undefined; - this._enableEnvironmentMapSubscription = undefined; this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); } @@ -336,14 +333,6 @@ Object.defineProperties(ModelGraphics.prototype, { * @type {Property|undefined} */ customShader: createPropertyDescriptor("customShader"), - - /** - * Gets or sets the boolean Property specifying if the model has {@link DynamicEnvironmentMapManager} enabled. - * @memberof ModelGraphics.prototype - * @type {Property|undefined} - * @default true - */ - enableEnvironmentMap: createPropertyDescriptor("enableEnvironmentMap"), }); /** @@ -378,7 +367,6 @@ ModelGraphics.prototype.clone = function (result) { result.articulations = this.articulations; result.clippingPlanes = this.clippingPlanes; result.customShader = this.customShader; - result.enableEnvironmentMap = this.enableEnvironmentMap; return result; }; @@ -453,10 +441,6 @@ ModelGraphics.prototype.merge = function (source) { source.clippingPlanes, ); this.customShader = defaultValue(this.customShader, source.customShader); - this.enableEnvironmentMap = defaultValue( - this.enableEnvironmentMap, - source.enableEnvironmentMap, - ); const sourceNodeTransformations = source.nodeTransformations; if (defined(sourceNodeTransformations)) { diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index 9c8fa3d6749f..1de790ac24f4 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -35,7 +35,6 @@ const defaultColor = Color.WHITE; const defaultColorBlendMode = ColorBlendMode.HIGHLIGHT; const defaultColorBlendAmount = 0.5; const defaultImageBasedLightingFactor = new Cartesian2(1.0, 1.0); -const defaultEnableEnvironmentMap = true; const modelMatrixScratch = new Matrix4(); const nodeMatrixScratch = new Matrix4(); @@ -86,6 +85,7 @@ async function createModelPrimitive( url: resource, incrementallyLoadTextures: incrementallyLoadTextures, scene: visualizer._scene, + environmentMapOptions: entity._environmentMapOptions, }); if (visualizer.isDestroyed() || !defined(modelHash[entity.id])) { @@ -290,12 +290,6 @@ ModelVisualizer.prototype.update = function (time) { time, ); - model.environmentMapManager.enabled = Property.getValueOrDefault( - modelGraphics._enableEnvironmentMap, - time, - defaultEnableEnvironmentMap, - ); - // It's possible for getBoundingSphere to run before // model becomes ready and these properties are updated modelHash[entity.id].modelUpdated = true; diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index e23d1061792b..bf2779cc6dcc 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -105,7 +105,7 @@ import DynamicEnvironmentMapManager from "./DynamicEnvironmentMapManager.js"; * @property {object} [pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. * @property {Cartesian3} [lightColor] The light color when shading models. When undefined the scene's light color is used instead. * @property {ImageBasedLighting} [imageBasedLighting] The properties for managing image-based lighting for this tileset. - * @param {DynamicEnvironmentMapManager.ConstructorOptions} [options.environmentMapOptions] The properties for managing dynamic environment maps on this model. + * @property {DynamicEnvironmentMapManager.ConstructorOptions} [environmentMapOptions] The properties for managing dynamic environment maps on this tileset. * @property {boolean} [backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. * @property {boolean} [enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. * @property {boolean} [showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. diff --git a/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js b/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js index 0c9ef09da4fe..09e85ef0be3c 100644 --- a/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js @@ -133,6 +133,7 @@ describe( visualizer.update(time); expect(primitive.show).toEqual(true); expect(primitive.maximumScreenSpaceError).toEqual(24.0); + expect(primitive.environmentMapManager.enabled).toEqual(false); }); it("A Cesium3DTilesetGraphics with a Resource causes a primitive to be created.", async function () { diff --git a/packages/engine/Specs/DataSources/ModelGraphicsSpec.js b/packages/engine/Specs/DataSources/ModelGraphicsSpec.js index 4a4158742c07..3f49259bd9f6 100644 --- a/packages/engine/Specs/DataSources/ModelGraphicsSpec.js +++ b/packages/engine/Specs/DataSources/ModelGraphicsSpec.js @@ -49,7 +49,6 @@ describe("DataSources/ModelGraphics", function () { articulations: { "articulation1 stage1": 45, }, - enableEnvironmentMap: false, }; const model = new ModelGraphics(options); @@ -105,9 +104,6 @@ describe("DataSources/ModelGraphics", function () { expect(model.lightColor.getValue()).toEqual(options.lightColor); expect(model.runAnimations.getValue()).toEqual(options.runAnimations); expect(model.clampAnimations.getValue()).toEqual(options.clampAnimations); - expect(model.enableEnvironmentMap.getValue()).toEqual( - options.enableEnvironmentMap, - ); let actualNodeTransformations = model.nodeTransformations.getValue( new JulianDate(), @@ -176,7 +172,6 @@ describe("DataSources/ModelGraphics", function () { "a1 s1": 10, "a2 s2": 20, }; - source.enableEnvironmentMap = new ConstantProperty(true); const target = new ModelGraphics(); target.merge(source); @@ -209,7 +204,6 @@ describe("DataSources/ModelGraphics", function () { expect(target.clampAnimations).toBe(source.clampAnimations); expect(target.nodeTransformations).toEqual(source.nodeTransformations); expect(target.articulations).toEqual(source.articulations); - expect(target.enableEnvironmentMap).toBe(source.enableEnvironmentMap); }); it("merge does not assign assigned properties", function () { @@ -247,7 +241,6 @@ describe("DataSources/ModelGraphics", function () { "a1 s1": 10, "a2 s2": 20, }; - source.enableEnvironmentMap = new ConstantProperty(true); const uri = new ConstantProperty(""); const show = new ConstantProperty(true); @@ -282,7 +275,6 @@ describe("DataSources/ModelGraphics", function () { "a1 s1": 10, "a2 s2": 20, }); - const enableEnvironmentMap = new ConstantProperty(true); const target = new ModelGraphics(); target.uri = uri; @@ -307,7 +299,6 @@ describe("DataSources/ModelGraphics", function () { target.clampAnimations = clampAnimations; target.nodeTransformations = nodeTransformations; target.articulations = articulations; - target.enableEnvironmentMap = enableEnvironmentMap; target.merge(source); @@ -333,7 +324,6 @@ describe("DataSources/ModelGraphics", function () { expect(target.clampAnimations).toBe(clampAnimations); expect(target.nodeTransformations).toBe(nodeTransformations); expect(target.articulations).toBe(articulations); - expect(target.enableEnvironmentMap).toBe(enableEnvironmentMap); }); it("clone works", function () { @@ -372,7 +362,6 @@ describe("DataSources/ModelGraphics", function () { "a1 s1": 10, "a2 s2": 20, }; - source.enableEnvironmentMap = new ConstantProperty(true); const result = source.clone(); expect(result.uri).toBe(source.uri); @@ -403,7 +392,6 @@ describe("DataSources/ModelGraphics", function () { expect(result.clampAnimations).toBe(source.clampAnimations); expect(result.nodeTransformations).toEqual(source.nodeTransformations); expect(result.articulations).toEqual(source.articulations); - expect(result.enableEnvironmentMap).toEqual(source.enableEnvironmentMap); }); it("merge throws if source undefined", function () { diff --git a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js index 385a4f754064..92b90d66320e 100644 --- a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js @@ -146,7 +146,6 @@ describe( new Cartesian2(0.5, 0.5), ); model.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0)); - model.enableEnvironmentMap = new ConstantProperty(false); const testObject = entityCollection.getOrCreateEntity("test"); testObject.position = new ConstantPositionProperty( From 26c7ffa749895d1098a2dfef42c6a60f156396ec Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Mon, 9 Dec 2024 16:08:55 -0500 Subject: [PATCH 28/41] add documentation about testing errors --- .../Contributors/TestingGuide/README.md | 20 +++++++++++++++---- packages/engine/Specs/Core/Cartesian3Spec.js | 10 ++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Documentation/Contributors/TestingGuide/README.md b/Documentation/Contributors/TestingGuide/README.md index 915c8bf38d38..ffde3a98870a 100644 --- a/Documentation/Contributors/TestingGuide/README.md +++ b/Documentation/Contributors/TestingGuide/README.md @@ -441,14 +441,26 @@ In addition to testing success cases, we also test all failure cases. The custom ```javascript it("fromDegrees throws with no latitude", function () { expect(function () { - Cartesian3.fromDegrees(0.0); - }).toThrowDeveloperError(); + Cartesian3.fromDegrees(0.0, undefined); + }).toThrowDeveloperError( + "Expected latitude to be typeof number, actual typeof was undefined", + ); }); ``` Above, `Cartesian3.fromDegrees` is expected to throw a `DeveloperError` because it expects longitude and latitude arguments, and only longitude is provided. -Tips: +#### Tips + +- When testing for exceptions it is recommended to test for the expected error message to verify that the test is triggering the correct error. This can be achieved either with the full error message, like above, or with a regular expression that will match the error message like this: + +```javascript +it("fromDegrees throws with no latitude", function () { + expect(function () { + Cartesian3.fromDegrees(0.0, undefined); + }).toThrowDeveloperError(/Expected latitude to be/); +}); +``` - When testing for exceptions, put only code that is expected to trigger the exception inside the function passed to `expect()`, in case setup code unintentionally throws an exception. - To verify the right exception is thrown, it is often useful to comment out the `expect` call when first running the test, for example: @@ -456,7 +468,7 @@ Tips: ```javascript it("fromDegrees throws with no latitude", function () { // expect(function() { - Cartesian3.fromDegrees(0.0); + Cartesian3.fromDegrees(0.0, undefined); // }).toThrowDeveloperError(); }); ``` diff --git a/packages/engine/Specs/Core/Cartesian3Spec.js b/packages/engine/Specs/Core/Cartesian3Spec.js index d2cae1feef9d..a0441473c06d 100644 --- a/packages/engine/Specs/Core/Cartesian3Spec.js +++ b/packages/engine/Specs/Core/Cartesian3Spec.js @@ -1241,14 +1241,16 @@ describe("Core/Cartesian3", function () { it("fromDegrees throws with no longitude", function () { expect(function () { - Cartesian3.fromDegrees(); - }).toThrowDeveloperError(); + Cartesian3.fromDegrees(undefined, undefined); + }).toThrowDeveloperError(/Expected longitude to be/); }); it("fromDegrees throws with no latitude", function () { expect(function () { - Cartesian3.fromDegrees(1); - }).toThrowDeveloperError(); + Cartesian3.fromDegrees(1, undefined); + }).toThrowDeveloperError( + "Expected latitude to be typeof number, actual typeof was undefined", + ); }); it("fromDegrees works works with default ellipsoid", function () { From 084d81d2025b8a5ae80a61ea87e232da5b091be7 Mon Sep 17 00:00:00 2001 From: ggetz Date: Wed, 11 Dec 2024 13:58:08 -0500 Subject: [PATCH 29/41] Fix memory usage for environment map manager --- .../Scene/DynamicEnvironmentMapManager.js | 82 ++++++++++--- .../engine/Specs/Scene/Cesium3DTilesetSpec.js | 2 + .../Scene/DynamicEnvironmentMapManagerSpec.js | 116 +++++++++--------- 3 files changed, 123 insertions(+), 77 deletions(-) diff --git a/packages/engine/Source/Scene/DynamicEnvironmentMapManager.js b/packages/engine/Source/Scene/DynamicEnvironmentMapManager.js index f3897e2ff0c3..458735893397 100644 --- a/packages/engine/Source/Scene/DynamicEnvironmentMapManager.js +++ b/packages/engine/Source/Scene/DynamicEnvironmentMapManager.js @@ -33,7 +33,7 @@ import ConvolveSpecularMapVS from "../Shaders/ConvolveSpecularMapVS.js"; * @typedef {object} DynamicEnvironmentMapManager.ConstructorOptions * Options for the DynamicEnvironmentMapManager constructor * @property {boolean} [enabled=true] If true, the environment map and related properties will continue to update. - * @property {number} [mipmapLevels=10] The number of mipmap levels to generate for specular maps. More mipmap levels will produce a higher resolution specular reflection. + * @property {number} [mipmapLevels=7] The number of mipmap levels to generate for specular maps. More mipmap levels will produce a higher resolution specular reflection. * @property {number} [maximumSecondsDifference=3600] The maximum amount of elapsed seconds before a new environment map is created. * @property {number} [maximumPositionEpsilon=1000] The maximum difference in position before a new environment map is created, in meters. Small differences in position will not visibly affect results. * @property {number} [atmosphereScatteringIntensity=2.0] The intensity of the scattered light emitted from the atmosphere. This should be adjusted relative to the value of {@link Scene.light} intensity. @@ -81,7 +81,7 @@ function DynamicEnvironmentMapManager(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const mipmapLevels = Math.min( - defaultValue(options.mipmapLevels, 10), + defaultValue(options.mipmapLevels, 7), Math.log2(ContextLimits.maximumCubeMapSize), ); @@ -354,6 +354,10 @@ DynamicEnvironmentMapManager._updateCommandQueue = (frameState) => { DynamicEnvironmentMapManager._activeComputeCommandCount++; command = DynamicEnvironmentMapManager._nextFrameCommandQueue.shift(); } + + if (defined(command)) { + DynamicEnvironmentMapManager._nextFrameCommandQueue.push(command); + } } }; @@ -539,7 +543,8 @@ function updateRadianceMap(manager, frameState) { let i = 0; for (const face of CubeMap.faceNames()) { let texture = manager._radianceMapTextures[i]; - if (defined(texture)) { + // Destroy any existing textures that have no yet been cleaned up + if (defined(texture) && !texture.isDestroyed()) { texture.destroy(); } @@ -570,7 +575,6 @@ function updateRadianceMap(manager, frameState) { ); }, }, - persists: true, owner: manager, postExecute: () => { const commands = manager._radianceMapComputeCommands; @@ -583,7 +587,6 @@ function updateRadianceMap(manager, frameState) { const framebuffer = new Framebuffer({ context: context, colorTextures: [manager._radianceMapTextures[index]], - destroyAttachments: false, }); // Copy the output texture into the corresponding cubemap face @@ -639,19 +642,34 @@ function updateSpecularMaps(manager, frameState) { facesCopied++; DynamicEnvironmentMapManager._activeComputeCommandCount--; - // All faces and levels have been copied - if (facesCopied === manager._specularMapTextures.length) { + texture.destroy(); + manager._specularMapTextures[index] = undefined; + + // All faces for each mipmap level have been copied + const length = manager._specularMapTextures.length; + if (facesCopied >= length) { manager._irradianceCommandDirty = true; radianceCubeMap.sampler = new Sampler({ minificationFilter: TextureMinificationFilter.LINEAR_MIPMAP_LINEAR, }); + manager._shouldRegenerateShaders = true; + + // Cleanup shared resources + manager._va.destroy(); + manager._va = undefined; + manager._convolveSP.destroy(); + manager._convolveSP = undefined; } }; let index = 0; for (let level = 1; level < mipmapLevels; ++level) { for (const face of CubeMap.faceNames()) { + if (defined(manager._specularMapTextures[index])) { + manager._specularMapTextures[index].destroy(); + } + const texture = (manager._specularMapTextures[index] = new Texture({ context: context, width: width, @@ -683,6 +701,8 @@ function updateSpecularMaps(manager, frameState) { shaderProgram: shaderProgram, vertexArray: vertexArray, outputTexture: texture, + // Persist so we can use a shared shader progam and vertex array across all commands + // Shared resources are instead destroyed in postExecute persists: true, owner: manager, uniformMap: { @@ -717,17 +737,19 @@ function updateIrradianceResources(manager, frameState) { const dimensions = irradianceTextureDimensions; let texture = manager._irradianceMapTexture; - if (!defined(texture)) { - texture = new Texture({ - context: context, - width: dimensions.x, - height: dimensions.y, - pixelDatatype: PixelDatatype.FLOAT, - pixelFormat: PixelFormat.RGBA, - }); - manager._irradianceMapTexture = texture; + if (defined(texture)) { + texture.destroy(); } + texture = new Texture({ + context: context, + width: dimensions.x, + height: dimensions.y, + pixelDatatype: PixelDatatype.FLOAT, + pixelFormat: PixelFormat.RGBA, + }); + manager._irradianceMapTexture = texture; + let fs = manager._irradianceMapFS; if (!defined(fs)) { fs = new ShaderSource({ @@ -750,6 +772,7 @@ function updateIrradianceResources(manager, frameState) { manager._irradianceTextureDirty = false; manager._irradianceComputeCommand = undefined; manager._sphericalHarmonicCoefficientsDirty = true; + manager._irradianceMapFS = undefined; DynamicEnvironmentMapManager._activeComputeCommandCount--; }, @@ -768,6 +791,11 @@ function updateIrradianceResources(manager, frameState) { function updateSphericalHarmonicCoefficients(manager, frameState) { const context = frameState.context; + if (!defined(manager._irradianceMapTexture)) { + // Operation was cancelled + return; + } + const framebuffer = new Framebuffer({ context: context, colorTextures: [manager._irradianceMapTexture], @@ -793,6 +821,8 @@ function updateSphericalHarmonicCoefficients(manager, frameState) { } framebuffer.destroy(); + manager._irradianceMapTexture.destroy(); + manager._irradianceMapTexture = undefined; manager._shouldRegenerateShaders = true; } @@ -910,19 +940,33 @@ DynamicEnvironmentMapManager.prototype.destroy = function () { length = this._radianceMapTextures.length; for (let i = 0; i < length; ++i) { this._radianceMapTextures[i] = - this._radianceMapTextures[i] && this._radianceMapTextures[i].destroy(); + this._radianceMapTextures[i] && + !this._radianceMapTextures[i].isDestroyed() && + this._radianceMapTextures[i].destroy(); } length = this._specularMapTextures.length; for (let i = 0; i < length; ++i) { this._specularMapTextures[i] = - this._specularMapTextures[i] && this._specularMapTextures[i].destroy(); + this._specularMapTextures[i] && + !this._specularMapTextures[i].isDestroyed() && + this._specularMapTextures[i].destroy(); } this._radianceCubeMap = this._radianceCubeMap && this._radianceCubeMap.destroy(); this._irradianceMapTexture = - this._irradianceMapTexture && this._irradianceMapTexture.destroy(); + this._irradianceMapTexture && + !this._irradianceMapTexture.isDestroyed() && + this._irradianceMapTexture.destroy(); + + if (defined(this._va)) { + this._va.destroy(); + } + + if (defined(this._convolveSP)) { + this._convolveSP.destroy(); + } return destroyObject(this); }; diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js index a05b1be4dc28..2ba0406a0db8 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js @@ -487,6 +487,8 @@ describe( }), ); expect(root.contentFailed).toBeTrue(); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); }); it("handles failed tile requests", async function () { diff --git a/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js b/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js index 0783774b7482..f00e7b67d02a 100644 --- a/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js +++ b/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js @@ -202,7 +202,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.13869766891002655, 0.17165547609329224, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -210,7 +210,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.11016352474689484, 0.15077166259288788, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -218,7 +218,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0013909616973251104, -0.00141593546140939, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -226,7 +226,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.00016706169117242098, 0.00006681153899990022, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); @@ -288,7 +288,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.03880387544631958, 0.050429586321115494, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -296,7 +296,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.00047372994595207274, 0.011921915225684643, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -304,7 +304,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0005534383235499263, -0.001172146643511951, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -312,22 +312,22 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.00010014028521254659, -0.0005452318582683802, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[4].y).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[4].z).toBeLessThan(0.0); - expect(manager.sphericalHarmonicCoefficients[5].x).toBeGreaterThan(0.0); - expect(manager.sphericalHarmonicCoefficients[5].y).toBeGreaterThan(0.0); - expect(manager.sphericalHarmonicCoefficients[5].z).toBeGreaterThan(0.0); + expect(manager.sphericalHarmonicCoefficients[5].x).toBeLessThan(0.0); + expect(manager.sphericalHarmonicCoefficients[5].y).toBeLessThan(0.0); + expect(manager.sphericalHarmonicCoefficients[5].z).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[6].x).toBeGreaterThan(0.0); expect(manager.sphericalHarmonicCoefficients[6].y).toBeGreaterThan(0.0); expect(manager.sphericalHarmonicCoefficients[6].z).toBeGreaterThan(0.0); - expect(manager.sphericalHarmonicCoefficients[7].x).toBeGreaterThan(0.0); + expect(manager.sphericalHarmonicCoefficients[7].x).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[7].y).toBeGreaterThan(0.0); expect(manager.sphericalHarmonicCoefficients[7].z).toBeGreaterThan(0.0); @@ -374,7 +374,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.3365404009819031, 0.3376566469669342, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -382,7 +382,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.25208908319473267, 0.25084879994392395, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -390,7 +390,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.0009837104007601738, 0.0008832928724586964, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( @@ -399,7 +399,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0015308377332985401, -0.0012394117657095194, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeGreaterThan(0.0); @@ -460,7 +460,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.04265068098902702, 0.04163559526205063, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -468,7 +468,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.023243442177772522, 0.025639381259679794, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -476,7 +476,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0033528741914778948, -0.0031588575802743435, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -484,7 +484,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.007121194154024124, 0.005899451207369566, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeGreaterThan(0.0); @@ -545,7 +545,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.0054358793422579765, 0.0027179396711289883, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -553,7 +553,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.0037772462237626314, 0.0018886231118813157, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -561,7 +561,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.000007333524990826845, -0.0000036667624954134226, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -569,7 +569,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.000008501945558236912, 0.000004250972779118456, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); @@ -633,7 +633,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.04545757919549942, 0.02313476987183094, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -641,7 +641,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.004114487674087286, -0.0017214358085766435, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -649,7 +649,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0008244783966802061, -0.00026270488160662353, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -657,16 +657,16 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.000012375472579151392, 0.0005265426589176059, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[4].y).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[4].z).toBeLessThan(0.0); - expect(manager.sphericalHarmonicCoefficients[5].x).toBeGreaterThan(0.0); - expect(manager.sphericalHarmonicCoefficients[5].y).toBeGreaterThan(0.0); - expect(manager.sphericalHarmonicCoefficients[5].z).toBeGreaterThan(0.0); + expect(manager.sphericalHarmonicCoefficients[5].x).toBeLessThan(0.0); + expect(manager.sphericalHarmonicCoefficients[5].y).toBeLessThan(0.0); + expect(manager.sphericalHarmonicCoefficients[5].z).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[6].x).toBeGreaterThan(0.0); expect(manager.sphericalHarmonicCoefficients[6].y).toBeGreaterThan(0.0); @@ -715,7 +715,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.039464931935071945, 0.047749463468790054, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -723,7 +723,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.031872138381004333, 0.04223670810461044, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -731,7 +731,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0008044499554671347, -0.0008345510577782989, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -739,7 +739,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.000017321406630799174, -0.000006108442903496325, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); @@ -798,7 +798,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.21367456018924713, 0.23666927218437195, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -806,7 +806,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.15787045657634735, 0.19085952639579773, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -814,7 +814,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0010327763156965375, -0.001100384397432208, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -822,7 +822,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.00028964842204004526, 0.00021805899450555444, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); @@ -881,7 +881,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.07419705390930176, 0.09077795594930649, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -889,7 +889,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.06336799263954163, 0.08409948647022247, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -897,7 +897,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0006284310948103666, -0.000669674074742943, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -905,7 +905,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.000024254957679659128, 0.00004792874096892774, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); @@ -964,7 +964,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.13499368727207184, 0.13499368727207184, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -972,7 +972,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.1081928238272667, 0.1081928238272667, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -980,7 +980,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0013909616973251104, -0.00141593546140939, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -988,7 +988,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.00016706169117242098, 0.00006681153899990022, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); @@ -1047,7 +1047,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.11958353966474533, 0.15991388261318207, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -1055,7 +1055,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.11915278434753418, 0.15629366040229797, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -1063,7 +1063,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.0016134318429976702, -0.0015525781782343984, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -1071,16 +1071,16 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.000019326049368828535, -0.000023931264877319336, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); - expect(manager.sphericalHarmonicCoefficients[4].y).toBeGreaterThan(0.0); + expect(manager.sphericalHarmonicCoefficients[4].y).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[4].z).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[5].x).toBeGreaterThan(0.0); - expect(manager.sphericalHarmonicCoefficients[5].y).toBeLessThan(0.0); - expect(manager.sphericalHarmonicCoefficients[5].z).toBeLessThan(0.0); + expect(manager.sphericalHarmonicCoefficients[5].y).toBeGreaterThan(0.0); + expect(manager.sphericalHarmonicCoefficients[5].z).toBeGreaterThan(0.0); expect(manager.sphericalHarmonicCoefficients[6].x).toBeLessThan(0.0); expect(manager.sphericalHarmonicCoefficients[6].y).toBeLessThan(0.0); @@ -1130,7 +1130,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.1812949925661087, 0.19759616255760193, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[1]).toEqualEpsilon( new Cartesian3( @@ -1138,7 +1138,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.09013032913208008, 0.13857196271419525, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[2]).toEqualEpsilon( new Cartesian3( @@ -1146,7 +1146,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { -0.000895244418643415, -0.0011140345595777035, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[3]).toEqualEpsilon( new Cartesian3( @@ -1154,7 +1154,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { 0.0004962628008797765, 0.0002673182752914727, ), - CesiumMath.EPSILON4, + CesiumMath.EPSILON2, ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); From 2464be8521dfe28d4074a3b2896f07e37d1a1a58 Mon Sep 17 00:00:00 2001 From: ggetz Date: Fri, 13 Dec 2024 14:15:02 -0500 Subject: [PATCH 30/41] Better handled resources of canceled commands --- .../Scene/DynamicEnvironmentMapManager.js | 113 ++++++++++-------- 1 file changed, 63 insertions(+), 50 deletions(-) diff --git a/packages/engine/Source/Scene/DynamicEnvironmentMapManager.js b/packages/engine/Source/Scene/DynamicEnvironmentMapManager.js index 458735893397..1469d31fe1a8 100644 --- a/packages/engine/Source/Scene/DynamicEnvironmentMapManager.js +++ b/packages/engine/Source/Scene/DynamicEnvironmentMapManager.js @@ -77,6 +77,7 @@ function DynamicEnvironmentMapManager(options) { this._sphericalHarmonicCoefficientsDirty = false; this._shouldRegenerateShaders = false; + this._shouldReset = false; options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -251,7 +252,7 @@ Object.defineProperties(DynamicEnvironmentMapManager.prototype, { } this._position = Cartesian3.clone(value, this._position); - this.reset(); + this._shouldReset = true; }, }, @@ -345,7 +346,7 @@ DynamicEnvironmentMapManager._updateCommandQueue = (frameState) => { DynamicEnvironmentMapManager._activeComputeCommandCount < DynamicEnvironmentMapManager._maximumComputeCommandCount ) { - if (command.canceled) { + if (command.owner.isDestroyed() || command.canceled) { command = DynamicEnvironmentMapManager._nextFrameCommandQueue.shift(); continue; } @@ -402,7 +403,6 @@ DynamicEnvironmentMapManager.prototype.reset = function () { for (let i = 0; i < length; ++i) { if (defined(this._radianceMapComputeCommands[i])) { this._radianceMapComputeCommands[i].canceled = true; - DynamicEnvironmentMapManager._activeComputeCommandCount--; } this._radianceMapComputeCommands[i] = undefined; } @@ -411,19 +411,19 @@ DynamicEnvironmentMapManager.prototype.reset = function () { for (let i = 0; i < length; ++i) { if (defined(this._convolutionComputeCommands[i])) { this._convolutionComputeCommands[i].canceled = true; - DynamicEnvironmentMapManager._activeComputeCommandCount--; } this._convolutionComputeCommands[i] = undefined; } if (defined(this._irradianceComputeCommand)) { this._irradianceComputeCommand.canceled = true; - DynamicEnvironmentMapManager._activeComputeCommandCount--; this._irradianceComputeCommand = undefined; } this._radianceMapDirty = true; this._radianceCommandsDirty = true; + this._convolutionsCommandsDirty = false; + this._irradianceCommandDirty = false; }; const scratchPackedAtmosphere = new Cartesian3(); @@ -576,33 +576,34 @@ function updateRadianceMap(manager, frameState) { }, }, owner: manager, - postExecute: () => { - const commands = manager._radianceMapComputeCommands; - if (!defined(commands[index])) { - // This command was cancelled - return; - } - commands[index] = undefined; - - const framebuffer = new Framebuffer({ - context: context, - colorTextures: [manager._radianceMapTextures[index]], - }); - - // Copy the output texture into the corresponding cubemap face - framebuffer._bind(); - manager._radianceCubeMap[face].copyFromFramebuffer(); - framebuffer._unBind(); - framebuffer.destroy(); - + }); + command.postExecute = () => { + if (manager.isDestroyed() || command.canceled) { DynamicEnvironmentMapManager._activeComputeCommandCount--; + return; + } - if (!commands.some(defined)) { - manager._convolutionsCommandsDirty = true; - manager._shouldRegenerateShaders = true; - } - }, - }); + const commands = manager._radianceMapComputeCommands; + commands[index] = undefined; + + const framebuffer = new Framebuffer({ + context: context, + colorTextures: [manager._radianceMapTextures[index]], + }); + + // Copy the output texture into the corresponding cubemap face + framebuffer._bind(); + manager._radianceCubeMap[face].copyFromFramebuffer(); + framebuffer._unBind(); + framebuffer.destroy(); + + DynamicEnvironmentMapManager._activeComputeCommandCount--; + + if (!commands.some(defined)) { + manager._convolutionsCommandsDirty = true; + manager._shouldRegenerateShaders = true; + } + }; manager._radianceMapComputeCommands[i] = command; DynamicEnvironmentMapManager._queueCommand(command, frameState); @@ -629,13 +630,14 @@ function updateSpecularMaps(manager, frameState) { const context = frameState.context; let facesCopied = 0; - const getPostExecute = (index, texture, face, level) => () => { - // Copy output texture to corresponding face and mipmap level - const commands = manager._convolutionComputeCommands; - if (!defined(commands[index]) || commands[index].canceled) { - // This command was cancelled + const getPostExecute = (command, index, texture, face, level) => () => { + if (manager.isDestroyed() || command.canceled) { + DynamicEnvironmentMapManager._activeComputeCommandCount--; return; } + + // Copy output texture to corresponding face and mipmap level + const commands = manager._convolutionComputeCommands; commands[index] = undefined; radianceCubeMap.copyFace(frameState, texture, face, level); @@ -712,8 +714,14 @@ function updateSpecularMaps(manager, frameState) { return CubeMap.getDirection(face, scratchCartesian); }, }, - postExecute: getPostExecute(index, texture, face, level), }); + command.postExecute = getPostExecute( + command, + index, + texture, + face, + level, + ); manager._convolutionComputeCommands[index] = command; DynamicEnvironmentMapManager._queueCommand(command, frameState); ++index; @@ -737,7 +745,7 @@ function updateIrradianceResources(manager, frameState) { const dimensions = irradianceTextureDimensions; let texture = manager._irradianceMapTexture; - if (defined(texture)) { + if (defined(texture) && !texture.isDestroyed()) { texture.destroy(); } @@ -761,22 +769,25 @@ function updateIrradianceResources(manager, frameState) { const command = new ComputeCommand({ fragmentShaderSource: fs, outputTexture: texture, + owner: manager, uniformMap: { u_radianceMap: () => manager._radianceCubeMap ?? context.defaultTexture, }, - postExecute: () => { - if (!defined(manager._irradianceComputeCommand)) { - // This command was cancelled - return; - } - manager._irradianceTextureDirty = false; - manager._irradianceComputeCommand = undefined; - manager._sphericalHarmonicCoefficientsDirty = true; - manager._irradianceMapFS = undefined; + }); + command.postExecute = () => { + if (manager.isDestroyed() || command.canceled) { DynamicEnvironmentMapManager._activeComputeCommandCount--; - }, - }); + return; + } + manager._irradianceTextureDirty = false; + manager._irradianceComputeCommand = undefined; + manager._sphericalHarmonicCoefficientsDirty = true; + manager._irradianceMapFS = undefined; + + DynamicEnvironmentMapManager._activeComputeCommandCount--; + }; + manager._irradianceComputeCommand = command; DynamicEnvironmentMapManager._queueCommand(command, frameState); manager._irradianceTextureDirty = true; @@ -792,7 +803,7 @@ function updateSphericalHarmonicCoefficients(manager, frameState) { const context = frameState.context; if (!defined(manager._irradianceMapTexture)) { - // Operation was cancelled + // Operation was canceled return; } @@ -864,9 +875,11 @@ DynamicEnvironmentMapManager.prototype.update = function (frameState) { this.maximumSecondsDifference, )); - if (regenerateEnvironmentMap) { + if (this._shouldReset || regenerateEnvironmentMap) { this.reset(); + this._shouldReset = false; this._lastTime = JulianDate.clone(frameState.time, this._lastTime); + return; } if (this._radianceMapDirty) { From 546e7a65c4a35ad90f7946bf26b72adb509881ba Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Thu, 19 Dec 2024 22:36:13 -0500 Subject: [PATCH 31/41] Fix precision issue in DepthPlaneVS --- CHANGES.md | 1 + packages/engine/Source/Shaders/DepthPlaneVS.glsl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f430332fe688..a265c33000f6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ ##### Fixes :wrench: - Fixed JulianDate to always generate valid ISO strings for fractional milliseconds [#12345](https://github.com/CesiumGS/cesium/pull/12345) +- Fixed intermittent z-fighting issue. [#12337](https://github.com/CesiumGS/cesium/issues/12337) ### 1.124 - 2024-12-02 diff --git a/packages/engine/Source/Shaders/DepthPlaneVS.glsl b/packages/engine/Source/Shaders/DepthPlaneVS.glsl index b5204ec2f53d..4141585366a6 100644 --- a/packages/engine/Source/Shaders/DepthPlaneVS.glsl +++ b/packages/engine/Source/Shaders/DepthPlaneVS.glsl @@ -5,7 +5,7 @@ out vec4 positionEC; void main() { positionEC = czm_modelView * position; - gl_Position = czm_modelViewProjection * position; + gl_Position = czm_projection * positionEC; czm_vertexLogDepth(); } From e6be1fec0f1118654d426d64003b57612b4a6eae Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 2 Jan 2025 11:40:36 -0500 Subject: [PATCH 32/41] Update release schedule for 2025 --- .slackbot.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/.slackbot.yml b/.slackbot.yml index e2cfc9e9c6ac..da3aaa3f1f9b 100644 --- a/.slackbot.yml +++ b/.slackbot.yml @@ -1,11 +1,13 @@ releaseSchedule: - - jjspace, 4/1/2024 - - ggetz, 5/1/2024 - - jjhembd, 6/1/2024 - - ggetz, 7/1/2024 - - jjhembd, 8/1/2024 - - jjspace, 9/1/2024 - - ggetz, 10/1/2024 - - lukemckinstry, 11/1/2024 - - jjspace, 12/1/2024 - + - ggetz, 1/2/2025 + - jjhembd, 2/3/2025 + - lukemckinstry, 3/3/2025 + - jjspace, 4/1/2025 + - ggetz, 5/1/2025 + - jjhembd, 6/2/2025 + - lukemckinstry, 7/1/2025 + - jjspace, 8/1/2025 + - ggetz, 9/1/2025 + - jjhembd, 10/1/2025 + - lukemckinstry, 11/3/2025 + - jjspace, 12/1/2025 From 74b40ed8f394085eed6fef003b808b0114c7b840 Mon Sep 17 00:00:00 2001 From: ggetz Date: Thu, 2 Jan 2025 12:51:08 -0500 Subject: [PATCH 33/41] Moved entity environmentMapOptions to ModelGraphics and adjusted default --- CHANGES.md | 2 +- .../DataSources/Cesium3DTilesetVisualizer.js | 4 +- packages/engine/Source/DataSources/Entity.js | 4 -- .../Source/DataSources/ModelGraphics.js | 24 ++++++++++- .../Source/DataSources/ModelVisualizer.js | 24 ++++++++++- .../Cesium3DTilesetVisualizerSpec.js | 1 - .../Specs/DataSources/ModelVisualizerSpec.js | 42 ++++++++++++++++++- 7 files changed, 88 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e26829340773..d5977e7bec13 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ ##### Fixes :wrench: -- Added `environmentMapOptions` to `Entity`'s constructor options with EnvironmentMap disabled by default to allow long distance `Entity` jumps without performance drop. If EnvironmentMap needs to be enabled, ensure to provide a `maximumPositionEpsilon` threshold value large enough with your entity movements use case. [#12358](https://github.com/CesiumGS/cesium/pull/12358) +- Added `environmentMapOptions` to `ModelGraphics`. For performance reasons, the environment map will not update if the entity position changes by default. If environment map updates based on entity position are desired, ensure to provide an appropriate `environmentMapOptions.maximumPositionEpsilon` value. [#12358](https://github.com/CesiumGS/cesium/pull/12358) - Fixed JulianDate to always generate valid ISO strings for fractional milliseconds [#12345](https://github.com/CesiumGS/cesium/pull/12345) - Fixed intermittent z-fighting issue. [#12337](https://github.com/CesiumGS/cesium/issues/12337) diff --git a/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js b/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js index 7317cd97d59b..314edf37e1c1 100644 --- a/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js +++ b/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js @@ -243,9 +243,7 @@ async function createTileset(resource, tilesetHash, entity, primitives) { }; try { - const tileset = await Cesium3DTileset.fromUrl(resource, { - environmentMapOptions: entity._environmentMapOptions, - }); + const tileset = await Cesium3DTileset.fromUrl(resource); tileset.id = entity; primitives.add(tileset); diff --git a/packages/engine/Source/DataSources/Entity.js b/packages/engine/Source/DataSources/Entity.js index 2d308b022a1e..d8c9fab17f9e 100644 --- a/packages/engine/Source/DataSources/Entity.js +++ b/packages/engine/Source/DataSources/Entity.js @@ -98,7 +98,6 @@ function createPropertyTypeDescriptor(name, Type) { * @property {PolylineVolumeGraphics | PolylineVolumeGraphics.ConstructorOptions} [polylineVolume] A polylineVolume to associate with this entity. * @property {RectangleGraphics | RectangleGraphics.ConstructorOptions} [rectangle] A rectangle to associate with this entity. * @property {WallGraphics | WallGraphics.ConstructorOptions} [wall] A wall to associate with this entity. - * @property {DynamicEnvironmentMapManager.ConstructorOptions} [environmentMapOptions={enabled: false}] The properties for managing dynamic environment maps on this entity. */ /** @@ -123,9 +122,6 @@ function Entity(options) { this._availability = undefined; this._id = id; this._definitionChanged = new Event(); - this._environmentMapOptions = defaultValue(options.environmentMapOptions, { - enabled: false, - }); this._name = options.name; this._show = defaultValue(options.show, true); this._trackingReferenceFrame = defaultValue( diff --git a/packages/engine/Source/DataSources/ModelGraphics.js b/packages/engine/Source/DataSources/ModelGraphics.js index 8320768fa319..10c5d8718c91 100644 --- a/packages/engine/Source/DataSources/ModelGraphics.js +++ b/packages/engine/Source/DataSources/ModelGraphics.js @@ -18,6 +18,10 @@ function createArticulationStagePropertyBag(value) { return new PropertyBag(value); } +function createEnvironmentMapPropertyBag(value) { + return new PropertyBag(value); +} + /** * @typedef {object} ModelGraphics.ConstructorOptions * @@ -40,6 +44,7 @@ function createArticulationStagePropertyBag(value) { * @property {Property | ColorBlendMode} [colorBlendMode=ColorBlendMode.HIGHLIGHT] An enum Property specifying how the color blends with the model. * @property {Property | number} [colorBlendAmount=0.5] A numeric Property specifying the color strength when the colorBlendMode is MIX. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. * @property {Property | Cartesian2} [imageBasedLightingFactor=new Cartesian2(1.0, 1.0)] A property specifying the contribution from diffuse and specular image-based lighting. + * @property {PropertyBag | Object} [environmentMapOptions] The properties for managing dynamic environment maps on this entity. * @property {Property | Color} [lightColor] A property specifying the light color when shading the model. When undefined the scene's light color is used instead. * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this model will be displayed. * @property {PropertyBag | Object} [nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. The transformation is applied after the node's existing transformation as specified in the glTF, and does not replace the node's existing transformation. @@ -101,6 +106,8 @@ function ModelGraphics(options) { this._colorBlendAmountSubscription = undefined; this._imageBasedLightingFactor = undefined; this._imageBasedLightingFactorSubscription = undefined; + this._environmentMapOptions = undefined; + this._environmentMapOptionsSubscription = undefined; this._lightColor = undefined; this._lightColorSubscription = undefined; this._distanceDisplayCondition = undefined; @@ -279,6 +286,17 @@ Object.defineProperties(ModelGraphics.prototype, { "imageBasedLightingFactor", ), + /** + * Gets or sets the {@link DynamicEnvironmentMapManager.ConstructorOptions} to apply to this model. This is represented as an {@link PropertyBag}. + * @memberof ModelGraphics.prototype + * @type {PropertyBag} + */ + environmentMapOptions: createPropertyDescriptor( + "environmentMapOptions", + undefined, + createEnvironmentMapPropertyBag, + ), + /** * A property specifying the {@link Cartesian3} light color when shading the model. When undefined the scene's light color is used instead. * @memberOf ModelGraphics.prototype @@ -361,6 +379,7 @@ ModelGraphics.prototype.clone = function (result) { result.colorBlendMode = this.colorBlendMode; result.colorBlendAmount = this.colorBlendAmount; result.imageBasedLightingFactor = this.imageBasedLightingFactor; + result.environmentMapOptions = this.environmentMapOptions; result.lightColor = this.lightColor; result.distanceDisplayCondition = this.distanceDisplayCondition; result.nodeTransformations = this.nodeTransformations; @@ -430,7 +449,10 @@ ModelGraphics.prototype.merge = function (source) { this.imageBasedLightingFactor, source.imageBasedLightingFactor, ); - + this.environmentMapOptions = defaultValue( + this.environmentMapOptions, + source.environmentMapOptions, + ); this.lightColor = defaultValue(this.lightColor, source.lightColor); this.distanceDisplayCondition = defaultValue( this.distanceDisplayCondition, diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index 1de790ac24f4..0b8f5a54938b 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -35,6 +35,9 @@ const defaultColor = Color.WHITE; const defaultColorBlendMode = ColorBlendMode.HIGHLIGHT; const defaultColorBlendAmount = 0.5; const defaultImageBasedLightingFactor = new Cartesian2(1.0, 1.0); +const defaultEnvironmentMapOptions = { + maximumPositionEpsilon: Number.POSITIVE_INFINITY, +}; const modelMatrixScratch = new Matrix4(); const nodeMatrixScratch = new Matrix4(); @@ -76,6 +79,7 @@ async function createModelPrimitive( entity, resource, incrementallyLoadTextures, + environmentMapOptions, ) { const primitives = visualizer._primitives; const modelHash = visualizer._modelHash; @@ -85,7 +89,7 @@ async function createModelPrimitive( url: resource, incrementallyLoadTextures: incrementallyLoadTextures, scene: visualizer._scene, - environmentMapOptions: entity._environmentMapOptions, + environmentMapOptions: environmentMapOptions, }); if (visualizer.isDestroyed() || !defined(modelHash[entity.id])) { @@ -177,6 +181,9 @@ ModelVisualizer.prototype.update = function (time) { articulationsScratch: {}, loadFailed: false, modelUpdated: false, + environmentMapOptionsScratch: { + ...defaultEnvironmentMapOptions, + }, }; modelHash[entity.id] = modelData; @@ -186,7 +193,20 @@ ModelVisualizer.prototype.update = function (time) { defaultIncrementallyLoadTextures, ); - createModelPrimitive(this, entity, resource, incrementallyLoadTextures); + const environmentMapOptions = Property.getValueOrDefault( + modelGraphics._environmentMapOptions, + time, + defaultEnvironmentMapOptions, + modelData.environmentMapOptionsScratch, + ); + + createModelPrimitive( + this, + entity, + resource, + incrementallyLoadTextures, + environmentMapOptions, + ); } const model = modelData.modelPrimitive; diff --git a/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js b/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js index 09e85ef0be3c..0c9ef09da4fe 100644 --- a/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js @@ -133,7 +133,6 @@ describe( visualizer.update(time); expect(primitive.show).toEqual(true); expect(primitive.maximumScreenSpaceError).toEqual(24.0); - expect(primitive.environmentMapManager.enabled).toEqual(false); }); it("A Cesium3DTilesetGraphics with a Resource causes a primitive to be created.", async function () { diff --git a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js index 92b90d66320e..862380d7c28b 100644 --- a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js @@ -196,7 +196,10 @@ describe( expect(primitive.lightColor).toEqual(new Cartesian3(1.0, 1.0, 0.0)); - expect(primitive.environmentMapManager.enabled).toEqual(false); + expect(primitive.environmentMapManager.enabled).toBeTrue(); + expect(primitive.environmentMapManager.maximumPositionEpsilon).toEqual( + Number.POSITIVE_INFINITY, + ); // wait till the model is loaded before we can check node transformations await pollToPromise(function () { @@ -278,6 +281,43 @@ describe( expect(node.matrix).toEqualEpsilon(expected, CesiumMath.EPSILON14); }); + it("can apply model environmentMapOptions", async function () { + const time = JulianDate.now(); + + const model = new ModelGraphics(); + model.uri = new ConstantProperty(boxArticulationsUrl); + + model.environmentMapOptions = { + enabled: false, + }; + + const testObject = entityCollection.getOrCreateEntity("test"); + testObject.position = new ConstantPositionProperty( + Cartesian3.fromDegrees(1, 2, 3), + ); + testObject.model = model; + + visualizer.update(time); + + let primitive; + await pollToPromise(function () { + primitive = scene.primitives.get(0); + return defined(primitive); + }); + + // wait till the model is loaded before we can check articulations + await pollToPromise(function () { + scene.render(); + return primitive.ready; + }); + visualizer.update(time); + + expect(primitive.environmentMapManager.enabled).toBeFalse(); + expect(primitive.environmentMapManager.maximumPositionEpsilon).toEqual( + Number.POSITIVE_INFINITY, + ); + }); + it("creates a primitive from ModelGraphics with a Resource", async function () { const time = JulianDate.now(); From beba3d93061f4e07ee534a762256eac386beb442 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:55:14 -0500 Subject: [PATCH 34/41] rename release schedule --- .slackbot.yml | 13 ------------- ReleaseSchedule.md | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 13 deletions(-) delete mode 100644 .slackbot.yml create mode 100644 ReleaseSchedule.md diff --git a/.slackbot.yml b/.slackbot.yml deleted file mode 100644 index da3aaa3f1f9b..000000000000 --- a/.slackbot.yml +++ /dev/null @@ -1,13 +0,0 @@ -releaseSchedule: - - ggetz, 1/2/2025 - - jjhembd, 2/3/2025 - - lukemckinstry, 3/3/2025 - - jjspace, 4/1/2025 - - ggetz, 5/1/2025 - - jjhembd, 6/2/2025 - - lukemckinstry, 7/1/2025 - - jjspace, 8/1/2025 - - ggetz, 9/1/2025 - - jjhembd, 10/1/2025 - - lukemckinstry, 11/3/2025 - - jjspace, 12/1/2025 diff --git a/ReleaseSchedule.md b/ReleaseSchedule.md new file mode 100644 index 000000000000..bace0bb1cc28 --- /dev/null +++ b/ReleaseSchedule.md @@ -0,0 +1,14 @@ +# Release Schedule + +- ggetz, 1/2/2025 +- jjhembd, 2/3/2025 +- lukemckinstry, 3/3/2025 +- jjspace, 4/1/2025 +- ggetz, 5/1/2025 +- jjhembd, 6/2/2025 +- lukemckinstry, 7/1/2025 +- jjspace, 8/1/2025 +- ggetz, 9/1/2025 +- jjhembd, 10/1/2025 +- lukemckinstry, 11/3/2025 +- jjspace, 12/1/2025 From 4430b9010f9430d720878011313f41e10de1c0a0 Mon Sep 17 00:00:00 2001 From: ggetz Date: Thu, 2 Jan 2025 13:22:49 -0500 Subject: [PATCH 35/41] Fix environment map tests --- .../Specs/Scene/DynamicEnvironmentMapManagerSpec.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js b/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js index f00e7b67d02a..7d8d9661efb7 100644 --- a/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js +++ b/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js @@ -183,6 +183,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -269,6 +270,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -355,6 +357,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -442,6 +445,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { DynamicAtmosphereLightingType.SUNLIGHT; scene.renderForSpecs(time); + scene.renderForSpecs(time); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -527,6 +531,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { DynamicAtmosphereLightingType.SUNLIGHT; scene.renderForSpecs(time); + scene.renderForSpecs(time); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -614,6 +619,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -696,6 +702,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -779,6 +786,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -862,6 +870,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -945,6 +954,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -1028,6 +1038,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); @@ -1111,6 +1122,7 @@ describe("Scene/DynamicEnvironmentMapManager", function () { const primitive = new EnvironmentMockPrimitive(manager); scene.primitives.add(primitive); + scene.renderForSpecs(); scene.renderForSpecs(); expect(manager.radianceCubeMap).toBeInstanceOf(CubeMap); From 6707383bcbf1a72a3056fa7ecb349f5288e9dd10 Mon Sep 17 00:00:00 2001 From: ggetz Date: Thu, 2 Jan 2025 13:55:43 -0500 Subject: [PATCH 36/41] Update CHANGES.md --- CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index a265c33000f6..bea7756ea92c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,7 +4,8 @@ ##### Fixes :wrench: -- Fixed JulianDate to always generate valid ISO strings for fractional milliseconds [#12345](https://github.com/CesiumGS/cesium/pull/12345) +- Reduced memory usage and peformance bottlenecks when using environment maps with models. [#12356](https://github.com/CesiumGS/cesium/issues/12356) +- Fixed JulianDate to always generate valid ISO strings for fractional milliseconds. [#12345](https://github.com/CesiumGS/cesium/pull/12345) - Fixed intermittent z-fighting issue. [#12337](https://github.com/CesiumGS/cesium/issues/12337) ### 1.124 - 2024-12-02 From d23196489f3e135f3b85468312ca0377224880eb Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:02:48 -0500 Subject: [PATCH 37/41] update changes --- CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index a265c33000f6..4715f9e5523e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ ##### Fixes :wrench: +- Expanded the integration with the [iTwin Platform](https://developer.bentley.com/) to load GeoJSON and KML data from the Reality Management API. Use `ITwinData.createDataSourceForRealityDataId(iTwinId, realityDataId)` to load data as the corresponding Data Source. [#12344](https://github.com/CesiumGS/cesium/pull/12344) - Fixed JulianDate to always generate valid ISO strings for fractional milliseconds [#12345](https://github.com/CesiumGS/cesium/pull/12345) - Fixed intermittent z-fighting issue. [#12337](https://github.com/CesiumGS/cesium/issues/12337) @@ -14,7 +15,7 @@ ##### Additions :tada: - Added an integration with the [iTwin Platform](https://developer.bentley.com/) to load iModels as 3D Tiles. Use `ITwinPlatform.defaultAccessToken` to set the access token. Use `ITwinData.createTilesetFromIModelId(iModelId)` to load the iModel as a `Cesium3DTileset`. [#12289](https://github.com/CesiumGS/cesium/pull/12289) -- Added an integration with the [iTwin Platform](https://developer.bentley.com/) to load Reality Data terrain meshes and GeoJSON. Use `ITwinPlatform.defaultAccessToken` to set the access token. Then use `ITwinData.createTilesetForRealityDataId(iTwinId, dataId)` to load terrain meshes as a `Cesium3DTileset` or `ITwinData.createDataSourceForRealityDataId(iTwinId, dataId)` to load GeoJSON or KML files as data sources. [#12344](https://github.com/CesiumGS/cesium/pull/12344) +- Added an integration with the [iTwin Platform](https://developer.bentley.com/) to load Reality Data terrain meshes. Use `ITwinPlatform.defaultAccessToken` to set the access token. Then use `ITwinData.createTilesetForRealityDataId(iTwinId, dataId)` to load terrain meshes as a `Cesium3DTileset` [#12334](https://github.com/CesiumGS/cesium/pull/12334) - Added `getSample` to `SampledProperty` to get the time of samples. [#12253](https://github.com/CesiumGS/cesium/pull/12253) - Added `Entity.trackingReferenceFrame` property to allow tracking entities in various reference frames. [#12194](https://github.com/CesiumGS/cesium/pull/12194), [#12314](https://github.com/CesiumGS/cesium/pull/12314) - `TrackingReferenceFrame.AUTODETECT` (default): uses either VVLH or ENU depending on entity's dynamic. Use `TrackingReferenceFrame.ENU` if your camera orientation flips abruptly from time to time. From 2552dde728984d472451915a70c8b9c29298c747 Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:19:42 -0500 Subject: [PATCH 38/41] relocate release schedule --- .../Contributors/ReleaseGuide/README.md | 2 +- .../Contributors/ReleaseGuide/ReleaseSchedule.md | 16 ++++++++++++++++ ReleaseSchedule.md | 14 -------------- 3 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 Documentation/Contributors/ReleaseGuide/ReleaseSchedule.md delete mode 100644 ReleaseSchedule.md diff --git a/Documentation/Contributors/ReleaseGuide/README.md b/Documentation/Contributors/ReleaseGuide/README.md index e8733d379fbc..14ccad454d73 100644 --- a/Documentation/Contributors/ReleaseGuide/README.md +++ b/Documentation/Contributors/ReleaseGuide/README.md @@ -1,6 +1,6 @@ # Release Guide -We release Cesium on the first work day of every month. [This file](../../../.slackbot.yml) outlines the release schedule and the developer responsible for each month's release. +We release Cesium on the first work day of every month. The [Release Schedule](./ReleaseSchedule.md) outlines the release schedule and the developer responsible for each month's release. There is no release manager; instead, our community shares the responsibility. Any committer can create the release for a given month, and at any point, they can pass the responsibility to someone else, or someone else can ask for it. This spreads knowledge, avoids stratification, avoids a single point of failure, and is beautifully unstructured ([more info](https://community.cesium.com/t/cesium-releases/45)). diff --git a/Documentation/Contributors/ReleaseGuide/ReleaseSchedule.md b/Documentation/Contributors/ReleaseGuide/ReleaseSchedule.md new file mode 100644 index 000000000000..75b8eef22a92 --- /dev/null +++ b/Documentation/Contributors/ReleaseGuide/ReleaseSchedule.md @@ -0,0 +1,16 @@ +# Release Schedule + +| Date | User | +| --------- | ---------------- | +| 1/2/2025 | `@ggetz` | +| 2/3/2025 | `@jjhembd` | +| 3/3/2025 | `@lukemckinstry` | +| 4/1/2025 | `@jjspace` | +| 5/1/2025 | `@ggetz` | +| 6/2/2025 | `@jjhembd` | +| 7/1/2025 | `@lukemckinstry` | +| 8/1/2025 | `@jjspace` | +| 9/1/2025 | `@ggetz` | +| 10/1/2025 | `@jjhembd` | +| 11/3/2025 | `@lukemckinstry` | +| 12/1/2025 | `@jjspace` | diff --git a/ReleaseSchedule.md b/ReleaseSchedule.md deleted file mode 100644 index bace0bb1cc28..000000000000 --- a/ReleaseSchedule.md +++ /dev/null @@ -1,14 +0,0 @@ -# Release Schedule - -- ggetz, 1/2/2025 -- jjhembd, 2/3/2025 -- lukemckinstry, 3/3/2025 -- jjspace, 4/1/2025 -- ggetz, 5/1/2025 -- jjhembd, 6/2/2025 -- lukemckinstry, 7/1/2025 -- jjspace, 8/1/2025 -- ggetz, 9/1/2025 -- jjhembd, 10/1/2025 -- lukemckinstry, 11/3/2025 -- jjspace, 12/1/2025 From 080fd9cdc4463ea33ca78c1ca77f47d3757b1a7c Mon Sep 17 00:00:00 2001 From: ggetz Date: Thu, 2 Jan 2025 14:22:44 -0500 Subject: [PATCH 39/41] Make test less strict --- .../Specs/Scene/DynamicEnvironmentMapManagerSpec.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js b/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js index 7d8d9661efb7..4e4f3d5ef0e0 100644 --- a/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js +++ b/packages/engine/Specs/Scene/DynamicEnvironmentMapManagerSpec.js @@ -1086,8 +1086,14 @@ describe("Scene/DynamicEnvironmentMapManager", function () { ); expect(manager.sphericalHarmonicCoefficients[4].x).toBeLessThan(0.0); - expect(manager.sphericalHarmonicCoefficients[4].y).toBeLessThan(0.0); - expect(manager.sphericalHarmonicCoefficients[4].z).toBeLessThan(0.0); + expect(manager.sphericalHarmonicCoefficients[4].y).toEqualEpsilon( + 0.0, + CesiumMath.EPSILON2, + ); + expect(manager.sphericalHarmonicCoefficients[4].z).toEqualEpsilon( + 0.0, + CesiumMath.EPSILON2, + ); expect(manager.sphericalHarmonicCoefficients[5].x).toBeGreaterThan(0.0); expect(manager.sphericalHarmonicCoefficients[5].y).toBeGreaterThan(0.0); From e470dc3eba1ef54b9bc550a5a17585ae269104ed Mon Sep 17 00:00:00 2001 From: jjspace <8007967+jjspace@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:24:06 -0500 Subject: [PATCH 40/41] additions not fixes --- CHANGES.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 4715f9e5523e..d39bb724ee3b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,9 +2,12 @@ ### 1.125 - 2025-01-02 -##### Fixes :wrench: +##### Additions :tada: - Expanded the integration with the [iTwin Platform](https://developer.bentley.com/) to load GeoJSON and KML data from the Reality Management API. Use `ITwinData.createDataSourceForRealityDataId(iTwinId, realityDataId)` to load data as the corresponding Data Source. [#12344](https://github.com/CesiumGS/cesium/pull/12344) + +##### Fixes :wrench: + - Fixed JulianDate to always generate valid ISO strings for fractional milliseconds [#12345](https://github.com/CesiumGS/cesium/pull/12345) - Fixed intermittent z-fighting issue. [#12337](https://github.com/CesiumGS/cesium/issues/12337) From 0717fcfb4d84ed6e7b0cb094f490133705ad2c15 Mon Sep 17 00:00:00 2001 From: ggetz Date: Thu, 2 Jan 2025 15:59:23 -0500 Subject: [PATCH 41/41] Updates for 1.125 release --- CHANGES.md | 8 ++++---- ThirdParty.json | 8 ++++---- package.json | 8 ++++---- packages/engine/Source/Core/Ion.js | 2 +- packages/engine/Source/Scene/ArcGisMapService.js | 2 +- packages/engine/package.json | 2 +- packages/widgets/package.json | 4 ++-- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 647b69313f0b..5c745014715f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,13 +6,13 @@ ##### Additions :tada: -- Expanded the integration with the [iTwin Platform](https://developer.bentley.com/) to load GeoJSON and KML data from the Reality Management API. Use `ITwinData.createDataSourceForRealityDataId(iTwinId, realityDataId)` to load data as the corresponding Data Source. [#12344](https://github.com/CesiumGS/cesium/pull/12344) -- Added `environmentMapOptions` to `ModelGraphics`. For performance reasons, the environment map will not update if the entity position changes by default. If environment map updates based on entity position are desired, ensure to provide an appropriate `environmentMapOptions.maximumPositionEpsilon` value. [#12358](https://github.com/CesiumGS/cesium/pull/12358) +- Expanded integration with the [iTwin Platform](https://developer.bentley.com/) to load GeoJSON and KML data from the Reality Management API. Use `ITwinData.createDataSourceForRealityDataId` to load data as either GeoJSON or KML`. [#12344](https://github.com/CesiumGS/cesium/pull/12344) +- Added `environmentMapOptions` to `ModelGraphics`. For performance reasons by default, the environment map will not update if the entity position change. If environment map updates based on entity position are desired, provide an appropriate `environmentMapOptions.maximumPositionEpsilon` value. [#12358](https://github.com/CesiumGS/cesium/pull/12358) ##### Fixes :wrench: -- Reduced memory usage and peformance bottlenecks when using environment maps with models. [#12356](https://github.com/CesiumGS/cesium/issues/12356) -- Fixed JulianDate to always generate valid ISO strings for fractional milliseconds [#12345](https://github.com/CesiumGS/cesium/pull/12345) +- Reduced memory usage and performance bottlenecks when using environment maps with models. [#12356](https://github.com/CesiumGS/cesium/issues/12356) +- Fixed `JulianDate` to always generate valid ISO strings for fractional milliseconds. [#12345](https://github.com/CesiumGS/cesium/pull/12345) - Fixed intermittent z-fighting issue. [#12337](https://github.com/CesiumGS/cesium/issues/12337) ### 1.124 - 2024-12-02 diff --git a/ThirdParty.json b/ThirdParty.json index ed72a070a4c1..e94b8cf49d93 100644 --- a/ThirdParty.json +++ b/ThirdParty.json @@ -12,7 +12,7 @@ "license": [ "BSD-3-Clause" ], - "version": "2.7.53", + "version": "2.7.54", "url": "https://www.npmjs.com/package/@zip.js/zip.js" }, { @@ -20,7 +20,7 @@ "license": [ "MIT" ], - "version": "4.0.0", + "version": "4.1.0", "url": "https://www.npmjs.com/package/autolinker" }, { @@ -44,7 +44,7 @@ "license": [ "Apache-2.0" ], - "version": "3.2.2", + "version": "3.2.3", "url": "https://www.npmjs.com/package/dompurify", "notes": "dompurify is available as both MPL-2.0 OR Apache-2.0" }, @@ -61,7 +61,7 @@ "license": [ "ISC" ], - "version": "3.0.0", + "version": "3.0.1", "url": "https://www.npmjs.com/package/earcut" }, { diff --git a/package.json b/package.json index 5f1ed19eb0bd..dea10612ca58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.124.0", + "version": "1.125.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -51,8 +51,8 @@ "./Specs/**/*" ], "dependencies": { - "@cesium/engine": "^13.0.0", - "@cesium/widgets": "^10.0.0" + "@cesium/engine": "^13.1.0", + "@cesium/widgets": "^10.1.0" }, "devDependencies": { "@playwright/test": "^1.41.1", @@ -159,4 +159,4 @@ "packages/engine", "packages/widgets" ] -} +} \ No newline at end of file diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index a0a75ec33486..fb02a59c509e 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -4,7 +4,7 @@ import Resource from "./Resource.js"; let defaultTokenCredit; const defaultAccessToken = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZDdmNWJiNy0wMmNlLTQ1MWUtODM2YS02NGM1MTBlOGMwMWQiLCJpZCI6MjU5LCJpYXQiOjE3MzMxNTc4OTV9.B3URHf0VdHDtGckb-hv7uqATdn8KfvkiuoAFZUq8tAo"; + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzYTBjYzY2NC0yMGEyLTQxZDYtYmI2MC1hMWE4ZTBlMGNlNjciLCJpZCI6MjU5LCJpYXQiOjE3MzU4NTEwMzF9.nshpaoC5qpRD4F5diwcjwJ3tddp1OjCSXoMrv37Ales"; /** * Default settings for accessing the Cesium ion API. * diff --git a/packages/engine/Source/Scene/ArcGisMapService.js b/packages/engine/Source/Scene/ArcGisMapService.js index 693004b42cd1..500fd79cd5f8 100644 --- a/packages/engine/Source/Scene/ArcGisMapService.js +++ b/packages/engine/Source/Scene/ArcGisMapService.js @@ -4,7 +4,7 @@ import Resource from "../Core/Resource.js"; let defaultTokenCredit; const defaultAccessToken = - "AAPTxy8BH1VEsoebNVZXo8HurEOF051kAEKlhkOhBEc9BmSrZYLHFXe7j_lQcsSJKc8-7rwh0IFSNWLGZErkzXRnYjMjURTz-hGiKMEeAJIZBG7uiYEn0Mt1rrwlJGIpirZQC4iO428519DlO3QC9DnRBqLXGTBhirgoU7-Z2209sy87s49kw6NOC8_Eew6nCLf-pZ883DRPRyAYH7LC8cvRLInud0EdndtUFa4y83TamrA.AT1_ahjrWDrq"; + "AAPTxy8BH1VEsoebNVZXo8HurEOF051kAEKlhkOhBEc9BmSFctdVnwhKUPPSRxMpNygUNlP8JmGGUdPJSkOUNGzOjDGJ6_IBw0ZIYb2CxiR6SbKR4hMj3np1HXa_Idxv_txLhu62WcUsFQSTBvq7ktym5DNKxqVmIzBnPljNsM8ff9hCKEXq0LTd8VzkHqjVA7-ig_wg7BqJGg7vUMgG1QseyUAjpmY2OaEv9rA8aeBjRrc.AT1_8nZ92i8c"; /** * Default options for accessing the ArcGIS image tile service. * diff --git a/packages/engine/package.json b/packages/engine/package.json index f95090f5176f..1c33ec28b78a 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/engine", - "version": "13.0.0", + "version": "13.1.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index eecf87e2728d..fbcc895a51bb 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/widgets", - "version": "10.0.0", + "version": "10.1.0", "description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", @@ -28,7 +28,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@cesium/engine": "^13.0.0", + "@cesium/engine": "^13.1.0", "nosleep.js": "^0.12.0" }, "type": "module",