UNPKG

polygonjs-engine

Version:

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

95 lines (94 loc) 3.23 kB
import {BaseSopOperation} from "./_Base"; import {objectTypeFromConstructor} from "../../geometry/Constant"; import {MapUtils as MapUtils2} from "../../MapUtils"; import {CoreGeometry} from "../../geometry/Geometry"; import {Group as Group3} from "three/src/objects/Group"; import {InputCloneMode as InputCloneMode2} from "../../../engine/poly/InputCloneMode"; export class MergeSopOperation extends BaseSopOperation { static type() { return "merge"; } cook(input_contents, params) { let all_objects = []; for (let input_core_group of input_contents) { if (input_core_group) { const objects = input_core_group.objects(); if (params.compact) { for (let object of objects) { object.traverse((child) => { all_objects.push(child); }); } } else { for (let object of input_core_group.objects()) { all_objects.push(object); } } } } if (params.compact) { all_objects = this._make_compact(all_objects); } for (let object of all_objects) { object.traverse((o) => { o.matrixAutoUpdate = false; }); } return this.create_core_group_from_objects(all_objects); } _make_compact(all_objects) { const materials_by_object_type = new Map(); const objects_by_type = new Map(); const ordered_object_types = []; for (let object of all_objects) { object.traverse((object3d) => { if (object3d instanceof Group3) { return; } const object2 = object3d; if (object2.geometry) { const object_type = objectTypeFromConstructor(object2.constructor); if (!ordered_object_types.includes(object_type)) { ordered_object_types.push(object_type); } if (object_type) { const found_mat = materials_by_object_type.get(object_type); if (!found_mat) { materials_by_object_type.set(object_type, object2.material); } MapUtils2.push_on_array_at_entry(objects_by_type, object_type, object2); } } }); } const merged_objects = []; ordered_object_types.forEach((object_type) => { const objects = objects_by_type.get(object_type); if (objects) { const geometries = []; for (let object of objects) { const geometry = object.geometry; geometry.applyMatrix4(object.matrix); geometries.push(geometry); } try { const merged_geometry = CoreGeometry.merge_geometries(geometries); if (merged_geometry) { const material = materials_by_object_type.get(object_type); const object = this.create_object(merged_geometry, object_type, material); merged_objects.push(object); } else { this.states?.error.set("merge failed, check that input geometries have the same attributes"); } } catch (e) { this.states?.error.set(e); } } }); return merged_objects; } } MergeSopOperation.DEFAULT_PARAMS = { compact: true }; MergeSopOperation.INPUT_CLONED_STATE = InputCloneMode2.FROM_NODE;