乐趣区

关于javascript:Uint8Array-我TM谢谢你不报错哦

为了节约内存, 对参数化数据的 typedArray 进行了判断抉择

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;
}

在进行合批操作时,合并所有的顶点、索引和 Uv 数据

// 合并 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, 这时候就呈现了问题,反正就是绘制不对,很奇怪的形态

在索引、顶点、法线中,我感觉只有索引出错能力导致这种状况,所以追踪剖析。

解决

罪魁呢 就是 Uint8Array, 因为这小子啊,下边越界不报错,给我又循环一遍 …
对于原理,我用几句代码阐明

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

当相加扭转数值大小,直到边界

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

再次相加

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

原理就是当 Uint8Array 越界之后不会报错,并且会在下一个边界循环!看 MDN

解决办法就是加完后判断下大小

// @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);
退出移动版