Skip to content

Commit

Permalink
support normalizing external buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaoji Chen committed Nov 18, 2019
1 parent 161e2de commit 24285eb
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
10 changes: 7 additions & 3 deletions modules/core/src/lib/attribute/attribute.js
Expand Up @@ -250,11 +250,14 @@ export default class Attribute extends DataColumn {
buffer = {value: buffer};
}
assert(ArrayBuffer.isView(buffer.value), `invalid ${settings.accessor}`);
const needsNormalize = buffer.size && buffer.size !== this.size;

state.logicalAccessor = getAccessorFromBuffer(buffer.value, {
...settings,
...buffer,
startIndices
size: buffer.size || this.size,
stride: buffer.stride,
offset: buffer.offset,
startIndices,
nested: needsNormalize
});
// Fall through to auto updater
return false;
Expand Down Expand Up @@ -285,6 +288,7 @@ export default class Attribute extends DataColumn {
return shaderAttributes;
}

/* eslint-disable max-depth, max-statements */
_autoUpdater(attribute, {data, startRow, endRow, props, numInstances}) {
const {settings, state, value, size, startIndices} = attribute;

Expand Down
41 changes: 28 additions & 13 deletions modules/core/src/utils/iterable-utils.js
Expand Up @@ -64,30 +64,45 @@ export function isAsyncIterable(data) {
/*
* Create an accessor function from a flat buffer that yields the value at each object index
*/
export function getAccessorFromBuffer(typedArray, opts) {
const {size, stride, offset, vertexStarts} = opts;
export function getAccessorFromBuffer(typedArray, {size, stride, offset, startIndices, nested}) {
const bytesPerElement = typedArray.BYTES_PER_ELEMENT;
const elementStride = stride ? stride / bytesPerElement : size;
const elementOffset = offset ? offset / bytesPerElement : 0;
const vertexCount = Math.floor((typedArray.length - elementOffset) / elementStride);

return (_, {index, target}) => {
if (vertexStarts) {
const startVertex = vertexStarts[index];
const endVertex = vertexStarts[index + 1] || vertexCount;
const result = new typedArray.constructor((endVertex - startVertex) * size);
for (let i = startVertex, targetIndex = 0; i < endVertex; i++) {
if (!startIndices) {
const sourceIndex = index * elementStride + elementOffset;
for (let j = 0; j < size; j++) {
target[j] = typedArray[sourceIndex + j];
}
return target;
}
const startIndex = startIndices[index];
const endIndex = startIndices[index + 1] || vertexCount;
let result;

if (nested) {
result = new Array(endIndex - startIndex);
for (let i = startIndex; i < endIndex; i++) {
const sourceIndex = i * elementStride + elementOffset;
target = new Array(size);
for (let j = 0; j < size; j++) {
target[j] = typedArray[sourceIndex + j];
}
result[i - startIndex] = target;
}
} else {
result = new typedArray.constructor((endIndex - startIndex) * size);
let targetIndex = 0;
for (let i = startIndex; i < endIndex; i++) {
const sourceIndex = i * elementStride + elementOffset;
for (let j = 0; j < size; j++) {
result[targetIndex++] = typedArray[sourceIndex + j];
}
}
return result;
}
const sourceIndex = index * elementStride + elementOffset;
for (let j = 0; j < size; j++) {
target[j] = typedArray[sourceIndex + j];
}
return target;

return result;
};
}
14 changes: 12 additions & 2 deletions test/modules/core/utils/iterable-utils.spec.js
Expand Up @@ -133,7 +133,7 @@ test('getAccessorFromBuffer', t => {
input: {
value: new Float32Array([1, 1, 0, 2, 2, 0, 3, 3, 0]),
size: 3,
vertexStarts: [0, 2]
startIndices: [0, 2]
},
output: [[1, 1, 0, 2, 2, 0], [3, 3, 0]]
},
Expand All @@ -144,9 +144,19 @@ test('getAccessorFromBuffer', t => {
size: 2,
stride: 12,
offset: 12,
vertexStarts: [0, 2]
startIndices: [0, 2]
},
output: [[1, 1, 2, 2], [3, 3]]
},
{
title: 'variable-width buffer nested',
input: {
value: new Float32Array([1, 1, 0, 2, 2, 0, 3, 3, 0]),
size: 3,
startIndices: [0, 2],
nested: true
},
output: [[[1, 1, 0], [2, 2, 0]], [[3, 3, 0]]]
}
];

Expand Down

0 comments on commit 24285eb

Please sign in to comment.