Added support for merging AttributeData

This commit is contained in:
Lucas Dower 2022-03-21 19:38:22 +00:00
parent 339d9cdf21
commit 4b949c07c0
2 changed files with 113 additions and 0 deletions

View File

@ -25,6 +25,45 @@ export interface AttributeData {
}
}
export function MergeAttributeData(...data: AttributeData[]): AttributeData {
if (data.length === 0) {
return {
indices: new Uint32Array(),
custom: {},
};
}
// Check custom attributes match
const requiredAttributes = Object.keys(data[0].custom);
for (let i = 1; i < data.length; ++i) {
const customAttributes = Object.keys(data[i].custom);
const isAllRequiredInCustom = requiredAttributes.every((attr) => {
return customAttributes.includes(attr);
});
const isAllCustomInRequired = customAttributes.every((attr) => {
return requiredAttributes.includes(attr);
});
ASSERT(isAllRequiredInCustom && isAllCustomInRequired, 'Attributes to merge do not match');
}
// Merge data
const indices = Array.from(data[0].indices);
const custom = data[0].custom;
for (let i = 1; i < data.length; ++i) {
const nextIndex = Math.max(...indices) + 1;
const d = data[i];
const newIndices = d.indices.map((index) => index + nextIndex);
indices.push(...Array.from(newIndices));
for (const attr of requiredAttributes) {
const attrData = d.custom[attr];
custom[attr].push(...attrData);
}
}
return {
indices: new Uint32Array(indices),
custom: custom,
};
}
export class RenderBuffer {
private _WebGLBuffer?: {
buffer: twgl.BufferInfo,

74
test/buffer.test.ts Normal file
View File

@ -0,0 +1,74 @@
import { AttributeData, MergeAttributeData } from '../src/buffer';
test('MergeAttributeData #1', () => {
const a: AttributeData = {
indices: new Uint32Array([0, 1, 2]),
custom: {
position: [1, 2, 3, 4, 5, 6, 7, 8, 9],
colour: [1, 0, 0, 0, 1, 0, 0, 0, 1],
},
};
const b = MergeAttributeData(a);
expect(JSON.stringify(a)).toEqual(JSON.stringify(b));
});
test('MergeAttributeData #2', () => {
const a: AttributeData = {
indices: new Uint32Array([0, 1, 2]),
custom: {
position: [1, 2, 3, 4, 5, 6, 7, 8, 9],
colour: [1, 0, 0, 0, 1, 0, 0, 0, 1],
},
};
const b: AttributeData = {
indices: new Uint32Array([0, 1, 2]),
custom: {
position: [10, 11, 12, 13, 14, 15, 16, 17, 18],
colour: [0, 1, 1, 1, 0, 1, 1, 1, 0],
},
};
const cActual = MergeAttributeData(a, b);
const cExpect: AttributeData = {
indices: new Uint32Array([0, 1, 2, 3, 4, 5]),
custom: {
position: [
1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18,
],
colour: [
1, 0, 0, 0, 1, 0, 0, 0, 1,
0, 1, 1, 1, 0, 1, 1, 1, 0,
],
},
};
expect(JSON.stringify(cActual)).toEqual(JSON.stringify(cExpect));
});
test('MergeAttributeData #3', () => {
const a: AttributeData = {
indices: new Uint32Array([0, 1]),
custom: {
data: [1, 2],
},
};
const b: AttributeData = {
indices: new Uint32Array([0, 1]),
custom: {
data: [3, 4],
},
};
const c: AttributeData = {
indices: new Uint32Array([0, 1]),
custom: {
data: [5, 6],
},
};
const dActual = MergeAttributeData(a, b, c);
const dExpect: AttributeData = {
indices: new Uint32Array([0, 1, 2, 3, 4, 5]),
custom: {
data: [1, 2, 3, 4, 5, 6],
},
};
expect(JSON.stringify(dActual)).toEqual(JSON.stringify(dExpect));
});