UNPKG

@polygonjs/polygonjs

Version:

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

114 lines (99 loc) 3.34 kB
import {BufferGeometry, Mesh, Vector3} from 'three'; import {CoreGeometryBuilderBase} from './_Base'; import {BaseCorePoint} from '../../../entities/point/CorePoint'; import {PolyDictionary} from '../../../../../types/GlobalTypes'; import {CoreObjectType, ObjectBuilder, ObjectContent} from '../../../ObjectContent'; import {CoreEntity} from '../../../CoreEntity'; import type {ThreejsPrimitiveTriangle} from '../ThreejsPrimitiveTriangle'; export class CoreGeometryBuilderMesh extends CoreGeometryBuilderBase { protected _filterPoints(points: BaseCorePoint[]): BaseCorePoint[] { // ensures we only keep points that form a full face. // if a single point from a face is discarded, we remove all 3 const firstPoint = points[0]; if (!firstPoint) { return []; } const geometry = firstPoint.geometry(); if (!geometry) { return []; } const indices = geometry.getIndex()?.array; if (!indices) { return []; } const points_by_index: PolyDictionary<BaseCorePoint> = {}; for (const point of points) { points_by_index[point.index()] = point; } const filteredPoints: BaseCorePoint[] = []; const index_length = indices.length; let pt0: BaseCorePoint; let pt1: BaseCorePoint; let pt2: BaseCorePoint; for (let i = 0; i < index_length; i += 3) { pt0 = points_by_index[indices[i + 0]]; pt1 = points_by_index[indices[i + 1]]; pt2 = points_by_index[indices[i + 2]]; if (pt0 && pt1 && pt2) { filteredPoints.push(pt0); filteredPoints.push(pt1); filteredPoints.push(pt2); } } return filteredPoints; } protected _indicesFromPoints(new_index_by_old_index: PolyDictionary<number>, old_geometry: BufferGeometry) { const index_attrib = old_geometry.index; if (index_attrib != null) { const old_indices = index_attrib.array; const new_indices: number[] = []; let old_index0: number; let old_index1: number; let old_index2: number; let new_index0: number; let new_index1: number; let new_index2: number; for (let i = 0; i < old_indices.length; i += 3) { old_index0 = old_indices[i + 0]; old_index1 = old_indices[i + 1]; old_index2 = old_indices[i + 2]; new_index0 = new_index_by_old_index[old_index0]; new_index1 = new_index_by_old_index[old_index1]; new_index2 = new_index_by_old_index[old_index2]; if (new_index0 != null && new_index1 != null && new_index2 != null) { new_indices.push(new_index0); new_indices.push(new_index1); new_indices.push(new_index2); } } return new_indices; } } } const _v3 = new Vector3(); const STRIDE = 3; export const threeMeshFromPrimitives: ObjectBuilder<CoreObjectType.THREEJS> = ( object: ObjectContent<CoreObjectType.THREEJS>, entities: CoreEntity[] ) => { const mesh = object as ObjectContent<CoreObjectType.THREEJS> as Mesh; const geometry = mesh.geometry; if (!geometry) { return undefined; } const oldIndex = geometry.getIndex(); if (!oldIndex) { return undefined; } const oldIndexArray = oldIndex.array; const primitives = entities as ThreejsPrimitiveTriangle[]; const newIndices = new Array(primitives.length * STRIDE); let i = 0; for (const primitive of primitives) { _v3.fromArray(oldIndexArray, primitive.index() * STRIDE); _v3.toArray(newIndices, i * STRIDE); i++; } geometry.setIndex(newIndices); return mesh; };