UNPKG

@polygonjs/polygonjs

Version:

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

97 lines (92 loc) 3.1 kB
import {Object3D} from 'three'; import {watch, WatchStopHandle, WatchCallback, WatchOptions, WatchSource} from '@vue-reactivity/watch'; import {PolyScene} from '../../../../engine/scene/PolyScene'; import {BaseSopNodeType} from '../../../../../src/engine/nodes/sop/_Base'; import {ThreejsCoreObject} from './ThreejsCoreObject'; import { JsIConnectionPointTypeToDataTypeMap, ParamConvertibleJsType, } from '../../../../engine/nodes/utils/io/connections/Js'; export interface CoreObjectHelperOptions<S extends PolyScene> { scene: S; object: Object3D; } interface CreateObjectOptions<S extends PolyScene> { scene: S; object: Object3D; } type OnAttributeChangeCallback<T> = (newValue: T, prevValue: T) => void; export class CoreObjectHelper<S extends PolyScene> { private _watchStopHandles: WatchStopHandle[] = []; public readonly scene: S; public readonly object: Object3D; constructor(public readonly options: CoreObjectHelperOptions<S>) { this.scene = options.scene; this.object = options.object; } dispose() { for (const watchStopHandle of this._watchStopHandles) { watchStopHandle(); } } onAttributeUpdate<T extends ParamConvertibleJsType>( attribName: string, attribType: T, defaultValue: JsIConnectionPointTypeToDataTypeMap[T], callback: OnAttributeChangeCallback<JsIConnectionPointTypeToDataTypeMap[T]> ) { const attributeRef = ThreejsCoreObject.attributeRef(this.object, attribName, attribType, defaultValue); if (attributeRef == null) { console.error(`attrib not found:'${attribName}'`); return; } const watchStopHandle = watch(attributeRef.current, callback); this._watchStopHandles.push(watchStopHandle); } watch<T, Immediate extends Readonly<boolean> = false>( source: WatchSource<T>, cb: WatchCallback<T, Immediate extends true ? T | undefined : T>, options?: WatchOptions<Immediate> ): void { const watchHandle = watch(source, cb, options); this._watchStopHandles.push(watchHandle); } } type CreateCoreObjectHelper<S extends PolyScene, T extends CoreObjectHelper<S>> = ( options: CreateObjectOptions<S> ) => T; interface ObjectFromNodeOptions { traverse?: boolean; } export async function objectFromNode<S extends PolyScene, T extends CoreObjectHelper<S>>( node: BaseSopNodeType, objectName: string, creatFunction: CreateCoreObjectHelper<S, T>, options?: ObjectFromNodeOptions ) { const container = await node.compute(); const coreGroup = container.coreContent(); if (!coreGroup) { console.error(`no core group found in node '${node.path()}'`); console.log(node.states.error.message()); return; } const objects = coreGroup.threejsObjects(); let foundObject = objects.find((o) => o.name == objectName); if (!foundObject && options?.traverse == true) { for (const object of objects) { if (foundObject == null) { object.traverse((child) => { if (child.name == objectName) { foundObject = child; } }); } } } if (!foundObject) { console.error(`no object with name '${objectName}'`); return; } return creatFunction({scene: node.scene() as S, object: foundObject}); }