loaders.gl
Version:
Framework-independent loaders for 3D graphics formats
192 lines (158 loc) • 6.19 kB
JavaScript
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
/**
* Flattens a nested array into a single level array,
* or a single value into an array with one value
* @example flatten([[1, [2]], [3], 4]) => [1, 2, 3, 4]
* @example flatten(1) => [1]
* @param {Array} array The array to flatten.
* @param {Function} filter= - Optional predicate called on each `value` to
* determine if it should be included (pushed onto) the resulting array.
* @param {Function} map= - Optional transform applied to each array elements.
* @param {Array} result=[] - Optional array to push value into
* @return {Array} Returns the new flattened array (new array or `result` if provided)
*/
export function flatten(array) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$filter = _ref.filter,
filter = _ref$filter === void 0 ? function () {
return true;
} : _ref$filter,
_ref$map = _ref.map,
map = _ref$map === void 0 ? function (x) {
return x;
} : _ref$map,
_ref$result = _ref.result,
result = _ref$result === void 0 ? [] : _ref$result;
// Wrap single object in array
if (!Array.isArray(array)) {
return filter(array) ? [map(array)] : [];
} // Deep flatten and filter the array
return flattenArray(array, filter, map, result);
} // Deep flattens an array. Helper to `flatten`, see its parameters
function flattenArray(array, filter, map, result) {
var index = -1;
while (++index < array.length) {
var value = array[index];
if (Array.isArray(value)) {
flattenArray(value, filter, map, result);
} else if (filter(value)) {
result.push(map(value));
}
}
return result;
}
export function countVertices(nestedArray) {
var dimensions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3;
var nestedCount = 0;
var localCount = 0;
var index = -1;
while (++index < nestedArray.length) {
var value = nestedArray[index];
if (Array.isArray(value) || ArrayBuffer.isView(value)) {
nestedCount += countVertices(value);
} else {
localCount++;
}
}
return nestedCount + (nestedCount === 0 && localCount < dimensions ? dimensions : localCount);
} // Flattens nested array of vertices, padding third coordinate as needed
export function flattenVertices(nestedArray) {
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref2$result = _ref2.result,
result = _ref2$result === void 0 ? [] : _ref2$result,
_ref2$dimensions = _ref2.dimensions,
dimensions = _ref2$dimensions === void 0 ? 3 : _ref2$dimensions;
var index = -1;
var vertexLength = 0;
while (++index < nestedArray.length) {
var value = nestedArray[index];
if (Array.isArray(value) || ArrayBuffer.isView(value)) {
flattenVertices(value, {
result: result,
dimensions: dimensions
});
} else {
// eslint-disable-next-line
if (vertexLength < dimensions) {
result.push(value);
vertexLength++;
}
}
} // Add a third coordinate if needed
if (vertexLength > 0 && vertexLength < dimensions) {
result.push(0);
}
return result;
}
export function flattenToTypedArray(nestedArray) {
var ArrayType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Float32Array;
if (nestedArray.length === 0) {
return new Float32Array(0);
}
if (!checkVertices(nestedArray)) {
return null;
}
var count = countVertices(nestedArray);
var typedArray = new ArrayType(count);
flattenVerticesInPlace(nestedArray, typedArray);
return typedArray;
}
function checkVertices(nestedArray) {
var predicate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Number.isFinite;
var index = -1;
while (++index < nestedArray.length) {
var value = nestedArray[index];
if (Array.isArray(value) || ArrayBuffer.isView(value)) {
if (!checkVertices(value, predicate)) {
return false;
}
} else if (!predicate(value)) {
return false;
}
}
return true;
}
function flattenVerticesInPlace(nestedArray, result) {
var dimensions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3;
flattenVerticesInPlaceRecursive(nestedArray, result, dimensions, 0);
return result;
} // Flattens nested array of vertices, padding third coordinate as needed
function flattenVerticesInPlaceRecursive(nestedArray, result, dimensions, insert) {
var index = -1;
var vertexLength = 0;
while (++index < nestedArray.length) {
var value = nestedArray[index];
if (Array.isArray(value) || ArrayBuffer.isView(value)) {
insert = flattenVerticesInPlaceRecursive(value, result, dimensions, insert);
} else {
// eslint-disable-next-line
if (vertexLength < dimensions) {
result[insert++] = value;
vertexLength++;
}
}
} // Add a third coordinate if needed
if (vertexLength > 0 && vertexLength < dimensions) {
result[insert++] = 0;
}
return insert;
}
//# sourceMappingURL=flatten.js.map