@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
87 lines (86 loc) • 3.15 kB
JavaScript
"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;
}