1

In order to save memory, the typedArray of parameterized data is judged and selected

 public static FillIndexArray(len: number) {
    let indexArr = len < 0x100 ? new Uint8Array(len) : (len < 0x10000 ? new Uint16Array(len) : new Uint32Array(len));
    for (let i = 0; i < len; ++i) {
        indexArr[i] = i;
    }
    return indexArr;
}

Merge all vertex, index and UV data when doing batch operations

 // 合并index数据
for (let i = 0; i < this.Geometries.length; ++i) {
    index.set(geo.Indices.map(x => x + curPosition/3), curIndex);
    curIndex += geo.Indices.length;
}

OK, there is a problem at this time, anyway, the drawing is wrong, very strange shape

In indices, vertices, normals, I feel that only an index error can cause this, so traced the analysis.

solve

The culprit is Uint8Array, because this kid doesn't report an error if it crosses the border, just loop it again for me...
For the principle, I use a few lines of code to explain

  const a = new Uint8Array(10)
  const b = a.map(v => v)
  console.log(b) // 结果 [0, 0, 0, 0,....]

When adding changes the size of the value until the boundary

 const a = new Uint8Array(10)
  const b = a.map(v => v+255)
  console.log(b) // 结果 [255, 255, 255, 255,....]

add again

 const a = new Uint8Array(10)
  const b = a.map(v => v+256)
  console.log(b) // 结果 [0, 0, 0, 0,....]

The principle is that when Uint8Array crosses the boundary, no error will be reported, and it will loop at the next boundary! see MDN

The solution is to judge the size after adding

 // @ts-ignore
const max = geo.Indices.reduce((acc, val) => {
    const value = val + curPosition/3
    if(value >= acc) {
        acc = value;
    }
    return acc;
}, 0)

const mapCount = geo.Indices.length
const mapIndices = max < 0x100 ? new Uint8Array(mapCount) : (indexCount < 0x10000 ? new Uint16Array(mapCount) : new Uint32Array(mapCount));
for(let i =0; i < mapCount; ++i) {
    mapIndices[i] = geo.Indices[i]
}

index.set(mapIndices.map(x => x + curPosition/3), curIndex);

陈东民
2.1k 声望269 粉丝

坚持自我 纯粹的技术