Skip to content

Commit

Permalink
Merge pull request #12204 from CesiumGS/gpm-support
Browse files Browse the repository at this point in the history
GPM 1.2 support
  • Loading branch information
ggetz authored Sep 30, 2024
2 parents 6c2e520 + c910090 commit e3e9837
Show file tree
Hide file tree
Showing 19 changed files with 2,405 additions and 0 deletions.
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;
}
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,
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.
*/
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
*
* @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
* 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
*
* @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
*
* @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

0 comments on commit e3e9837

Please sign in to comment.