2021-08-02 11:31:59 -04:00
|
|
|
"use strict";
|
|
|
|
const Cesium = require("cesium");
|
2017-03-13 15:28:51 -04:00
|
|
|
|
2019-02-05 20:59:09 -05:00
|
|
|
const ComponentDatatype = Cesium.ComponentDatatype;
|
2017-03-13 15:28:51 -04:00
|
|
|
|
|
|
|
module.exports = ArrayStorage;
|
|
|
|
|
2019-02-05 20:59:09 -05:00
|
|
|
const initialLength = 1024; // 2^10
|
|
|
|
const doublingThreshold = 33554432; // 2^25 (~134 MB for a Float32Array)
|
|
|
|
const fixedExpansionLength = 33554432; // 2^25 (~134 MB for a Float32Array)
|
2017-03-13 15:28:51 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Provides expandable typed array storage for geometry data. This is preferable to JS arrays which are
|
|
|
|
* stored with double precision. The resizing mechanism is similar to std::vector.
|
|
|
|
*
|
|
|
|
* @param {ComponentDatatype} componentDatatype The data type.
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function ArrayStorage(componentDatatype) {
|
2021-08-02 11:31:59 -04:00
|
|
|
this.componentDatatype = componentDatatype;
|
|
|
|
this.typedArray = ComponentDatatype.createTypedArray(componentDatatype, 0);
|
|
|
|
this.length = 0;
|
2017-03-13 15:28:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function resize(storage, length) {
|
2021-08-02 11:31:59 -04:00
|
|
|
const typedArray = ComponentDatatype.createTypedArray(
|
|
|
|
storage.componentDatatype,
|
|
|
|
length
|
|
|
|
);
|
|
|
|
typedArray.set(storage.typedArray);
|
|
|
|
storage.typedArray = typedArray;
|
2017-03-13 15:28:51 -04:00
|
|
|
}
|
|
|
|
|
2021-08-02 11:31:59 -04:00
|
|
|
ArrayStorage.prototype.push = function (value) {
|
|
|
|
const length = this.length;
|
|
|
|
const typedArrayLength = this.typedArray.length;
|
2017-03-13 15:28:51 -04:00
|
|
|
|
2021-08-02 11:31:59 -04:00
|
|
|
if (length === 0) {
|
|
|
|
resize(this, initialLength);
|
|
|
|
} else if (length === typedArrayLength) {
|
|
|
|
if (length < doublingThreshold) {
|
|
|
|
resize(this, typedArrayLength * 2);
|
|
|
|
} else {
|
|
|
|
resize(this, typedArrayLength + fixedExpansionLength);
|
2017-03-13 15:28:51 -04:00
|
|
|
}
|
2021-08-02 11:31:59 -04:00
|
|
|
}
|
2017-03-13 15:28:51 -04:00
|
|
|
|
2021-08-02 11:31:59 -04:00
|
|
|
this.typedArray[this.length++] = value;
|
2017-03-13 15:28:51 -04:00
|
|
|
};
|
|
|
|
|
2021-08-02 11:31:59 -04:00
|
|
|
ArrayStorage.prototype.get = function (index) {
|
|
|
|
return this.typedArray[index];
|
2017-03-13 15:28:51 -04:00
|
|
|
};
|
|
|
|
|
2019-02-05 20:59:09 -05:00
|
|
|
const sizeOfUint16 = 2;
|
|
|
|
const sizeOfUint32 = 4;
|
|
|
|
const sizeOfFloat = 4;
|
2017-03-13 15:28:51 -04:00
|
|
|
|
2021-08-02 11:31:59 -04:00
|
|
|
ArrayStorage.prototype.toUint16Buffer = function () {
|
|
|
|
const length = this.length;
|
|
|
|
const typedArray = this.typedArray;
|
|
|
|
const paddedLength = length + (length % 2 === 0 ? 0 : 1); // Round to next multiple of 2
|
|
|
|
const buffer = Buffer.alloc(paddedLength * sizeOfUint16);
|
|
|
|
for (let i = 0; i < length; ++i) {
|
|
|
|
buffer.writeUInt16LE(typedArray[i], i * sizeOfUint16);
|
|
|
|
}
|
|
|
|
return buffer;
|
2017-03-13 15:28:51 -04:00
|
|
|
};
|
|
|
|
|
2021-08-02 11:31:59 -04:00
|
|
|
ArrayStorage.prototype.toUint32Buffer = function () {
|
|
|
|
const length = this.length;
|
|
|
|
const typedArray = this.typedArray;
|
|
|
|
const buffer = Buffer.alloc(length * sizeOfUint32);
|
|
|
|
for (let i = 0; i < length; ++i) {
|
|
|
|
buffer.writeUInt32LE(typedArray[i], i * sizeOfUint32);
|
|
|
|
}
|
|
|
|
return buffer;
|
2017-03-13 15:28:51 -04:00
|
|
|
};
|
|
|
|
|
2021-08-02 11:31:59 -04:00
|
|
|
ArrayStorage.prototype.toFloatBuffer = function () {
|
|
|
|
const length = this.length;
|
|
|
|
const typedArray = this.typedArray;
|
|
|
|
const buffer = Buffer.alloc(length * sizeOfFloat);
|
|
|
|
for (let i = 0; i < length; ++i) {
|
|
|
|
buffer.writeFloatLE(typedArray[i], i * sizeOfFloat);
|
|
|
|
}
|
|
|
|
return buffer;
|
2017-03-13 15:28:51 -04:00
|
|
|
};
|
|
|
|
|
2021-08-02 11:31:59 -04:00
|
|
|
ArrayStorage.prototype.getMinMax = function (components) {
|
|
|
|
const length = this.length;
|
|
|
|
const typedArray = this.typedArray;
|
|
|
|
const count = length / components;
|
|
|
|
const min = new Array(components).fill(Number.POSITIVE_INFINITY);
|
|
|
|
const max = new Array(components).fill(Number.NEGATIVE_INFINITY);
|
|
|
|
for (let i = 0; i < count; ++i) {
|
|
|
|
for (let j = 0; j < components; ++j) {
|
|
|
|
const index = i * components + j;
|
|
|
|
const value = typedArray[index];
|
|
|
|
min[j] = Math.min(min[j], value);
|
|
|
|
max[j] = Math.max(max[j], value);
|
2017-03-13 15:28:51 -04:00
|
|
|
}
|
2021-08-02 11:31:59 -04:00
|
|
|
}
|
|
|
|
return {
|
|
|
|
min: min,
|
|
|
|
max: max,
|
|
|
|
};
|
2017-03-13 15:28:51 -04:00
|
|
|
};
|