UNPKG

@polygonjs/polygonjs

Version:

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

138 lines (126 loc) 4.95 kB
import {BaseSopOperation} from './_Base'; import {CoreGroup} from '../../../core/geometry/Group'; import {InputCloneMode} from '../../../engine/poly/InputCloneMode'; import { Float32BufferAttribute, Float16BufferAttribute, Uint32BufferAttribute, Int32BufferAttribute, Uint16BufferAttribute, Int16BufferAttribute, Uint8ClampedBufferAttribute, Uint8BufferAttribute, Int8BufferAttribute, BufferAttribute, } from 'three'; import {isBooleanTrue} from '../../../core/BooleanValue'; import {DefaultOperationParams} from '../../../core/operations/_Base'; import {CoreObjectType, ObjectContent} from '../../../core/geometry/ObjectContent'; import {corePointClassFactory, coreVertexClassFactory} from '../../../core/geometry/CoreObjectFactory'; export enum AttribType { Float32BufferAttribute = 'Float32BufferAttribute', Float16BufferAttribute = 'Float16BufferAttribute', Uint32BufferAttribute = 'Uint32BufferAttribute', Int32BufferAttribute = 'Int32BufferAttribute', Uint16BufferAttribute = 'Uint16BufferAttribute', Int16BufferAttribute = 'Int16BufferAttribute', Uint8ClampedBufferAttribute = 'Uint8ClampedBufferAttribute', Uint8BufferAttribute = 'Uint8BufferAttribute', Int8BufferAttribute = 'Int8BufferAttribute', } export const ATTRIB_TYPES: AttribType[] = [ AttribType.Float32BufferAttribute, AttribType.Float16BufferAttribute, AttribType.Uint32BufferAttribute, AttribType.Int32BufferAttribute, AttribType.Uint16BufferAttribute, AttribType.Int16BufferAttribute, AttribType.Uint8ClampedBufferAttribute, AttribType.Uint8BufferAttribute, AttribType.Int8BufferAttribute, ]; const ATTRIB_CLASS_BY_TYPE = { [AttribType.Float32BufferAttribute]: Float32BufferAttribute, [AttribType.Float16BufferAttribute]: Float16BufferAttribute, [AttribType.Uint32BufferAttribute]: Uint32BufferAttribute, [AttribType.Int32BufferAttribute]: Int32BufferAttribute, [AttribType.Uint16BufferAttribute]: Uint16BufferAttribute, [AttribType.Int16BufferAttribute]: Int16BufferAttribute, [AttribType.Uint8ClampedBufferAttribute]: Uint8ClampedBufferAttribute, [AttribType.Uint8BufferAttribute]: Uint8BufferAttribute, [AttribType.Int8BufferAttribute]: Int8BufferAttribute, }; const ARRAY_CLASS_BY_TYPE = { [AttribType.Float32BufferAttribute]: Float32Array, [AttribType.Float16BufferAttribute]: Uint16Array, [AttribType.Uint32BufferAttribute]: Uint32Array, [AttribType.Int32BufferAttribute]: Int32Array, [AttribType.Uint16BufferAttribute]: Uint16Array, [AttribType.Int16BufferAttribute]: Int16Array, [AttribType.Uint8ClampedBufferAttribute]: Uint8Array, [AttribType.Uint8BufferAttribute]: Uint8Array, [AttribType.Int8BufferAttribute]: Int8Array, }; interface AttribCastSopParams extends DefaultOperationParams { castAttributes: boolean; mask: string; castIndex: boolean; type: number; } export class AttribCastSopOperation extends BaseSopOperation { static override readonly DEFAULT_PARAMS: AttribCastSopParams = { castAttributes: true, mask: '*', castIndex: false, type: ATTRIB_TYPES.indexOf(AttribType.Float32BufferAttribute), }; static override readonly INPUT_CLONED_STATE = InputCloneMode.FROM_NODE; static override type(): Readonly<'attribCast'> { return 'attribCast'; } override cook(inputCoreGroups: CoreGroup[], params: AttribCastSopParams) { const coreGroup = inputCoreGroups[0]; const objects = coreGroup.allObjects(); for (let object of objects) { this._castPointAttributes(object, params); } return coreGroup; } private _castPointAttributes<T extends CoreObjectType>(object: ObjectContent<T>, params: AttribCastSopParams) { const type = ATTRIB_TYPES[params.type]; const attribClass = ATTRIB_CLASS_BY_TYPE[type]; const arrayClass = ARRAY_CLASS_BY_TYPE[type]; const corePointClass = corePointClassFactory(object); if (isBooleanTrue(params.castAttributes)) { const attribNames = corePointClass.attributeNamesMatchingMask(object, params.mask); for (let attribName of attribNames) { const attrib: BufferAttribute = corePointClass.attribute(object, attribName) as BufferAttribute; const array = attrib.array; const count = attrib.count; const itemSize = attrib.itemSize; const newArray = new arrayClass(count * itemSize); for (let i = 0; i < array.length; i++) { newArray[i] = array[i]; } const newAttribute = new attribClass(newArray, itemSize); corePointClass.addAttribute(object, attribName, newAttribute); } } // index if (params.castIndex) { const coreVertexClass = coreVertexClassFactory(object); const index = coreVertexClass.indexAttribute(object); if (index) { const array = index.array; const count = index.count; const itemSize = 1; const newArray = new arrayClass(count * itemSize); for (let i = 0; i < array.length; i++) { newArray[i] = array[i]; } const newAttr = new attribClass(newArray, itemSize); coreVertexClass.setIndexAttribute(object, newAttr); } } } }