UNPKG

@polygonjs/polygonjs

Version:

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

87 lines (75 loc) 3.04 kB
import {TypeAssert} from './../../poly/Assert'; import {BaseSopOperation} from './_Base'; import {CoreGroup} from '../../../core/geometry/Group'; import {Mesh, BufferGeometry} from 'three'; import {InputCloneMode} from '../../../engine/poly/InputCloneMode'; import {DefaultOperationParams} from '../../../core/operations/_Base'; export enum SetGeometryMode { ONE_GEO_PER_OBJECT = 'One Geometry Per Object', FIRST_GEO_TO_EACH_OBJECT = 'First Geometry To Each Object', } export const SET_GEOMETRY_MODES: SetGeometryMode[] = [ SetGeometryMode.ONE_GEO_PER_OBJECT, SetGeometryMode.FIRST_GEO_TO_EACH_OBJECT, ]; interface SetGeometrySopParams extends DefaultOperationParams { mode: number; } export class SetGeometrySopOperation extends BaseSopOperation { static override readonly DEFAULT_PARAMS: SetGeometrySopParams = { mode: SET_GEOMETRY_MODES.indexOf(SetGeometryMode.ONE_GEO_PER_OBJECT), }; static override readonly INPUT_CLONED_STATE = [InputCloneMode.FROM_NODE, InputCloneMode.NEVER]; static override type(): Readonly<'setGeometry'> { return 'setGeometry'; } override cook(inputCoreGroups: CoreGroup[], params: SetGeometrySopParams) { const coreGroupDest = inputCoreGroups[0]; const coreGroupSrc = inputCoreGroups[1]; this._applyMode(coreGroupDest, coreGroupSrc, params); return coreGroupDest; } private _applyMode(coreGroupDest: CoreGroup, coreGroupSrc: CoreGroup, params: SetGeometrySopParams) { const mode = SET_GEOMETRY_MODES[params.mode]; switch (mode) { case SetGeometryMode.ONE_GEO_PER_OBJECT: { return this._oneGeoPerObject(coreGroupDest, coreGroupSrc); } case SetGeometryMode.FIRST_GEO_TO_EACH_OBJECT: { return this._firstGeoToEachObject(coreGroupDest, coreGroupSrc); } } TypeAssert.unreachable(mode); } private _oneGeoPerObject(coreGroupDest: CoreGroup, coreGroupSrc: CoreGroup) { const destObjects = coreGroupDest.threejsObjects(); const srcObjects = coreGroupSrc.threejsObjects(); for (let i = 0; i < destObjects.length; i++) { const destObject = destObjects[i] as Mesh | undefined; const srcObject = srcObjects[i] as Mesh | undefined; if (destObject) { destObject.geometry = srcObject ? srcObject.geometry : SetGeometrySopOperation._emptyGeometry(); } } } private _firstGeoToEachObject(coreGroupDest: CoreGroup, coreGroupSrc: CoreGroup) { const destObjects = coreGroupDest.threejsObjects(); const srcObjects = coreGroupSrc.threejsObjects(); let firstGeometry: BufferGeometry | undefined; for (let srcObject of srcObjects) { if ((srcObject as Mesh).geometry) { firstGeometry = (srcObject as Mesh).geometry; } } for (let i = 0; i < destObjects.length; i++) { const destObject = destObjects[i] as Mesh | undefined; if (destObject) { destObject.geometry = firstGeometry || SetGeometrySopOperation._emptyGeometry(); } } } private static __emptyGeometry: BufferGeometry | undefined; private static _emptyGeometry() { return (this.__emptyGeometry = this.__emptyGeometry || new BufferGeometry()); } }