UNPKG

@polygonjs/polygonjs

Version:

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

134 lines (125 loc) 4.4 kB
/** * Target of the animation * * */ import {TypedAnimNode} from './_Base'; import {TimelineBuilder} from '../../../core/animation/TimelineBuilder'; export enum AnimTargetNodeTargetType { SCENE_GRAPH = 'scene graph', NODE = 'node', } export const ANIM_TARGET_TYPES: AnimTargetNodeTargetType[] = [ AnimTargetNodeTargetType.SCENE_GRAPH, AnimTargetNodeTargetType.NODE, ]; const TARGET_TYPE_SCENE_GRAPH = ANIM_TARGET_TYPES.indexOf(AnimTargetNodeTargetType.SCENE_GRAPH); const TARGET_TYPE_NODE = ANIM_TARGET_TYPES.indexOf(AnimTargetNodeTargetType.NODE); import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {TypeAssert} from '../../poly/Assert'; import {AnimPropertyTarget} from '../../../core/animation/PropertyTarget'; import {AnimationUpdateCallback} from '../../../core/animation/UpdateCallback'; import {BaseParamType} from '../../params/_Base'; import {BaseNodeType} from '../_Base'; import {isBooleanTrue} from '../../../core/BooleanValue'; import {AnimType} from '../../poly/registers/nodes/types/Anim'; class TargetAnimParamsConfig extends NodeParamsConfig { /** @param sets if the target is a Polygonjs node, or a THREE object */ type = ParamConfig.INTEGER(TARGET_TYPE_SCENE_GRAPH, { menu: { entries: ANIM_TARGET_TYPES.map((name, value) => { return {name, value}; }), }, }); /** @param if set to a Polygonjs node, this is the node path */ nodePath = ParamConfig.NODE_PATH('', { visibleIf: {type: TARGET_TYPE_NODE}, }); /** @param if set to a THREE object, this is a mask to find the objects */ objectMask = ParamConfig.STRING('/geo*', { visibleIf: {type: TARGET_TYPE_SCENE_GRAPH}, objectMask: true, }); /** @param sets if the matrix should be updated as the animation progresses */ updateMatrix = ParamConfig.BOOLEAN(1, { visibleIf: {type: TARGET_TYPE_SCENE_GRAPH}, }); /** @param prints which objects are targeted by this node, for debugging */ printResolve = ParamConfig.BUTTON(null, { callback: (node: BaseNodeType, param: BaseParamType) => { TargetAnimNode.PARAM_CALLBACK_print_resolve(node as TargetAnimNode); }, }); } const ParamsConfig = new TargetAnimParamsConfig(); export class TargetAnimNode extends TypedAnimNode<TargetAnimParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return AnimType.TARGET; } override initializeNode() { this.io.inputs.setCount(0, 1); } override cook(inputCoreContents: TimelineBuilder[]) { const timelineBuilder = inputCoreContents[0] || new TimelineBuilder(); const target = this._create_target(timelineBuilder); timelineBuilder.setTarget(target); this._set_update_callback(timelineBuilder); this.setTimelineBuilder(timelineBuilder); } setTargetType(targetType: AnimTargetNodeTargetType) { this.p.type.set(ANIM_TARGET_TYPES.indexOf(targetType)); } private _create_target(timelineBuilder: TimelineBuilder) { const type = ANIM_TARGET_TYPES[this.pv.type]; switch (type) { case AnimTargetNodeTargetType.NODE: { return new AnimPropertyTarget(this.scene(), { node: { path: this.pv.nodePath.path(), relativeTo: this, }, }); } case AnimTargetNodeTargetType.SCENE_GRAPH: { return new AnimPropertyTarget(this.scene(), {object: {mask: this.pv.objectMask}}); } } TypeAssert.unreachable(type); } private _set_update_callback(timelineBuilder: TimelineBuilder) { const type = ANIM_TARGET_TYPES[this.pv.type]; let update_callback = timelineBuilder.updateCallback(); switch (type) { case AnimTargetNodeTargetType.NODE: { return; } case AnimTargetNodeTargetType.SCENE_GRAPH: { if (isBooleanTrue(this.pv.updateMatrix)) { update_callback = update_callback || new AnimationUpdateCallback(); update_callback.setUpdateMatrix(this.pv.updateMatrix); timelineBuilder.setUpdateCallback(update_callback); } return; } } TypeAssert.unreachable(type); } static PARAM_CALLBACK_print_resolve(node: TargetAnimNode) { node.print_resolve(); } private print_resolve() { const type = ANIM_TARGET_TYPES[this.pv.type]; const timeline_builder = new TimelineBuilder(); const target = this._create_target(timeline_builder); switch (type) { case AnimTargetNodeTargetType.NODE: { return console.log(target.node()); } case AnimTargetNodeTargetType.SCENE_GRAPH: { return console.log(target.objects()); } } } }