UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

87 lines (86 loc) 3.15 kB
"use strict"; import { arrayIsEqual } from "../../../../ArrayUtils"; import { QuadGeometry } from "../QuadGeometry"; import { QuadObject } from "../QuadObject"; import { QuadPoint } from "../QuadPoint"; import { QuadVertex } from "../QuadVertex"; import { QuadPrimitive } from "../QuadPrimitive"; import { BufferAttribute } from "three"; function _attributesAreTheSame(quadObjects, entityClass) { const firstGeometryPointAttributeNames = entityClass.attributeNames(quadObjects[0]); for (const quadObject of quadObjects) { const attribNames = entityClass.attributeNames(quadObject); if (!arrayIsEqual(firstGeometryPointAttributeNames, attribNames)) { return false; } } return true; } function _mergePointAttributes(quadObjects, target) { const attributeNames = QuadPoint.attributeNames(quadObjects[0]); let i = 0; for (const attributeName of attributeNames) { _mergePointAttribute(quadObjects, attributeName, i == 0, target); i++; } } function _mergePointAttribute(quadObjects, attributeName, addIndex, target) { const firstAttribute = QuadPoint.attribute(quadObjects[0], attributeName); const itemSize = firstAttribute.itemSize; const values = []; const indices = []; let indexOffset = 0; for (const object of quadObjects) { const attribute = QuadPoint.attribute(object, attributeName); const array = attribute.array; for (const item of array) { values.push(item); } if (addIndex) { const index = object.geometry.index; for (const indexItem of index) { indices.push(indexItem + indexOffset); } } indexOffset += attribute.count; } target.setAttribute(attributeName, new BufferAttribute(new Float32Array(values), itemSize)); if (addIndex) { target.setIndex(indices); } } function _mergeAttributes(quadObjects, entityClass, target) { const attributeNames = entityClass.attributeNames(quadObjects[0]); for (const attributeName of attributeNames) { _mergeAttribute(quadObjects, attributeName, entityClass, target); } } function _mergeAttribute(quadObjects, attributeName, entityClass, target) { const firstAttribute = entityClass.attribute(quadObjects[0], attributeName); const { itemSize, isString } = firstAttribute; const values = []; for (const object of quadObjects) { const attribute2 = entityClass.attribute(object, attributeName); const array = attribute2.array; for (const item of array) { values.push(item); } } const dummyObject = new QuadObject(target); const attribute = { isString, array: values, itemSize }; entityClass.addAttribute(dummyObject, attributeName, attribute); } export function quadGeomeryMerge(quadObjects) { if (!(_attributesAreTheSame(quadObjects, QuadPoint) && _attributesAreTheSame(quadObjects, QuadVertex) && _attributesAreTheSame(quadObjects, QuadPrimitive))) { return; } const mergedGeometry = new QuadGeometry(); _mergePointAttributes(quadObjects, mergedGeometry); _mergeAttributes(quadObjects, QuadPrimitive, mergedGeometry); _mergeAttributes(quadObjects, QuadVertex, mergedGeometry); return mergedGeometry; }