为了节约内存, 对参数化数据的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);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。