Skip to content

Commit

Permalink
Move glTF handling from Cesium3DTilesVoxelProvider to VoxelContent
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeshurun Hembd committed Jan 22, 2025
1 parent 10d30e2 commit 20ac82c
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 94 deletions.
67 changes: 4 additions & 63 deletions packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Check from "../Core/Check.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import Ellipsoid from "../Core/Ellipsoid.js";
import GltfLoader from "./GltfLoader.js";
import hasExtension from "./hasExtension.js";
import ImplicitSubtree from "./ImplicitSubtree.js";
import ImplicitSubtreeCache from "./ImplicitSubtreeCache.js";
Expand All @@ -21,8 +20,7 @@ import RuntimeError from "../Core/RuntimeError.js";
import VoxelBoxShape from "./VoxelBoxShape.js";
import VoxelCylinderShape from "./VoxelCylinderShape.js";
import VoxelShapeType from "./VoxelShapeType.js";
import MetadataComponentType from "./MetadataComponentType.js";
import ComponentDatatype from "../Core/ComponentDatatype.js";
import VoxelContent from "./VoxelContent.js";

/**
* A {@link VoxelProvider} that fetches voxel data from a 3D Tiles tileset.
Expand Down Expand Up @@ -474,7 +472,7 @@ async function getSubtree(provider, subtreeCoord) {
}

/**
* Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z.
* Requests the data for a given tile.
*
* @private
*
Expand All @@ -483,9 +481,8 @@ async function getSubtree(provider, subtreeCoord) {
* @param {number} [options.tileX=0] The tile's X coordinate.
* @param {number} [options.tileY=0] The tile's Y coordinate.
* @param {number} [options.tileZ=0] The tile's Z coordinate.
* @param {FrameState} options.frameState The frame state
* @privateparam {number} [options.keyframe=0] The requested keyframe.
* @returns {Promise<Array[]>|undefined} A promise to an array of typed arrays containing the requested voxel data or undefined if there was a problem loading the data.
* @returns {Promise<VoxelContent>} A promise resolving to a VoxelContent containing the data for the tile.
*/
Cesium3DTilesVoxelProvider.prototype.requestData = async function (options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
Expand All @@ -498,10 +495,6 @@ Cesium3DTilesVoxelProvider.prototype.requestData = async function (options) {
frameState,
} = options;

//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("options.frameState", frameState);
//>>includeEnd('debug');

if (keyframe !== 0) {
return Promise.reject(
`3D Tiles currently doesn't support time-dynamic data.`,
Expand Down Expand Up @@ -554,59 +547,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = async function (options) {
url: gltfRelative.url,
});

const gltfLoader = new GltfLoader({
gltfResource: gltfResource,
releaseGltfJson: false,
loadAttributesAsTypedArray: true,
});

await gltfLoader.load();
gltfLoader.process(frameState);
await gltfLoader._loadResourcesPromise;
gltfLoader.process(frameState);

const { attributes } = gltfLoader.components.scene.nodes[0].primitives[0];
return processAttributes(attributes, that);
return VoxelContent.fromGltf(gltfResource, this, frameState);
};

/**
* Processes the attributes from the glTF loader, reordering them into the order expected by the primitive.
* TODO: use a MetadataTable?
*
* @param {ModelComponents.Attribute[]} attributes The attributes to process.
* @param {VoxelProvider} provider The provider from which these attributes were received.
* @returns {TypedArray[]} An array of typed arrays containing the attribute values.
* @private
*/
function processAttributes(attributes, provider) {
const { names, types, componentTypes } = provider;
const data = new Array(attributes.length);

for (let i = 0; i < attributes.length; i++) {
// The attributes array from GltfLoader is not in the same order as
// names, types, etc. from the provider.
// Find the appropriate glTF attribute based on its name.
// Note: glTF custom attribute names are prefixed with "_"
const name = `_${names[i]}`;
const attribute = attributes.find((a) => a.name === name);
if (!defined(attribute)) {
continue;
}

const componentDatatype = MetadataComponentType.toComponentDatatype(
componentTypes[i],
);
const componentCount = MetadataType.getComponentCount(types[i]);
const totalCount = attribute.count * componentCount;
data[i] = ComponentDatatype.createArrayBufferView(
componentDatatype,
attribute.typedArray.buffer,
attribute.typedArray.byteOffset + attribute.byteOffset,
totalCount,
);
}

return data;
}

export default Cesium3DTilesVoxelProvider;
13 changes: 2 additions & 11 deletions packages/engine/Source/Scene/KeyframeNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,26 @@ const LoadState = Object.freeze({
*
* @param {SpatialNode} spatialNode
* @param {number} keyframe
* // TODO: add contentResource param? Or does that go in VoxelContent?
*
* @private
*/
function KeyframeNode(spatialNode, keyframe) {
this.spatialNode = spatialNode;
this.keyframe = keyframe;
this.state = LoadState.UNLOADED;
// TODO: switch to .content
this.metadata = [];
//this.content = undefined;
//this.contentResource = contentResource;
this.content = undefined;
this.megatextureIndex = -1;
this.priority = -Number.MAX_VALUE;
this.highPriorityFrameNumber = -1;
}

//KeyframeNode.prototype.requestContent = function() {
//};

/**
* Frees the resources used by this object.
* TODO: replace with a destroy method?
* @private
*/
KeyframeNode.prototype.unload = function () {
// TODO: switch to .content
//this.content = this.content && this.content.destroy();
this.metadata = [];
this.content = this.content && this.content.destroy();

this.spatialNode = undefined;
this.state = LoadState.UNLOADED;
Expand Down
5 changes: 3 additions & 2 deletions packages/engine/Source/Scene/SpatialNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,15 @@ SpatialNode.prototype.addKeyframeNodeToMegatextures = function (
) {
if (
keyframeNode.megatextureIndex !== -1 ||
keyframeNode.metadata.length !== megatextures.length
keyframeNode.content.metadata.length !== megatextures.length
) {
throw new DeveloperError("Keyframe node cannot be added to megatexture");
}

const { metadata } = keyframeNode.content;
for (let i = 0; i < megatextures.length; i++) {
const megatexture = megatextures[i];
keyframeNode.megatextureIndex = megatexture.add(keyframeNode.metadata[i]);
keyframeNode.megatextureIndex = megatexture.add(metadata[i]);
}

const renderableKeyframeNodes = this.renderableKeyframeNodes;
Expand Down
Loading

0 comments on commit 20ac82c

Please sign in to comment.