UNPKG

polygonjs-engine

Version:

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

88 lines (76 loc) 3.1 kB
import {CorePoint} from '../Point'; import {BufferGeometry} from 'three/src/core/BufferGeometry'; import {CoreGeometry} from '../Geometry'; import {Float32BufferAttribute} from 'three/src/core/BufferAttribute'; import {Vector3} from 'three/src/math/Vector3'; import {ArrayUtils} from '../../ArrayUtils'; import {PolyDictionary} from '../../../types/GlobalTypes'; export abstract class CoreGeometryBuilderBase { from_points(points: CorePoint[]) { points = this._filter_points(points); const geometry = new BufferGeometry(); const core_geometry = new CoreGeometry(geometry); const first_point = points[0]; if (first_point != null) { const old_geometry = first_point.geometry(); const old_core_geometry = first_point.core_geometry(); // index const new_index_by_old_index: PolyDictionary<number> = {}; for (let i = 0; i < points.length; i++) { new_index_by_old_index[points[i].index()] = i; } const indices = this._indices_from_points(new_index_by_old_index, old_geometry); if (indices) { geometry.setIndex(indices); } // attributes const {attributes} = old_geometry; // const new_attributes = {} for (let attribute_name of Object.keys(attributes)) { const attrib_values = old_core_geometry.userDataAttribs()[attribute_name]; const is_attrib_indexed = attrib_values != null; if (is_attrib_indexed) { const new_values: string[] = ArrayUtils.uniq( points.map((point) => point.indexedAttribValue(attribute_name)) ); const new_index_by_value: PolyDictionary<number> = {}; new_values.forEach((new_value, i) => (new_index_by_value[new_value] = i)); core_geometry.userDataAttribs()[attribute_name] = new_values; // const old_attrib = old_geometry.getAttribute(attribute_name) // const old_attrib_array = old_attrib.array const new_attrib_indices = []; for (let point of points) { // const old_index = old_attrib_array[point.index()] const new_index = new_index_by_value[point.indexedAttribValue(attribute_name)]; new_attrib_indices.push(new_index); } geometry.setAttribute(attribute_name, new Float32BufferAttribute(new_attrib_indices, 1)); } else { const attrib_size = attributes[attribute_name].itemSize; const values: number[] = new Array(points.length * attrib_size); switch (attrib_size) { case 1: for (let i = 0; i < points.length; i++) { values[i] = points[i].attribValue(attribute_name) as number; } break; default: let value: Vector3; for (let i = 0; i < points.length; i++) { value = points[i].attribValue(attribute_name) as Vector3; value.toArray(values, i * attrib_size); } break; } geometry.setAttribute(attribute_name, new Float32BufferAttribute(values, attrib_size)); } } } return geometry; } protected abstract _filter_points(points: CorePoint[]): CorePoint[]; protected abstract _indices_from_points( new_index_by_old_index: PolyDictionary<number>, old_geometry: BufferGeometry ): number[] | undefined; }