@giro3d/giro3d
Version:
A JS/WebGL framework for 3D geospatial data visualization
66 lines (52 loc) • 1.74 kB
text/typescript
/*
* Copyright (c) 2015-2018, IGN France.
* Copyright (c) 2018-2026, Giro3D team.
* SPDX-License-Identifier: MIT
*/
import type { Box3 } from 'three';
import { createReader, getTypedArray, type PotreePointCloudAttribute } from './attributes';
export interface BufferAttributeDescriptor {
array: ArrayBuffer;
dimension: number;
normalized: boolean;
}
function readAttribute(
attribute: PotreePointCloudAttribute,
view: DataView,
pointByteSize: number,
pointCount: number,
): BufferAttributeDescriptor {
const array = getTypedArray(attribute.type, attribute.size, attribute.dimension, pointCount);
const read = createReader(attribute, pointByteSize);
for (let i = 0; i < pointCount; i++) {
read(view, i, array);
}
return {
array: array.buffer,
dimension: attribute.dimension,
normalized: attribute.normalized,
};
}
export interface ParseResult {
positionBuffer: BufferAttributeDescriptor;
attributeBuffers: BufferAttributeDescriptor[];
localBoundingBox?: Box3;
}
export function readBinFile(
buffer: ArrayBuffer,
pointByteSize: number,
positionAttribute: PotreePointCloudAttribute,
attributes: PotreePointCloudAttribute[],
): ParseResult {
const view = new DataView(buffer);
// Format: X1,Y1,Z1,R1,G1,B1,A1,[...],XN,YN,ZN,RN,GN,BN,AN
const pointCount = Math.floor(buffer.byteLength / pointByteSize);
const positionBuffer = readAttribute(positionAttribute, view, pointByteSize, pointCount);
const attributeBuffers = attributes.map(attribute =>
readAttribute(attribute, view, pointByteSize, pointCount),
);
return {
positionBuffer,
attributeBuffers,
};
}