Skip to content

Commit

Permalink
add boolean flag to primitive to calculate statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
lukemckinstry committed Feb 11, 2025
1 parent 254ae74 commit 3759b69
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 25 deletions.
2 changes: 1 addition & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#### Additions :tada:

- Add `ITwinData.loadGeospatialFeatures(iTwinId, collectionId)` function to load data from the [Geospatial Features API](https://developer.bentley.com/apis/geospatial-features/operations/get-features/) [#12449](https://github.com/CesiumGS/cesium/pull/12449)
- Implemented `texturesByteLength`, `visited`, and `numberOfTilesWithContentReady` in `VoxelPrimitive.statistics`.
- Implemented `texturesByteLength`, `visited`, and `numberOfTilesWithContentReady` in `VoxelPrimitive.statistics`. To use statistics, set `options.calculateStatistics` to `true` in the constructor. Note `VoxelPrimitive` is experimental.

#### Fixes :wrench:

Expand Down
10 changes: 8 additions & 2 deletions packages/engine/Source/Scene/VoxelPrimitive.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import Cesium3DTilesetStatistics from "./Cesium3DTilesetStatistics.js";
* @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The model matrix used to transform the primitive.
* @param {CustomShader} [options.customShader] The custom shader used to style the primitive.
* @param {Clock} [options.clock] The clock used to control time dynamic behavior.
* @param {Boolean} [options.calculateStatistics] Generate statistics for performance profile.
*
* @see VoxelProvider
* @see Cesium3DTilesVoxelProvider
Expand Down Expand Up @@ -77,6 +78,12 @@ function VoxelPrimitive(options) {
*/
this._statistics = new Cesium3DTilesetStatistics();

/**
* @type {boolean}
* @private
*/
this._calculateStatistics = defaultValue(options.calculateStatistics, false);

/**
* This member is not created until the provider is ready.
*
Expand Down Expand Up @@ -1062,6 +1069,7 @@ Object.defineProperties(VoxelPrimitive.prototype, {

/**
* Loading and rendering information for requested content
* To use `visited` and `numberOfTilesWithContentReady` statistics, set options._calculateStatistics` to `true` in the constructor.
* @type {Cesium3DTilesetStatistics}
* @readonly
* @private
Expand Down Expand Up @@ -1145,8 +1153,6 @@ VoxelPrimitive.prototype.update = function (frameState) {
this._clock,
);

this.statistics.clear();

const traversal = this._traversal;
const sampleCountOld = traversal._sampleCount;

Expand Down
45 changes: 27 additions & 18 deletions packages/engine/Source/Scene/VoxelTraversal.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Cartesian2 from "../Core/Cartesian2.js";
import CesiumMath from "../Core/Math.js";
import CullingVolume from "../Core/CullingVolume.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js";
Expand Down Expand Up @@ -93,6 +94,15 @@ function VoxelTraversal(
*/
this._debugPrint = false;

/**
* @type {boolean}
* @private
*/
this._calculateStatistics = defaultValue(
this._primitive._calculateStatistics,
false,
);

/**
* @type {number}
* @private
Expand Down Expand Up @@ -332,16 +342,23 @@ VoxelTraversal.prototype.update = function (
generateOctree(this, sampleCount, levelBlendFactor);
const timestamp2 = getTimestamp();

const loadAndUnloadTimeMs = timestamp1 - timestamp0;
const generateOctreeTimeMs = timestamp2 - timestamp1;
const totalTimeMs = timestamp2 - timestamp0;
postPassesUpdate(
this,
frameState,
loadAndUnloadTimeMs,
generateOctreeTimeMs,
totalTimeMs,
);
const checkEventListeners =
primitive.loadProgress.numberOfListeners > 0 ||
primitive.allTilesLoaded.numberOfListeners > 0 ||
primitive.initialTilesLoaded.numberOfListeners > 0;

if (this._debugPrint || this._calculateStatistics || checkEventListeners) {
const loadAndUnloadTimeMs = timestamp1 - timestamp0;
const generateOctreeTimeMs = timestamp2 - timestamp1;
const totalTimeMs = timestamp2 - timestamp0;
postPassesUpdate(
this,
frameState,
loadAndUnloadTimeMs,
generateOctreeTimeMs,
totalTimeMs,
);
}
};

/**
Expand Down Expand Up @@ -794,14 +811,6 @@ function postPassesUpdate(
loadStateByCount[KeyframeNode.LoadState.LOADED];
primitive.statistics.visited = nodeCountTotal;

const checkEventListeners =
primitive.loadProgress.numberOfListeners > 0 ||
primitive.allTilesLoaded.numberOfListeners > 0 ||
primitive.initialTilesLoaded.numberOfListeners > 0;
if (!that._debugPrint && !checkEventListeners) {
return;
}

const numberOfPendingRequests =
loadStateByCount[KeyframeNode.LoadState.RECEIVING];
const numberOfTilesProcessing =
Expand Down
47 changes: 46 additions & 1 deletion packages/engine/Specs/Scene/VoxelPrimitiveSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe(
expect(spyUpdate.calls.count()).toEqual(1);
});

it("initial tiles loaded and all tiles loaded events are raised and statistics are updates", async function () {
it("initial tiles loaded and all tiles loaded events are raised", async function () {
const spyUpdate1 = jasmine.createSpy("listener");
const spyUpdate2 = jasmine.createSpy("listener");
const primitive = new VoxelPrimitive({ provider });
Expand All @@ -83,11 +83,56 @@ describe(
});
expect(spyUpdate1.calls.count()).toEqual(1);
expect(spyUpdate2.calls.count()).toEqual(1);
});

it("statistics are updated when event listeners are assigned", async function () {
const spyUpdate1 = jasmine.createSpy("listener");
const spyUpdate2 = jasmine.createSpy("listener");
const primitive = new VoxelPrimitive({ provider });
scene.primitives.add(primitive);
primitive.allTilesLoaded.addEventListener(spyUpdate1);
primitive.initialTilesLoaded.addEventListener(spyUpdate2);
await pollToPromise(() => {
scene.renderForSpecs();
return primitive._traversal._initialTilesLoaded;
});
expect(primitive.statistics.numberOfTilesWithContentReady).toEqual(1);
expect(primitive.statistics.visited).toEqual(1);
expect(primitive.statistics.texturesByteLength).toEqual(134217728);
});

it("statistics are updated when constructor option is true", async function () {
const primitive = new VoxelPrimitive({
provider,
calculateStatistics: true,
});
scene.primitives.add(primitive);
await pollToPromise(() => {
scene.renderForSpecs();
return primitive.ready;
});
await pollToPromise(() => {
scene.renderForSpecs();
return primitive._traversal._initialTilesLoaded;
});
expect(primitive.statistics.numberOfTilesWithContentReady).toEqual(1);
expect(primitive.statistics.visited).toEqual(1);
});

it("statistics are not updated when constructor option is false", async function () {
const primitive = new VoxelPrimitive({ provider });
scene.primitives.add(primitive);
await pollToPromise(() => {
scene.renderForSpecs();
return primitive.ready;
});
for (let i = 0; i < 10; i++) {
scene.renderForSpecs();
}
expect(primitive.statistics.numberOfTilesWithContentReady).toEqual(0);
expect(primitive.statistics.visited).toEqual(0);
});

it("tile load, load progress and tile visible events are raised", async function () {
const spyUpdate1 = jasmine.createSpy("listener");
const spyUpdate2 = jasmine.createSpy("listener");
Expand Down
5 changes: 2 additions & 3 deletions packages/engine/Specs/Scene/VoxelTraversalSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,11 @@ describe(

const megatexture = traversal.megatextures[0];
expect(megatexture.occupiedCount).toBe(1);
expect(traversal._primitive.statistics.texturesByteLength).toEqual(
134217728,
);
expect(traversal.textureMemoryByteLength).toEqual(500);
});

it("tile failed event is raised", async function () {
traversal._calculateStatistics = true;
const keyFrameLocation = 0;
const recomputeBoundingVolumes = true;
const pauseUpdate = false;
Expand Down

0 comments on commit 3759b69

Please sign in to comment.