UNPKG

@polygonjs/polygonjs

Version:

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

211 lines (198 loc) 6.78 kB
/** * Value of the property the animation will be animated to * * */ import {TypedAnimNode} from './_Base'; import {TimelineBuilder} from '../../../core/animation/TimelineBuilder'; import {isNumber, isVector} from '../../../core/Type'; import {TypeAssert} from '../../poly/Assert'; import {Object3D} from 'three'; import {Quaternion} from 'three'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {isBooleanTrue} from '../../../core/BooleanValue'; import {BaseNodeType} from '../_Base'; export enum AnimPropertyValueNodeMode { CUSTOM = 'custom', FROM_SCENE_GRAPH = 'from scene graph', FROM_NODE = 'from node', } const PROPERTY_VALUE_MODES: AnimPropertyValueNodeMode[] = [ AnimPropertyValueNodeMode.CUSTOM, AnimPropertyValueNodeMode.FROM_SCENE_GRAPH, AnimPropertyValueNodeMode.FROM_NODE, ]; const PROPERTY_VALUE_MODE_CUSTOM = PROPERTY_VALUE_MODES.indexOf(AnimPropertyValueNodeMode.CUSTOM); const PROPERTY_VALUE_MODE_FROM_SCENE_GRAPH = PROPERTY_VALUE_MODES.indexOf(AnimPropertyValueNodeMode.FROM_SCENE_GRAPH); const PROPERTY_VALUE_MODE_FROM_NODE = PROPERTY_VALUE_MODES.indexOf(AnimPropertyValueNodeMode.FROM_NODE); class PropertyValueAnimParamsConfig extends NodeParamsConfig { /** @param mode */ mode = ParamConfig.INTEGER(PROPERTY_VALUE_MODE_CUSTOM, { menu: { entries: PROPERTY_VALUE_MODES.map((name, value) => { return {name, value}; }), }, }); /** @param if set to a Polygonjs node, this is the node path */ nodePath = ParamConfig.NODE_PATH('', { visibleIf: {mode: PROPERTY_VALUE_MODE_FROM_NODE}, }); /** @param if set to a THREE object, this is a mask to find the objects */ objectMask = ParamConfig.STRING('*geo1', { visibleIf: {mode: PROPERTY_VALUE_MODE_FROM_SCENE_GRAPH}, }); /** @param print the object matching the objectMask, to help debugging */ printResolve = ParamConfig.BUTTON(null, { visibleIf: {mode: PROPERTY_VALUE_MODE_FROM_SCENE_GRAPH}, callback: (node: BaseNodeType) => { PropertyValueAnimNode.PARAM_CALLBACK_printResolve(node as PropertyValueAnimNode); }, }); overridePropertyName = ParamConfig.BOOLEAN(0, { visibleIf: [{mode: PROPERTY_VALUE_MODE_FROM_SCENE_GRAPH}, {mode: PROPERTY_VALUE_MODE_FROM_NODE}], }); propertyName = ParamConfig.STRING('', { visibleIf: [ {overridePropertyName: true, mode: PROPERTY_VALUE_MODE_FROM_SCENE_GRAPH}, {overridePropertyName: true, mode: PROPERTY_VALUE_MODE_FROM_NODE}, ], }); /** @param size of the parameter to animate */ size = ParamConfig.INTEGER(3, { range: [1, 4], rangeLocked: [true, true], visibleIf: {mode: PROPERTY_VALUE_MODE_CUSTOM}, separatorAfter: true, }); /** @param value for a float */ value1 = ParamConfig.FLOAT(0, { visibleIf: {mode: PROPERTY_VALUE_MODE_CUSTOM, size: 1}, }); /** @param value for a vector2 */ value2 = ParamConfig.VECTOR2([0, 0], { visibleIf: {mode: PROPERTY_VALUE_MODE_CUSTOM, size: 2}, }); /** @param value for a vector3 */ value3 = ParamConfig.VECTOR3([0, 0, 0], { visibleIf: {mode: PROPERTY_VALUE_MODE_CUSTOM, size: 3, asColor: false}, }); /** @param value for a vector3 as color */ color = ParamConfig.COLOR([0, 0, 0], { visibleIf: {mode: PROPERTY_VALUE_MODE_CUSTOM, size: 3, asColor: true}, }); /** @param value for a vector4 */ value4 = ParamConfig.VECTOR4([0, 0, 0, 0], { visibleIf: {mode: PROPERTY_VALUE_MODE_CUSTOM, size: 4}, }); /** @param when using vector3, use toggle on it should be a color */ asColor = ParamConfig.BOOLEAN(0, { visibleIf: {mode: PROPERTY_VALUE_MODE_CUSTOM, size: 3}, }); } const ParamsConfig = new PropertyValueAnimParamsConfig(); export class PropertyValueAnimNode extends TypedAnimNode<PropertyValueAnimParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return 'propertyValue'; } override initializeNode() { this.io.inputs.setCount(0, 1); } override async cook(inputContents: TimelineBuilder[]) { const timelineBuilder = inputContents[0] || new TimelineBuilder(); await this._prepareTimelineBuilder(timelineBuilder); this.setTimelineBuilder(timelineBuilder); } setMode(targetType: AnimPropertyValueNodeMode) { this.p.mode.set(PROPERTY_VALUE_MODES.indexOf(targetType)); } private async _prepareTimelineBuilder(timelineBuilder: TimelineBuilder) { const mode = PROPERTY_VALUE_MODES[this.pv.mode]; switch (mode) { case AnimPropertyValueNodeMode.CUSTOM: { return this._prepareTimebuilderCustom(timelineBuilder); } case AnimPropertyValueNodeMode.FROM_SCENE_GRAPH: { return this._prepareTimebuilderFromSceneGraph(timelineBuilder); } case AnimPropertyValueNodeMode.FROM_NODE: { return await this._prepareTimebuilderFromNode(timelineBuilder); } } TypeAssert.unreachable(mode); } private _prepareTimebuilderCustom(timelineBuilder: TimelineBuilder) { const size = this.pv.size; switch (size) { case 1: { return timelineBuilder.setPropertyValue(this.pv.value1); } case 2: { return timelineBuilder.setPropertyValue(this.pv.value2); } case 3: { if (isBooleanTrue(this.pv.asColor)) { return timelineBuilder.setPropertyValue(this.pv.color); } else { return timelineBuilder.setPropertyValue(this.pv.value3); } } case 4: { return timelineBuilder.setPropertyValue(this.pv.value4); } } } private _prepareTimebuilderFromSceneGraph(timelineBuilder: TimelineBuilder) { const propertyName = isBooleanTrue(this.pv.overridePropertyName) ? this.pv.propertyName : timelineBuilder.propertyName(); if (!propertyName) { return; } const foundObject = this._foundObjectFromSceneGraph() as Object3D | undefined; if (foundObject) { const value: any = foundObject[propertyName as keyof Object3D]; if (value) { if (isNumber(value) || isVector(value) || value instanceof Quaternion) { timelineBuilder.setPropertyValue(value); } } } } private async _prepareTimebuilderFromNode(timelineBuilder: TimelineBuilder) { const propertyName = isBooleanTrue(this.pv.overridePropertyName) ? this.pv.propertyName : timelineBuilder.propertyName(); if (!propertyName) { return; } const node = this.pv.nodePath.node(); if (!node) { return; } const param = node.params.get(propertyName); if (!param) { return; } if (param.isDirty()) { await param.compute(); } const value = param.value; if (value) { if (isNumber(value) || isVector(value)) { timelineBuilder.setPropertyValue(value); } } } static PARAM_CALLBACK_printResolve(node: PropertyValueAnimNode) { node.printResolve(); } private _foundObjectFromSceneGraph() { return this.scene().findObjectByMask(this.pv.objectMask); } private printResolve() { const foundObject = this._foundObjectFromSceneGraph(); console.log(foundObject); } }