UNPKG

polygonjs-engine

Version:

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

323 lines (322 loc) 8.83 kB
import {Vector3 as Vector32} from "three/src/math/Vector3"; import {Group as Group2} from "three/src/objects/Group"; import {Box3 as Box32} from "three/src/math/Box3"; import {CoreObject} from "./Object"; import {CoreGeometry} from "./Geometry"; import {CoreAttribute} from "./Attribute"; import {CoreString} from "../String"; import {CoreConstant, objectTypeFromConstructor} from "./Constant"; import {CoreType} from "../Type"; import {ArrayUtils as ArrayUtils2} from "../ArrayUtils"; export class CoreGroup { constructor() { this._objects = []; this._objects_with_geo = []; this.touch(); } timestamp() { return this._timestamp; } touch() { this._timestamp = performance.now(); this.reset(); } reset() { this._bounding_box = void 0; this._core_geometries = void 0; this._core_objects = void 0; } clone() { const core_group = new CoreGroup(); if (this._objects) { const objects = []; for (let object of this._objects) { objects.push(CoreObject.clone(object)); } core_group.setObjects(objects); } return core_group; } setObjects(objects) { this._objects = objects; this._objects_with_geo = objects.filter((obj) => obj.geometry != null); this.touch(); } objects() { return this._objects; } objectsWithGeo() { return this._objects_with_geo; } coreObjects() { return this._core_objects = this._core_objects || this._create_core_objects(); } _create_core_objects() { if (this._objects) { return this._objects.map((object, i) => new CoreObject(object, i)); } return []; } objectsData() { if (this._objects) { return this._objects.map((object) => this._objectData(object)); } return []; } _objectData(object) { let points_count = 0; if (object.geometry) { points_count = CoreGeometry.pointsCount(object.geometry); } return { type: objectTypeFromConstructor(object.constructor), name: object.name, children_count: object.children.length, points_count }; } geometries() { const list = []; for (let core_object of this.coreObjects()) { const geometry = core_object.object().geometry; if (geometry) { list.push(geometry); } } return list; } coreGeometries() { return this._core_geometries = this._core_geometries || this._createCoreGeometries(); } _createCoreGeometries() { const list = []; for (let geometry of this.geometries()) { list.push(new CoreGeometry(geometry)); } return list; } static geometryFromObject(object) { if (object.isMesh || object.isLine || object.isPoints) { return object.geometry; } return null; } faces() { return this.coreGeometries().map((g) => g.faces()).flat(); } points() { return this.coreGeometries().map((g) => g.points()).flat(); } pointsCount() { return ArrayUtils2.sum(this.coreGeometries().map((g) => g.pointsCount())); } totalPointsCount() { if (this._objects) { let sum = 0; for (let object of this._objects) { object.traverse((object2) => { const geometry = object2.geometry; if (geometry) { sum += CoreGeometry.pointsCount(geometry); } }); } return sum; } else { return 0; } } pointsFromGroup(group) { if (group) { const indices = CoreString.indices(group); const points = this.points(); return ArrayUtils2.compact(indices.map((i) => points[i])); } else { return this.points(); } } static _fromObjects(objects) { const core_group = new CoreGroup(); core_group.setObjects(objects); return core_group; } objectsFromGroup(group_name) { return this.coreObjectsFromGroup(group_name).map((co) => co.object()); } coreObjectsFromGroup(group_name) { group_name = group_name.trim(); if (group_name !== "") { const index = parseInt(group_name); if (!CoreType.isNaN(index)) { return ArrayUtils2.compact([this.coreObjects()[index]]); } else { return this.coreObjects().filter((core_object) => { return CoreString.matchMask(group_name, core_object.name()); }); } } else { return this.coreObjects(); } } boundingBox() { return this._bounding_box = this._bounding_box || this._compute_bounding_box(); } center() { const center = new Vector32(); this.boundingBox().getCenter(center); return center; } size() { const size = new Vector32(); this.boundingBox().getSize(size); return size; } _compute_bounding_box() { let bbox; if (this._objects) { for (let object of this._objects) { const geometry = object.geometry; if (geometry) { geometry.computeBoundingBox(); if (bbox) { bbox.expandByObject(object); } else { if (geometry.boundingBox) { bbox = geometry.boundingBox.clone(); } } } } } bbox = bbox || new Box32(new Vector32(-1, -1, -1), new Vector32(1, 1, 1)); return bbox; } computeVertexNormals() { for (let object of this.coreObjects()) { object.computeVertexNormals(); } } hasAttrib(name) { let first_geometry; if ((first_geometry = this.coreGeometries()[0]) != null) { return first_geometry.hasAttrib(name); } else { return false; } } attribType(name) { const first_core_geometry = this.coreGeometries()[0]; if (first_core_geometry != null) { return first_core_geometry.attribType(name); } else { return null; } } objectAttribType(name) { const first_core_object = this.coreObjects()[0]; if (first_core_object != null) { return first_core_object.attribType(name); } else { return null; } } renameAttrib(old_name, new_name, attrib_class) { switch (attrib_class) { case CoreConstant.ATTRIB_CLASS.VERTEX: if (this.hasAttrib(old_name)) { if (this._objects) { for (let object of this._objects) { object.traverse((child) => { const geometry = CoreGroup.geometryFromObject(child); if (geometry) { const core_geometry = new CoreGeometry(geometry); core_geometry.renameAttrib(old_name, new_name); } }); } } } break; case CoreConstant.ATTRIB_CLASS.OBJECT: if (this.hasAttrib(old_name)) { if (this._objects) { for (let object of this._objects) { object.traverse((child) => { const core_object = new CoreObject(child, 0); core_object.renameAttrib(old_name, new_name); }); } } } break; } } attribNames() { let first_geometry; if ((first_geometry = this.coreGeometries()[0]) != null) { return first_geometry.attribNames(); } else { return []; } } objectAttribNames() { let first_object; if ((first_object = this.coreObjects()[0]) != null) { return first_object.attribNames(); } else { return []; } } attribNamesMatchingMask(masks_string) { const masks = CoreString.attribNames(masks_string); const matching_attrib_names = []; for (let attrib_name of this.attribNames()) { for (let mask of masks) { if (CoreString.matchMask(attrib_name, mask)) { matching_attrib_names.push(attrib_name); } } } return ArrayUtils2.uniq(matching_attrib_names); } attribSizes() { let first_geometry; if ((first_geometry = this.coreGeometries()[0]) != null) { return first_geometry.attribSizes(); } else { return {}; } } objectAttribSizes() { let first_object; if ((first_object = this.coreObjects()[0]) != null) { return first_object.attribSizes(); } else { return {}; } } attribSize(attrib_name) { let first_geometry; if ((first_geometry = this.coreGeometries()[0]) != null) { return first_geometry.attribSize(attrib_name); } else { return 0; } } addNumericVertexAttrib(name, size, default_value) { if (default_value == null) { default_value = CoreAttribute.default_value(size); } for (let core_geometry of this.coreGeometries()) { core_geometry.addNumericAttrib(name, size, default_value); } } static clone(src_group) { const new_group = new Group2(); src_group.children.forEach((src_object) => { const new_object = CoreObject.clone(src_object); new_group.add(new_object); }); return new_group; } }