UNPKG

@polygonjs/polygonjs

Version:

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

99 lines (98 loc) 4.07 kB
"use strict"; import { BufferGeometry, Mesh, Vector4, Vector3, BufferAttribute } from "three"; import { ObjectType } from "../../../Constant"; import { Attribute } from "../../../Attribute"; import { DEFAULT_MATERIALS } from "../../../Constant"; import { stringMatchMask } from "../../../../String"; import { QuadPrimitive } from "../QuadPrimitive"; import { ThreejsPrimitiveTriangle } from "../../three/ThreejsPrimitiveTriangle"; import { prepareObject } from "./QuadToObject3DCommon"; const _v4 = new Vector4(); const _p0 = new Vector3(); const _p1 = new Vector3(); const _p2 = new Vector3(); const _p3 = new Vector3(); export function quadToMesh(quadObject, options) { const quadGeometry = quadObject.geometry; const quadsCount = quadGeometry.quadsCount(); const geometry = new BufferGeometry(); const mesh = new Mesh(geometry, DEFAULT_MATERIALS[ObjectType.MESH]); const srcPositions = quadGeometry.attributes[Attribute.POSITION].array; const indices = quadGeometry.index; const newIndices = new Array(quadsCount * 6); if (options.splitQuads) { const newPositions = []; for (let i = 0; i < quadsCount; i++) { _v4.fromArray(indices, i * 4); _p0.fromArray(srcPositions, _v4.x * 3); _p1.fromArray(srcPositions, _v4.y * 3); _p2.fromArray(srcPositions, _v4.z * 3); _p3.fromArray(srcPositions, _v4.w * 3); newPositions.push(_p0.x, _p0.y, _p0.z); newPositions.push(_p1.x, _p1.y, _p1.z); newPositions.push(_p2.x, _p2.y, _p2.z); newPositions.push(_p3.x, _p3.y, _p3.z); const i6 = i * 6; const i4 = i * 4; newIndices[i6 + 0] = i4 + 0; newIndices[i6 + 1] = i4 + 1; newIndices[i6 + 2] = i4 + 2; newIndices[i6 + 3] = i4 + 0; newIndices[i6 + 4] = i4 + 2; newIndices[i6 + 5] = i4 + 3; } geometry.setAttribute(Attribute.POSITION, new BufferAttribute(new Float32Array(newPositions), 3)); } else { for (let i = 0; i < quadsCount; i++) { _v4.fromArray(indices, i * 4); const i6 = i * 6; newIndices[i6 + 0] = _v4.x; newIndices[i6 + 1] = _v4.y; newIndices[i6 + 2] = _v4.z; newIndices[i6 + 3] = _v4.x; newIndices[i6 + 4] = _v4.z; newIndices[i6 + 5] = _v4.w; } geometry.setAttribute(Attribute.POSITION, new BufferAttribute(new Float32Array(srcPositions), 3)); } geometry.setIndex(newIndices); const pointAttributeNames = Object.keys(quadGeometry.attributes).filter( (attributeName) => stringMatchMask(attributeName, options.pointAttributes) && attributeName != Attribute.POSITION ); for (const attribName of pointAttributeNames) { const attribute = quadGeometry.attributes[attribName]; const values = attribute.array; geometry.setAttribute(attribName, new BufferAttribute(new Float32Array(values), attribute.itemSize)); } const normalAttribute = geometry.attributes[Attribute.NORMAL]; if (!normalAttribute) { geometry.computeVertexNormals(); } const primitiveAttributes = QuadPrimitive.attributesFromGeometry(quadGeometry); if (primitiveAttributes) { const primitiveAttributeNames = Object.keys(primitiveAttributes).filter( (attributeName) => stringMatchMask(attributeName, options.primitiveAttributes) ); for (const primitiveAttributeName of primitiveAttributeNames) { const srcAttribute = primitiveAttributes[primitiveAttributeName]; const destPrimitivesCount = quadsCount * 2; const destAttribute = { itemSize: srcAttribute.itemSize, isString: srcAttribute.isString, array: new Array(destPrimitivesCount * srcAttribute.itemSize) }; ThreejsPrimitiveTriangle.addAttribute(mesh, primitiveAttributeName, destAttribute); const srcArray = srcAttribute.array; const destArray = destAttribute.array; const srcArraySize = srcArray.length; let j = 0; for (let i = 0; i < srcArraySize; i++) { destArray[j] = srcArray[i]; destArray[j + 1] = srcArray[i]; j += 2; } } } prepareObject(mesh, { shadow: true }); return mesh; }