Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPM 1.2 support #12204

Merged
merged 42 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
eb4ec20
First, partial support of GPM classes
javagl Sep 17, 2024
d7f1c91
Fix import and usage of 'Check'
javagl Sep 18, 2024
e09cb04
Start wiring in GPM loader
javagl Sep 18, 2024
7e14791
Move loaders to extension directory
javagl Sep 19, 2024
6ee7344
Added implementation note in GltfGpmLoader
javagl Sep 19, 2024
c2a064c
Fix handling of min, max, offset, scale for PPE textures
javagl Sep 19, 2024
50b0727
Enable releaseGltfJson
javagl Sep 21, 2024
cac091f
Let GltfGpmLoader not extend ResourceLoader
javagl Sep 21, 2024
1cc38fa
Minor cleanup and comments
javagl Sep 21, 2024
4e6d501
Fix type checks
javagl Sep 21, 2024
9e7bfcf
Explicit conversion of PPE into structural metadata
javagl Sep 21, 2024
5110166
Remove debug logs
javagl Sep 24, 2024
323f4f0
Additional type checks
javagl Sep 24, 2024
6326d40
Added JSDoc comment
javagl Sep 24, 2024
eaf6112
First part of GPM loading specs
javagl Sep 24, 2024
9dbd45e
Proper imports for spec file
javagl Sep 25, 2024
6e290c8
Explicitly offer parsed GPM data
javagl Sep 25, 2024
6e41b36
Add specs for mesh primitive GPM data
javagl Sep 25, 2024
616171f
Remove log. Check for definedness.
javagl Sep 25, 2024
810684b
Merge tag 'pre-prettier-v3' into gpm-support-prettier
javagl Sep 27, 2024
c6d9784
Merge tag 'post-prettier-v3' into gpm-support-prettier
javagl Sep 27, 2024
d341dc5
Merge remote-tracking branch 'origin/main' into gpm-support-prettier
javagl Sep 27, 2024
8c0f926
Remove experimental tag for getExtensions
javagl Sep 27, 2024
5723c8b
Add return type to JSDoc
javagl Sep 27, 2024
bb74ec4
Add JSDoc for getExtension
javagl Sep 27, 2024
962a986
Add type tag to property
javagl Sep 27, 2024
804fa0a
More elaborate warning text
javagl Sep 27, 2024
905925a
Removed obsolete part of JSDoc
javagl Sep 27, 2024
e887e53
Add JSDoc return type info
javagl Sep 27, 2024
13b2db0
Change error type for load function
javagl Sep 27, 2024
ac78182
List supported extension in model documentation
javagl Sep 27, 2024
e61667c
Update CHANGES.md
javagl Sep 27, 2024
e94ca56
Try to clarify private and experimental
javagl Sep 28, 2024
72414c5
Add links to GPM spec. Updated comments.
javagl Sep 28, 2024
55df6c9
Document constructor options
javagl Sep 28, 2024
b8b5445
Avoid unnecessary constructor options
javagl Sep 28, 2024
e4efa51
Add underscore to internal functions
javagl Sep 28, 2024
860b05b
Further clarification for private
javagl Sep 28, 2024
8eebc95
Merge remote-tracking branch 'origin/main' into gpm-support
javagl Sep 28, 2024
9bfe61a
Update spec for changed error type
javagl Sep 28, 2024
9805652
Further options- and constructor documentation
javagl Sep 28, 2024
c910090
Try to revert undesired formatting changes
javagl Sep 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

