UNPKG

@polygonjs/polygonjs

Version:

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

213 lines (212 loc) 6.06 kB
"use strict"; import { Float32BufferAttribute, Int32BufferAttribute, InstancedBufferAttribute } from "three"; import { CorePoint } from "../../entities/point/CorePoint"; import { Attribute } from "../../Attribute"; import { objectCloneDeep } from "../../../ObjectUtils"; import { markedAsInstance } from "../../GeometryUtils"; import { pointsCountFromBufferGeometry, positionAttributeNameFromBufferGeometry } from "./CoreThreejsPointUtils"; import { attributeNumericValues } from "../../entities/utils/Common"; import { ThreejsVertex } from "./ThreejsVertex"; import { pointsCountFromObject } from "../../entities/point/CorePointUtils"; const INDEX_ATTRIB_VALUES = "indexedAttribValues"; const target = { attributeAdded: false, values: [] }; export class ThreejsPoint extends CorePoint { constructor(object, index) { super(object, index); this._updateGeometry(); } setIndex(index, object) { this._index = index; if (object) { this._object = object; this._updateGeometry(); } return this; } _updateGeometry() { const geometry = this._object.geometry; if (geometry) { this._geometry = geometry; } } geometry() { return this._geometry; } static addAttribute(object, attribName, attribute) { const geometry = object.geometry; if (!geometry) { return; } geometry.setAttribute(attribName, attribute); } static attributes(object) { const geometry = object.geometry; if (!geometry) { return; } return geometry.attributes; } static entitiesCount(object) { const geometry = object.geometry; if (!geometry) { return 0; } return pointsCountFromBufferGeometry(geometry); } static positionAttributeName(object) { const geometry = object.geometry; if (!geometry) { return null; } return positionAttributeNameFromBufferGeometry(geometry); } static position(object, index, target2) { const geometry = object.geometry; if (!geometry) { return null; } const { array } = geometry.getAttribute(Attribute.POSITION); return target2.fromArray(array, index * 3); } position(target2) { if (!this._geometry) { return target2; } const { array } = this._geometry.getAttribute(Attribute.POSITION); return target2.fromArray(array, this._index * 3); } normal(target2) { if (!this._geometry) { return target2; } const { array } = this._geometry.getAttribute(Attribute.NORMAL); return target2.fromArray(array, this._index * 3); } static computeNormals(object) { const geometry = object.geometry; if (!geometry) { return null; } geometry.computeVertexNormals(); } static markAttribAsNeedsUpdate(object, attribName) { const geometry = object.geometry; if (!geometry) { return null; } const attribute = geometry.getAttribute(attribName); if (!attribute) { return; } attribute.needsUpdate = true; } // // // // // static userDataAttribs(object) { const geometry = object.geometry; if (!geometry) { return {}; } return geometry.userData[INDEX_ATTRIB_VALUES] = geometry.userData[INDEX_ATTRIB_VALUES] || {}; } static setIndexedAttribute(object, attribName, values, indices) { const geometry = object.geometry; if (!geometry) { return; } this.setIndexedAttributeValues(object, attribName, values); geometry.setAttribute(attribName, new Int32BufferAttribute(indices, 1)); geometry.getAttribute(attribName).needsUpdate = true; } static attribValueIndex(object, index, attribName) { if (this.isAttribIndexed(object, attribName)) { const geometry = object.geometry; if (geometry) { return geometry.getAttribute(attribName).array[index]; } } return -1; } // // // // // static renameAttribute(object, oldName, newName) { const geometry = object.geometry; if (!geometry) { return; } if (this.isAttribIndexed(object, oldName)) { this.userDataAttribs(object)[newName] = objectCloneDeep(this.userDataAttribs(object)[oldName]); delete this.userDataAttribs(object)[oldName]; } const oldAttrib = geometry.getAttribute(oldName); geometry.setAttribute(newName, new Float32BufferAttribute(oldAttrib.array, oldAttrib.itemSize)); return geometry.deleteAttribute(oldName); } static deleteAttribute(object, attribName) { const geometry = object.geometry; if (!geometry) { return; } if (this.isAttribIndexed(object, attribName)) { delete this.userDataAttribs(object)[attribName]; } return geometry.deleteAttribute(attribName); } static addNumericAttribute(object, attribName, size = 1, defaultValue = 0) { const geometry = object.geometry; if (!geometry) { return; } attributeNumericValues(object, pointsCountFromObject, size, defaultValue, target); if (target.attributeAdded) { if (markedAsInstance(geometry)) { const valuesAsTypedArray = new Float32Array(target.values); geometry.setAttribute(attribName.trim(), new InstancedBufferAttribute(valuesAsTypedArray, size)); } else { geometry.setAttribute(attribName.trim(), new Float32BufferAttribute(target.values, size)); } } else { console.warn(defaultValue); throw `CoreThreejsPoint.addNumericAttrib error: no other default value allowed for now (default given: ${defaultValue})`; } } // // // RELATED ENTITIES // // static relatedVertexIds(object, pointIndex, target2, traversedRelatedEntityData) { const geometry = object.geometry; if (!geometry) { return; } const index = geometry.getIndex(); if (!index) { return; } const indexArray = index.array; let i = 0; for (const indexValue of indexArray) { if (indexValue == pointIndex) { target2.push(i); } i++; } } static relatedVertexClass(object) { return ThreejsVertex; } }