Skip to content

Commit ee4fdcb

Browse files
committed
Address reviewer feedback
1 parent ab62884 commit ee4fdcb

6 files changed

Lines changed: 98 additions & 33 deletions

File tree

packages/engine/Source/Scene/BufferPointCollection.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,7 @@ class BufferPointCollection extends BufferPrimitiveCollection {
9898
* @ignore
9999
*/
100100
_cloneEmpty(capacity = Frozen.EMPTY_OBJECT) {
101-
return new BufferPointCollection({
102-
primitiveCountMax: capacity.primitiveCountMax ?? this.primitiveCountMax,
103-
positionDatatype: this.positionDatatype,
104-
positionNormalized: this.positionNormalized,
105-
});
101+
return new BufferPointCollection(this._cloneEmptyBaseArgs(capacity));
106102
}
107103

108104
/////////////////////////////////////////////////////////////////////////////

packages/engine/Source/Scene/BufferPolygonCollection.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,9 @@ class BufferPolygonCollection extends BufferPrimitiveCollection {
252252
*/
253253
_cloneEmpty(capacity = Frozen.EMPTY_OBJECT) {
254254
return new BufferPolygonCollection({
255-
primitiveCountMax: capacity.primitiveCountMax ?? this.primitiveCountMax,
256-
vertexCountMax: capacity.vertexCountMax ?? this.vertexCountMax,
255+
...this._cloneEmptyBaseArgs(capacity),
257256
holeCountMax: capacity.holeCountMax ?? this.holeCountMax,
258257
triangleCountMax: capacity.triangleCountMax ?? this.triangleCountMax,
259-
positionDatatype: this.positionDatatype,
260-
positionNormalized: this.positionNormalized,
261258
});
262259
}
263260

packages/engine/Source/Scene/BufferPolylineCollection.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,7 @@ class BufferPolylineCollection extends BufferPrimitiveCollection {
8181
* @ignore
8282
*/
8383
_cloneEmpty(capacity = Frozen.EMPTY_OBJECT) {
84-
return new BufferPolylineCollection({
85-
primitiveCountMax: capacity.primitiveCountMax ?? this.primitiveCountMax,
86-
vertexCountMax: capacity.vertexCountMax ?? this.vertexCountMax,
87-
positionDatatype: this.positionDatatype,
88-
positionNormalized: this.positionNormalized,
89-
});
84+
return new BufferPolylineCollection(this._cloneEmptyBaseArgs(capacity));
9085
}
9186

9287
/////////////////////////////////////////////////////////////////////////////

packages/engine/Source/Scene/BufferPrimitiveCollection.js

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,14 @@ class BufferPrimitiveCollection {
467467
result._primitiveCount = collection._primitiveCount;
468468
result._positionCount = collection._positionCount;
469469

470-
// Unset PickIds.
470+
// Copy per-primitive pick objects and unset each GPU PickId.
471+
// PickIds are regenerated for the result collection on next render.
472+
const srcPickObjects = collection._pickObjects;
473+
const dstPickObjects = result._pickObjects;
474+
dstPickObjects.length = 0;
471475
const primitive = new PrimitiveClass();
472476
for (let i = 0, il = result.primitiveCount; i < il; i++) {
477+
dstPickObjects[i] = srcPickObjects[i];
473478
result.get(i, primitive)._pickId = 0;
474479
}
475480

@@ -485,11 +490,18 @@ class BufferPrimitiveCollection {
485490
* Returns a copy of this collection resized to the given capacities, with all
486491
* primitives copied in. The new collection must be large enough to hold every primitive.
487492
*
493+
* <p>Collection-level state (model matrix, blend option, picking, bounding-volume
494+
* mode, etc.) is carried over, but GPU resources are not: the source collection
495+
* retains ownership of its renderer resources, so the caller is responsible for
496+
* calling {@link BufferPrimitiveCollection#destroy} on the source once it is no
497+
* longer needed.</p>
498+
*
488499
* @example
489-
* const grown = collection.toCapacity({
500+
* const grown = collection.withCapacity({
490501
* primitiveCountMax: collection.primitiveCountMax * 2,
491502
* vertexCountMax: collection.vertexCountMax * 2,
492503
* });
504+
* collection.destroy(); // release the source collection's GPU resources
493505
*
494506
* @param {BufferPrimitiveCapacity} [capacity] Capacities for the new collection.
495507
* @returns {BufferPrimitiveCollection<T>}
@@ -500,6 +512,35 @@ class BufferPrimitiveCollection {
500512
return result;
501513
}
502514

515+
/**
516+
* Base constructor arguments that carry over collection-level state to an
517+
* empty copy created by {@link BufferPrimitiveCollection#withCapacity}.
518+
* Subclasses should spread the result into their constructor arguments,
519+
* adding any type-specific capacities. Omitted capacities are inherited from
520+
* this collection.
521+
*
522+
* @param {BufferPrimitiveCapacity} capacity
523+
* @returns {object}
524+
* @protected
525+
* @ignore
526+
*/
527+
_cloneEmptyBaseArgs(capacity) {
528+
return {
529+
primitiveCountMax: capacity.primitiveCountMax ?? this.primitiveCountMax,
530+
vertexCountMax: capacity.vertexCountMax ?? this.vertexCountMax,
531+
positionDatatype: this.positionDatatype,
532+
positionNormalized: this.positionNormalized,
533+
modelMatrix: this._modelMatrix,
534+
show: this.show,
535+
debugShowBoundingVolume: this.debugShowBoundingVolume,
536+
blendOption: this._blendOption,
537+
allowPicking: this._allowPicking,
538+
boundingVolume: this._boundingVolumeAutoUpdate
539+
? undefined
540+
: this._boundingVolume,
541+
};
542+
}
543+
503544
/**
504545
* Returns an empty collection with the same structure as this one, sized to the
505546
* given capacity. Omitted capacities are inherited from this collection.

packages/engine/Source/Scene/ClippingPolygonCollection.js

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import ComputeCommand from "../Renderer/ComputeCommand.js";
2323
import PolygonSignedDistanceFS from "../Shaders/PolygonSignedDistanceFS.js";
2424
import Pass from "../Renderer/Pass.js";
2525
import BufferPolygonCollection from "./BufferPolygonCollection.js";
26-
import BufferPrimitiveCollection from "./BufferPrimitiveCollection.js";
2726
import BufferPolygon from "./BufferPolygon.js";
2827

2928
// Reused flyweight for reading/writing individual BufferPolygons.
@@ -84,19 +83,17 @@ function ClippingPolygonCollection(options) {
8483
*/
8584
this._polygons = [];
8685

87-
// Add each ClippingPolygon object.
8886
const polygons = options.polygons;
8987
let numVertices = 0;
9088
if (defined(polygons)) {
9189
const polygonsLength = polygons.length;
9290
for (let i = 0; i < polygonsLength; ++i) {
93-
this._polygons.push({ clippingPolygon: polygons[i], bufferIndex: -1 });
9491
numVertices += polygons[i].length;
9592
}
9693
}
9794

98-
// Note: update uses this as a heuristic for tracking changes to the collections. Leave it as 0 for now so that
99-
// the first update loop always runs.
95+
// Note: update uses this as a sentinel for tracking changes to the collections. Leave it as 0 for now so that
96+
// the first update loop always runs, even though we already know the value (numVertices).
10097
this._totalPositions = 0;
10198

10299
// For now: this is a write-through mirror of the polygons array. In upcoming work,
@@ -105,15 +102,9 @@ function ClippingPolygonCollection(options) {
105102
this._bufferPolygonCollection = new BufferPolygonCollection({
106103
// We just need it as a data structure, set show to false to prevent unnecessary render buffer allocations.
107104
show: false,
108-
// Preallocate double the number of polygons
109-
primitiveCountMax:
110-
polygons?.length > 0
111-
? 2 * polygons.length
112-
: BufferPrimitiveCollection.DEFAULT_CAPACITY,
113-
vertexCountMax:
114-
numVertices > 0
115-
? 2 * numVertices
116-
: BufferPrimitiveCollection.DEFAULT_CAPACITY,
105+
// Preallocate double the initial data.
106+
primitiveCountMax: 2 * (polygons?.length ?? 0),
107+
vertexCountMax: 2 * numVertices,
117108
// ClippingPolygonCollection does not support holes currently (when this changes, update accordingly)
118109
holeCountMax: 0,
119110
// This may be fine to stay as 0: we do not need the triangulation for Vector-based clipping.
@@ -123,8 +114,7 @@ function ClippingPolygonCollection(options) {
123114
if (defined(polygons)) {
124115
for (let i = 0; i < polygons.length; ++i) {
125116
const positions = polygons[i].positions;
126-
this._polygons[i].bufferIndex =
127-
this._bufferPolygonCollection.primitiveCount;
117+
const bufferIndex = this._bufferPolygonCollection.primitiveCount;
128118
this._bufferPolygonCollection.add(
129119
{
130120
positions: Cartesian3.packArray(
@@ -134,6 +124,10 @@ function ClippingPolygonCollection(options) {
134124
},
135125
bufferPolygonScratch,
136126
);
127+
this._polygons.push({
128+
clippingPolygon: polygons[i],
129+
bufferIndex: bufferIndex,
130+
});
137131
}
138132
}
139133

@@ -356,6 +350,8 @@ function reserveBufferCapacity(collection, addedVertexCount) {
356350
primitiveCountMax: Math.max(2 * buffer.primitiveCountMax, neededPrimitives),
357351
vertexCountMax: Math.max(2 * buffer.vertexCountMax, neededVertices),
358352
});
353+
354+
buffer.destroy();
359355
collection._bufferPolygonCollection = grown;
360356
return grown;
361357
}

packages/engine/Specs/Scene/BufferPolygonCollectionSpec.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
Color,
55
ComponentDatatype,
66
Matrix4,
7+
BlendOption,
78
BufferPolygon,
89
BufferPolygonCollection,
910
BufferPolygonMaterial,
@@ -322,6 +323,45 @@ describe("Scene/BufferPolygonCollection", () => {
322323
expect(inherited.triangleCountMax).toBe(4);
323324
});
324325

326+
it("withCapacity transfers collection state", () => {
327+
const modelMatrix = Matrix4.fromTranslation(new Cartesian3(1, 2, 3));
328+
const boundingVolume = new BoundingSphere(new Cartesian3(4, 5, 6), 7);
329+
const pickObject = { id: "picked" };
330+
331+
const src = new BufferPolygonCollection({
332+
primitiveCountMax: 2,
333+
vertexCountMax: 6,
334+
holeCountMax: 1,
335+
triangleCountMax: 4,
336+
modelMatrix: modelMatrix,
337+
blendOption: BlendOption.OPAQUE,
338+
allowPicking: true,
339+
boundingVolume: boundingVolume,
340+
debugShowBoundingVolume: true,
341+
});
342+
343+
const polygon = new BufferPolygon();
344+
src.add(
345+
{ positions: createBoxPositions(3), pickObject: pickObject },
346+
polygon,
347+
);
348+
349+
const dst = src.withCapacity({ primitiveCountMax: 4 });
350+
351+
// Constructor-only collection state is carried over.
352+
expect(dst.modelMatrix).toEqual(modelMatrix);
353+
expect(dst._blendOption).toBe(BlendOption.OPAQUE);
354+
expect(dst._allowPicking).toBe(true);
355+
expect(dst.debugShowBoundingVolume).toBe(true);
356+
357+
// Manual bounding-volume mode and value are preserved.
358+
expect(dst._boundingVolumeAutoUpdate).toBe(false);
359+
expect(dst.boundingVolume).toEqual(boundingVolume);
360+
361+
// Per-primitive pick objects are copied.
362+
expect(dst._pickObjects[0]).toBe(pickObject);
363+
});
364+
325365
it("sort", () => {
326366
const collection = new BufferPolygonCollection({
327367
primitiveCountMax: 3,

0 commit comments

Comments
 (0)