UNPKG

@polygonjs/polygonjs

Version:

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

216 lines (204 loc) 7.57 kB
import {TypeAssert} from './../../poly/Assert'; import {AttribClass, ATTRIBUTE_CLASSES_WITHOUT_CORE_GROUP} from './../../../core/geometry/Constant'; import {BaseSopOperation} from './_Base'; import {CoreGroup} from '../../../core/geometry/Group'; // import {Attribute} from '../../../core/geometry/Attribute'; import {DefaultOperationParams} from '../../../core/operations/_Base'; import {BufferAttribute} from 'three'; import {isBooleanTrue} from '../../../core/Type'; // import {BaseCoreObject} from '../../../core/geometry/entities/object/BaseCoreObject'; import {CoreObjectType, ObjectContent} from '../../../core/geometry/ObjectContent'; import {CoreEntity} from '../../../core/geometry/CoreEntity'; import { corePointClassFactory, corePrimitiveClassFactory, coreVertexClassFactory, } from '../../../core/geometry/CoreObjectFactory'; import {PrimitiveNumberAttribute} from '../../../core/geometry/entities/primitive/PrimitiveAttribute'; import {primitivesFromObject} from '../../../core/geometry/entities/primitive/CorePrimitiveUtils'; import {CorePoint} from '../../../core/geometry/entities/point/CorePoint'; import {CorePrimitive} from '../../../core/geometry/entities/primitive/CorePrimitive'; import {pointsFromObject} from '../../../core/geometry/entities/point/CorePointUtils'; import {CoreVertex} from '../../../core/geometry/entities/vertex/CoreVertex'; import {verticesFromObject} from '../../../core/geometry/entities/vertex/CoreVertexUtils'; import {VertexNumberAttribute} from '../../../core/geometry/entities/vertex/VertexAttribute'; interface AttribIdSopParams extends DefaultOperationParams { class: number; id: boolean; idName: string; idn: boolean; idnName: string; } const _points: CorePoint<CoreObjectType>[] = []; const _vertices: CoreVertex<CoreObjectType>[] = []; const _primitives: CorePrimitive<CoreObjectType>[] = []; export class AttribIdSopOperation extends BaseSopOperation { static override readonly DEFAULT_PARAMS: AttribIdSopParams = { class: ATTRIBUTE_CLASSES_WITHOUT_CORE_GROUP.indexOf(AttribClass.POINT), id: true, idName: 'id', idn: true, idnName: 'idn', }; static override type(): Readonly<'attribId'> { return 'attribId'; } override cook(inputCoreGroups: CoreGroup[], params: AttribIdSopParams) { const coreGroup = inputCoreGroups[0]; const attribClass = ATTRIBUTE_CLASSES_WITHOUT_CORE_GROUP[params.class]; this._addAttribute(attribClass, coreGroup, params); return coreGroup; } private async _addAttribute(attribClass: AttribClass, coreGroup: CoreGroup, params: AttribIdSopParams) { const objects = coreGroup.allObjects(); switch (attribClass) { case AttribClass.POINT: return this._addPointAttributesToObjects(objects, params); case AttribClass.VERTEX: { this._addVertexAttributesToObjects(objects, params); return; } case AttribClass.PRIMITIVE: { this._addPrimitiveAttributesToObjects(objects, params); return; } case AttribClass.OBJECT: return this._addAttributesToEntities(coreGroup.allCoreObjects(), params); case AttribClass.CORE_GROUP: // no effect return; } TypeAssert.unreachable(attribClass); } // private _addObjectAttributes(coreObjects: BaseCoreObject<CoreObjectType>[], params: AttribIdSopParams) { // const objectsCount = coreObjects.length; // if (objectsCount > 1) { // let i = 0; // for (const coreObject of coreObjects) { // if (isBooleanTrue(params.id)) { // coreObject.addAttribute(params.idName, i); // } // if (isBooleanTrue(params.idn)) { // coreObject.addAttribute(params.idnName, i / (objectsCount - 1)); // } // i++; // } // } else { // coreObjects[0].addAttribute(params.idName, 0); // coreObjects[0].addAttribute(params.idnName, 0); // } // } private _addPointAttributesToObjects(objects: ObjectContent<CoreObjectType>[], params: AttribIdSopParams) { for (const object of objects) { this._addPointAttributesToObject(object, params); } } private _addVertexAttributesToObjects(objects: ObjectContent<CoreObjectType>[], params: AttribIdSopParams) { for (const object of objects) { this._addVertexAttributes(object, params); } } private _addPrimitiveAttributesToObjects(objects: ObjectContent<CoreObjectType>[], params: AttribIdSopParams) { for (const object of objects) { this._addPrimitiveAttributes(object, params); } } private _addPointAttributesToObject(object: ObjectContent<CoreObjectType>, params: AttribIdSopParams) { const pointClass = corePointClassFactory(object); pointsFromObject(object, _points); const entitiesCount = _points.length; if (isBooleanTrue(params.id)) { const idValues = new Array(entitiesCount); for (let i = 0; i < entitiesCount; i++) { idValues[i] = i; } const idArray = new Float32Array(idValues); const attrib = new BufferAttribute(idArray, 1); pointClass.addAttribute(object, params.idName, attrib); } if (isBooleanTrue(params.idn)) { const idnValues = new Array(entitiesCount); const pointsCountMinus1 = entitiesCount - 1; if (pointsCountMinus1 == 0) { for (let i = 0; i < entitiesCount; i++) { idnValues[i] = 0; } } else { for (let i = 0; i < entitiesCount; i++) { idnValues[i] = i / (entitiesCount - 1); } } const idnArray = new Float32Array(idnValues); const attrib = new BufferAttribute(idnArray, 1); pointClass.addAttribute(object, params.idnName, attrib); } } private _addVertexAttributes(object: ObjectContent<CoreObjectType>, params: AttribIdSopParams) { const vertexClass = coreVertexClassFactory(object); verticesFromObject(object, _vertices); if (isBooleanTrue(params.id)) { const attribute: VertexNumberAttribute = { isString: false, array: new Array(_vertices.length), itemSize: 1, }; vertexClass.addAttribute(object, params.idName, attribute); } if (isBooleanTrue(params.idn)) { const attribute: VertexNumberAttribute = { isString: false, array: new Array(_vertices.length), itemSize: 1, }; vertexClass.addAttribute(object, params.idnName, attribute); } this._addAttributesToEntities(_vertices, params); } private _addPrimitiveAttributes(object: ObjectContent<CoreObjectType>, params: AttribIdSopParams) { const primitiveClass = corePrimitiveClassFactory(object); primitivesFromObject(object, _primitives); if (isBooleanTrue(params.id)) { const attribute: PrimitiveNumberAttribute = { isString: false, array: new Array(_primitives.length), itemSize: 1, }; primitiveClass.addAttribute(object, params.idName, attribute); } if (isBooleanTrue(params.idn)) { const attribute: PrimitiveNumberAttribute = { isString: false, array: new Array(_primitives.length), itemSize: 1, }; primitiveClass.addAttribute(object, params.idnName, attribute); } this._addAttributesToEntities(_primitives, params); } private _addAttributesToEntities(entities: CoreEntity[], params: AttribIdSopParams) { const entitiesCount = entities.length; if (isBooleanTrue(params.id)) { let i = 0; for (const entity of entities) { entity.setAttribValue(params.idName, i); i++; } } if (isBooleanTrue(params.idn)) { const pointsCountMinus1 = entitiesCount - 1; if (pointsCountMinus1 == 0) { let i = 0; for (const entity of entities) { entity.setAttribValue(params.idnName, 0); i++; } } else { let i = 0; for (const entity of entities) { entity.setAttribValue(params.idnName, i / (entitiesCount - 1)); i++; } } } } }