Stop generating so much garbage during mesh expansion.

Avoids a slow script dialog in the 3D demo.
This commit is contained in:
Patrick Walton 2017-09-28 10:47:16 -07:00
parent 1675944dfb
commit 6217577674
1 changed files with 34 additions and 17 deletions

View File

@ -36,6 +36,8 @@ export const B_QUAD_LOWER_CONTROL_POINT_VERTEX_OFFSET: number = 4 * 6;
export const B_QUAD_UPPER_INDICES_OFFSET: number = B_QUAD_UPPER_LEFT_VERTEX_OFFSET;
export const B_QUAD_LOWER_INDICES_OFFSET: number = B_QUAD_LOWER_LEFT_VERTEX_OFFSET;
const B_QUAD_FIELD_COUNT: number = B_QUAD_SIZE / UINT32_SIZE;
type BufferType = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER';
export interface Meshes<T> {
@ -71,7 +73,7 @@ export class PathfinderMeshData implements Meshes<ArrayBuffer> {
}
expand(pathIDs: number[]): PathfinderMeshData {
const bQuads = _.chunk(new Uint32Array(this.bQuads), B_QUAD_SIZE / UINT32_SIZE);
const bQuads = new Uint32Array(this.bQuads);
const bVertexPositions = new Float32Array(this.bVertexPositions);
const bVertexPathIDs = new Uint16Array(this.bVertexPathIDs);
const bVertexLoopBlinnData = new Uint32Array(this.bVertexLoopBlinnData);
@ -83,6 +85,11 @@ export class PathfinderMeshData implements Meshes<ArrayBuffer> {
for (let indexIndex = 3; indexIndex < edgeLowerCurveIndices.length; indexIndex += 4)
edgeLowerCurveIndices[indexIndex] = 0;
const coverInteriorIndices = new Uint32Array(this.coverInteriorIndices);
const coverCurveIndices = new Uint32Array(this.coverCurveIndices);
const edgeUpperLineIndices = new Uint32Array(this.edgeUpperLineIndices);
const edgeLowerLineIndices = new Uint32Array(this.edgeLowerLineIndices);
const expandedBQuads: number[] = [];
const expandedBVertexPositions: number[] = [];
const expandedBVertexPathIDs: number[] = [];
@ -114,51 +121,50 @@ export class PathfinderMeshData implements Meshes<ArrayBuffer> {
// Copy over indices.
copyIndices(expandedCoverInteriorIndices,
new Uint32Array(this.coverInteriorIndices),
coverInteriorIndices,
firstExpandedBVertexIndex,
firstBVertexIndex,
bVertexIndex);
copyIndices(expandedCoverCurveIndices,
new Uint32Array(this.coverCurveIndices),
coverCurveIndices,
firstExpandedBVertexIndex,
firstBVertexIndex,
bVertexIndex);
copyIndices(expandedEdgeUpperLineIndices,
new Uint32Array(this.edgeUpperLineIndices),
edgeUpperLineIndices,
firstExpandedBVertexIndex,
firstBVertexIndex,
bVertexIndex);
copyIndices(expandedEdgeUpperCurveIndices,
new Uint32Array(edgeUpperCurveIndices),
edgeUpperCurveIndices,
firstExpandedBVertexIndex,
firstBVertexIndex,
bVertexIndex,
indexIndex => indexIndex % 4 < 3);
copyIndices(expandedEdgeLowerLineIndices,
new Uint32Array(this.edgeLowerLineIndices),
edgeLowerLineIndices,
firstExpandedBVertexIndex,
firstBVertexIndex,
bVertexIndex);
copyIndices(expandedEdgeLowerCurveIndices,
new Uint32Array(edgeLowerCurveIndices),
edgeLowerCurveIndices,
firstExpandedBVertexIndex,
firstBVertexIndex,
bVertexIndex,
indexIndex => indexIndex % 4 < 3);
// Copy over B-quads.
let firstBQuadIndex = _.findIndex(bQuads,
bQuad => bVertexPathIDs[bQuad[0]] === pathID);
if (firstBQuadIndex < 0)
let firstBQuadIndex = findFirstBQuadIndex(bQuads, pathID);
if (firstBQuadIndex == null)
firstBQuadIndex = bQuads.length;
const indexDelta = firstExpandedBVertexIndex - firstBVertexIndex;
for (let bQuadIndex = firstBQuadIndex; bQuadIndex < bQuads.length; bQuadIndex++) {
const bQuad = bQuads[bQuadIndex];
if (bVertexPathIDs[bQuad[0]] !== pathID)
if (bVertexPathIDs[bQuads[bQuadIndex * B_QUAD_FIELD_COUNT]] !== pathID)
break;
for (let indexIndex = 0; indexIndex < B_QUAD_SIZE / UINT32_SIZE; indexIndex++) {
const srcIndex = bQuad[indexIndex];
for (let indexIndex = 0; indexIndex < B_QUAD_FIELD_COUNT; indexIndex++) {
const srcIndex = bQuads[bQuadIndex * B_QUAD_FIELD_COUNT + indexIndex];
if (srcIndex === UINT32_MAX)
expandedBQuads.push(srcIndex);
else
@ -239,10 +245,8 @@ function copyIndices(destIndices: number[],
if (firstIndex === lastIndex)
return;
// FIXME(pcwalton): Use binary search instead of linear search.
let indexIndex = _.findIndex(srcIndices, srcIndex => {
return srcIndex >= firstIndex && srcIndex < lastIndex;
});
// FIXME(pcwalton): Speed this up somehow.
let indexIndex = srcIndices.findIndex(index => index >= firstIndex && index < lastIndex);
if (indexIndex < 0)
return;
@ -259,3 +263,16 @@ function copyIndices(destIndices: number[],
indexIndex++;
}
}
function findFirstBQuadIndex(bQuads: Uint32Array, queryPathID: number): number | null {
let low = 0, high = bQuads.length / B_QUAD_FIELD_COUNT;
while (low < high) {
const mid = low + (high - low) / 2;
const thisPathID = bQuads[mid * B_QUAD_FIELD_COUNT];
if (queryPathID <= thisPathID)
high = mid;
else
low = mid + 1;
}
return bQuads[low * B_QUAD_FIELD_COUNT] === queryPathID ? low : null;
}