- Added `enableVerticalExaggeration` option to models. Set this value to `false` to prevent model exaggeration when `Scene.verticalExaggeration` is set to a value other than `1.0`. [#12141](https://github.com/CesiumGS/cesium/pull/12141)
- Added `CallbackPositionProperty` to allow lazy entity position evaluation. [#12170](https://github.com/CesiumGS/cesium/pull/12170)
- Added experimental support for the `NGA_gpm_local` glTF extension, for GPM 1.2 [#12204](https://github.com/CesiumGS/cesium/pull/12204)

##### Fixes :wrench:

Expand Down
80 changes: 80 additions & 0 deletions packages/engine/Source/Scene/GltfLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import ResourceCache from "./ResourceCache.js";
import ResourceLoader from "./ResourceLoader.js";
import SupportedImageFormats from "./SupportedImageFormats.js";
import VertexAttributeSemantic from "./VertexAttributeSemantic.js";
import GltfGpmLoader from "./Model/Extensions/Gpm/GltfGpmLoader.js";
import GltfMeshPrimitiveGpmLoader from "./Model/Extensions/Gpm/GltfMeshPrimitiveGpmLoader.js";
import oneTimeWarning from "../Core/oneTimeWarning.js";

const {
Attribute,
Expand Down Expand Up @@ -260,6 +263,7 @@ function GltfLoader(options) {
this._geometryLoaders = [];
this._geometryCallbacks = [];
this._structuralMetadataLoader = undefined;
this._meshPrimitiveGpmLoader = undefined;
this._loadResourcesPromise = undefined;
this._resourcesLoaded = false;
this._texturesLoaded = false;
Expand Down Expand Up @@ -471,6 +475,25 @@ function processLoaders(loader, frameState) {
ready = ready && metadataReady;
}

const meshPrimitiveGpmLoader = loader._meshPrimitiveGpmLoader;
if (defined(meshPrimitiveGpmLoader)) {
const metadataReady = meshPrimitiveGpmLoader.process(frameState);
if (metadataReady) {
if (defined(loader._components.structuralMetadata)) {
oneTimeWarning(
"structural-metadata-gpm",
"The model defines both the 'EXT_structural_metadata' extension and the " +
"'NGA_gpm_local' extension. The data from the 'EXT_structural_metadata' " +
"extension will be replaced with the data from the 'NGA_gpm_local' extension, " +
"and will no longer be available for styling and picking.",
);
}
loader._components.structuralMetadata =
meshPrimitiveGpmLoader.structuralMetadata;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be a possibility to merge these together rather than replacing existing structural metadata with that from the GPM extension? This could be for this PR or for the future.

Copy link
Contributor Author

@javagl javagl Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The option of merging metadata (and their schemas) was considered, but cannot be addressed here. There are many caveats. An obvious one:

  • The glTF contains EXT_structural_metadata, with a schema that has the id : "MY_EXAMPLE_SCHEMA"
  • It also defines NGA_gpm_local. Metadata classes will be created for the PPE textures, and added to the schema.
  • Will the schema afterwards still have the id : "MY_EXAMPLE_SCHEMA"?
    • Yes: This does not make sense, because it is a new schema, different from the original one
    • No: Which ID should it have? (And what will users think when their schema with id: "MY_EXAMPLE_SCHEMA" suddenly disappears?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@javagl Does it make sense to document this limitation in an issue and add discussion there about potential solutions?

}
ready = ready && metadataReady;
}

if (ready) {
// Geometry requires further processing
loader._state = GltfLoaderState.POST_PROCESSING;
Expand Down Expand Up @@ -2450,6 +2473,20 @@ async function loadStructuralMetadata(
return structuralMetadataLoader.load();
}

async function loadMeshPrimitiveGpm(loader, gltf, extension, frameState) {
const meshPrimitiveGpmLoader = new GltfMeshPrimitiveGpmLoader({
gltf: gltf,
extension: extension,
gltfResource: loader._gltfResource,
ggetz marked this conversation as resolved.
Show resolved Hide resolved
baseResource: loader._baseResource,
supportedImageFormats: loader._supportedImageFormats,
frameState: frameState,
asynchronous: loader._asynchronous,
});
loader._meshPrimitiveGpmLoader = meshPrimitiveGpmLoader;
return meshPrimitiveGpmLoader.load();
}

function loadAnimationSampler(loader, gltfSampler) {
const animationSampler = new AnimationSampler();
const accessors = loader.gltfJson.accessors;
Expand Down Expand Up @@ -2678,6 +2715,38 @@ function parse(loader, frameState) {
loader._loaderPromises.push(promise);
}

// Load NGA_gpm_local from root object
const gpmExtension = extensions.NGA_gpm_local;
if (defined(gpmExtension)) {
const gltfGpmLocal = GltfGpmLoader.load(gpmExtension);
loader._components.extensions["NGA_gpm_local"] = gltfGpmLocal;
}

// Load NGA_gpm_local from mesh primitives
const meshes = gltf.meshes;
if (defined(meshes)) {
for (const mesh of meshes) {
const primitives = mesh.primitives;
if (defined(primitives)) {
for (const primitive of primitives) {
const primitiveExtensions = primitive.extensions;
if (defined(primitiveExtensions)) {
const meshPrimitiveGpmExtension = primitiveExtensions.NGA_gpm_local;
if (defined(meshPrimitiveGpmExtension)) {
const promise = loadMeshPrimitiveGpm(
loader,
gltf,
meshPrimitiveGpmExtension,
frameState,
);
loader._loaderPromises.push(promise);
}
}
}
}
}
}

// Gather promises and handle any errors
const readyPromises = [];
readyPromises.push.apply(readyPromises, loader._loaderPromises);
Expand Down Expand Up @@ -2742,6 +2811,16 @@ function unloadStructuralMetadata(loader) {
}
}

function unloadMeshPrimitiveGpm(loader) {
if (
defined(loader._meshPrimitiveGpmLoader) &&
!loader._meshPrimitiveGpmLoader.isDestroyed()
) {
loader._meshPrimitiveGpmLoader.destroy();
loader._meshPrimitiveGpmLoader = undefined;
}
}

/**
* Returns whether the resource has been unloaded.
* @private
Expand All @@ -2765,6 +2844,7 @@ GltfLoader.prototype.unload = function () {
unloadGeometry(this);
unloadGeneratedAttributes(this);
unloadStructuralMetadata(this);
unloadMeshPrimitiveGpm(this);

this._components = undefined;
this._typedArray = undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import Check from "../../../../Core/Check.js";

/**
* @typedef {object} AnchorPointDirect.ConstructorOptions
*
* Initialization options for the AnchorPointDirect constructor
*
* @property {Cartesian3} position Anchor point geographic coordinates
* @property {Cartesian3} adjustmentParams The adjustment values in meters
*/

/**
* Metadata for one stored anchor point using direct storage.
*
* This reflects the `anchronPointDirect` definition of the
* {@link https://nsgreg.nga.mil/csmwg.jsp|NGA_gpm_local} glTF extension.
*
* @constructor
* @param {AnchorPointDirect.ConstructorOptions} options An object describing initialization options
* @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
ggetz marked this conversation as resolved.
Show resolved Hide resolved
*/
function AnchorPointDirect(options) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("options.position", options.position);
Check.typeOf.object("options.adjustmentParams", options.adjustmentParams);
//>>includeEnd('debug');

this._position = options.position;
this._adjustmentParams = options.adjustmentParams;
}

Object.defineProperties(AnchorPointDirect.prototype, {
/**
* Anchor point geographic coordinates in meters as X/Easting, Y/Northing, Z/HAE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HAE -> "Height above ellipsoid"

Correct? Would you mind using the full string?

Copy link
Contributor Author

@javagl javagl Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These strings are taken from the JSON schema descriptions. I did not modify them (except for minor things like "this is a 3-element array" -> "this is a vector/point" or such).

*
* @memberof AnchorPointDirect.prototype
* @type {Cartesian3}
* @readonly
*/
position: {
get: function () {
return this._position;
},
},

/**
* The delta-x delta-y delta-z adjustment values in meters per anchor
ggetz marked this conversation as resolved.
Show resolved Hide resolved
* point.
*
* @memberof AnchorPointDirect.prototype
* @type {Cartesian3}
* @readonly
*/
adjustmentParams: {
get: function () {
return this._adjustmentParams;
},
},
});

export default AnchorPointDirect;
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import Check from "../../../../Core/Check.js";

/**
* @typedef {object} AnchorPointIndirect.ConstructorOptions
*
* Initialization options for the AnchorPointIndirect constructor
*
* @property {Cartesian3} position Anchor point geographic coordinates
* @property {Cartesian3} adjustmentParams The adjustment values in meters
* @property {Matrix3} covarianceMatrix The 3x3 covariance matrix
*/

/**
* Metadata for one stored anchor point.
*
* This reflects the `anchronPointIndirect` definition of the
* {@link https://nsgreg.nga.mil/csmwg.jsp|NGA_gpm_local} glTF extension.
*
* @constructor
* @param {AnchorPointIndirect.ConstructorOptions} options An object describing initialization options
* @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
*/
function AnchorPointIndirect(options) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("options.position", options.position);
Check.typeOf.object("options.adjustmentParams", options.adjustmentParams);
Check.typeOf.object("options.covarianceMatrix", options.covarianceMatrix);
//>>includeEnd('debug');

this._position = options.position;
this._adjustmentParams = options.adjustmentParams;
this._covarianceMatrix = options.covarianceMatrix;
}

Object.defineProperties(AnchorPointIndirect.prototype, {
/**
* Anchor point geographic coordinates in meters as X/Easting, Y/Northing, Z/HAE
ggetz marked this conversation as resolved.
Show resolved Hide resolved
*
* @memberof AnchorPointIndirect.prototype
* @type {Cartesian3}
* @readonly
*/
position: {
get: function () {
return this._position;
},
},

/**
* The delta-x delta-y delta-z adjustment values in meters per anchor
* point.
*
* @memberof AnchorPointIndirect.prototype
* @type {Cartesian3}
* @readonly
*/
adjustmentParams: {
get: function () {
return this._adjustmentParams;
},
},

/**
* The 3x3 covariance matrix.
*
* @memberof AnchorPointIndirect.prototype
* @type {Matrix3}
* @readonly
*/
covarianceMatrix: {
get: function () {
return this._covarianceMatrix;
},
},
});

export default AnchorPointIndirect;
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Check from "../../../../Core/Check.js";

/**
* @typedef {object} CorrelationGroup.ConstructorOptions
*
* Initialization options for the CorrelationGroup constructor
*
* @property {boolean[]} groupFlags Array of 3 booleans indicating if
* parameters delta-x delta-y delta-z used in the correlation group
* @property {Cartesian3} rotationThetas Rotations in milliradians
* about X, Y, Z axes, respectively
* @property {Spdcf[]} params Array of `Spdcf` (Strictly Positive-Definite
* Correlation Function) parameters, for the U, V, W directions, respectively
*/

/**
* Metadata identifying parameters using same correlation modeling and
* associated correlation parameters.
*
* This reflects the `correlationGroup` definition of the
* {@link https://nsgreg.nga.mil/csmwg.jsp|NGA_gpm_local} glTF extension.
*
* @constructor
* @param {CorrelationGroup.ConstructorOptions} options An object describing initialization options
* @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
*/
function CorrelationGroup(options) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("options.groupFlags", options.groupFlags);
Check.typeOf.object("options.rotationThetas", options.rotationThetas);
Check.typeOf.object("options.params", options.params);
//>>includeEnd('debug');

this._groupFlags = options.groupFlags;
this._rotationThetas = options.rotationThetas;
this._params = options.params;
}

Object.defineProperties(CorrelationGroup.prototype, {
/**
* Array of 3 booleans indicating if parameters delta-x delta-y delta-z
* used in the correlation group
*
* @memberof CorrelationGroup.prototype
* @type {boolean[]}
* @readonly
*/
groupFlags: {
get: function () {
return this._groupFlags;
},
},

/**
* Rotations in milliradians about X, Y, Z axes, respectively
ggetz marked this conversation as resolved.
Show resolved Hide resolved
*
* @memberof CorrelationGroup.prototype
* @type {Cartesian3}
* @readonly
*/
rotationThetas: {
get: function () {
return this._rotationThetas;
},
},

/**
* Array of 3 sets of SPDCF parameters, for the U, V, W directions, respectively
*
* @memberof CorrelationGroup.prototype
* @type {Spdcf[]}
* @readonly
*/
params: {
get: function () {
return this._params;
},
},
});

export default CorrelationGroup;
Loading