Skip to content

Commit 389770e

Browse files
authored
Merge pull request #8820 from CesiumGS/outline-32
Fix problem switching from Uint16 to Uint32 indices for outlining.
2 parents d8145e7 + 743a5ba commit 389770e

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
##### Fixes :wrench:
1010

11+
- Fixed a bug that could cause rendering of a glTF model to become corrupt when switching from a Uint16 to a Uint32 index buffer to accomodate new vertices added for edge outlining. [#8820](https://github.com/CesiumGS/cesium/pull/8820)
1112
- This fixes a bug where a removed billboard can prevent changing of the terrainProvider [#8766](https://github.com/CesiumGS/cesium/pull/8766)
1213

1314
### 1.69.0 - 2020-05-01

Source/Scene/ModelOutlineLoader.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"
88
import TextureWrap from "../Renderer/TextureWrap.js";
99
import ForEach from "../ThirdParty/GltfPipeline/ForEach.js";
1010

11+
// glTF does not allow an index value of 65535 because this is the primitive
12+
// restart value in some APIs.
13+
var MAX_GLTF_UINT16_INDEX = 65534;
14+
1115
/**
1216
* Creates face outlines for glTF primitives with the `CESIUM_primitive_outline` extension.
1317
* @private
@@ -273,7 +277,10 @@ function addOutline(
273277
vertexCopies[unmatchableVertexIndex] = copy;
274278
}
275279

276-
if (copy >= 65536 && triangleIndices instanceof Uint16Array) {
280+
if (
281+
copy > MAX_GLTF_UINT16_INDEX &&
282+
triangleIndices instanceof Uint16Array
283+
) {
277284
// We outgrew a 16-bit index buffer, switch to 32-bit.
278285
triangleIndices = new Uint32Array(triangleIndices);
279286
triangleIndexAccessorGltf.componentType = 5125; // UNSIGNED_INT
@@ -295,6 +302,15 @@ function addOutline(
295302
0,
296303
triangleIndices.byteLength
297304
);
305+
306+
// The index componentType is also squirreled away in ModelLoadResources.
307+
// Hackily update it, or else we'll end up creating the wrong type
308+
// of index buffer later.
309+
loadResources.indexBuffersToCreate._array.forEach(function (toCreate) {
310+
if (toCreate.id === triangleIndexAccessorGltf.bufferView) {
311+
toCreate.componentType = triangleIndexAccessorGltf.componentType;
312+
}
313+
});
298314
}
299315

300316
if (unmatchableVertexIndex === i0) {

Specs/Scene/ModelOutlineLoaderSpec.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,13 +499,21 @@ describe(
499499
});
500500
});
501501

502-
it("switches to 32-bit indices if more than 65536 vertices are required", function () {
502+
it("switches to 32-bit indices if more than 65535 vertices are required", function () {
503+
if (!scene.context.elementIndexUint) {
504+
// This extension is supported everywhere these days, except possibly
505+
// in our mocked WebGL context used in the tests on Travis. Consistent
506+
// with the approach in ModelSpec.js, `loads a gltf with uint32 indices`,
507+
// we'll just give this test a pass if uint indices aren't supported.
508+
return;
509+
}
510+
503511
var vertices = [];
504512
var indices = [];
505513
var edges = [];
506514

507515
// Tricky model is 9 vertices. Add copies of it until we're just under 65636 vertices.
508-
for (var i = 0; vertices.length / 7 + 9 <= 65536; ++i) {
516+
for (var i = 0; vertices.length / 7 + 9 <= 65535; ++i) {
509517
createTrickyModel(vertices, indices, edges, 2, true, true, true);
510518
}
511519

@@ -575,6 +583,10 @@ describe(
575583
}
576584
}
577585

586+
var rendererIndexBuffer =
587+
model._rendererResources.buffers[triangleIndexAccessor.bufferView];
588+
expect(rendererIndexBuffer.bytesPerIndex).toBe(4);
589+
578590
builder.destroy();
579591
});
580592
});

0 commit comments

Comments
 (0)