UNPKG

polygonjs-engine

Version:

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

102 lines (91 loc) 2.9 kB
import {TypedSopNode} from './_Base'; import {AnimationMixer} from 'three/src/animation/AnimationMixer'; import {InputCloneMode} from '../../poly/InputCloneMode'; import {CoreGroup} from '../../../core/geometry/Group'; import {BaseNodeType} from '../_Base'; import {NodeContext} from '../../poly/NodeContext'; import {Object3D} from 'three/src/core/Object3D'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {BaseParamType} from '../../params/_Base'; class AnimationMixerSopParamsConfig extends NodeParamsConfig { time = ParamConfig.FLOAT('$T', {range: [0, 10]}); clip = ParamConfig.OPERATOR_PATH('/ANIM/OUT', { nodeSelection: { context: NodeContext.ANIM, }, dependentOnFoundNode: false, }); reset = ParamConfig.BUTTON(null, { callback: (node: BaseNodeType, param: BaseParamType) => { AnimationMixerSopNode.PARAM_CALLBACK_reset(node as AnimationMixerSopNode, param); }, }); } const ParamsConfig = new AnimationMixerSopParamsConfig(); export class AnimationMixerSopNode extends TypedSopNode<AnimationMixerSopParamsConfig> { params_config = ParamsConfig; static type() { return 'animationMixer'; } private _previous_time: number | undefined; private _mixer: AnimationMixer | undefined; static displayedInputNames(): string[] { return ['geometry to be animated']; } initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode.NEVER); } async cook(input_contents: CoreGroup[]) { const core_group = input_contents[0]; const object = core_group.objects()[0]; if (object) { await this.create_mixer_if_required(object); this._update_mixer(); } this.setObjects([object]); } private async create_mixer_if_required(object: Object3D) { if (!this._mixer) { const mixer = await this._create_mixer(object); if (mixer) { this._mixer = mixer; } } } private async _create_mixer(object: Object3D) { if (this.p.clip.isDirty()) { await this.p.clip.compute(); } const anim_node = this.p.clip.found_node_with_context(NodeContext.ANIM); if (anim_node) { // const container = await anim_node.requestContainer(); // const animation_clip = container.animation_clip(); const mixer = new AnimationMixer(object); // const action = mixer.clipAction(animation_clip); // action.play(); return mixer; } } private _update_mixer() { this._set_mixer_time(); // this._update_mixer_weights(); } private _set_mixer_time() { if (this.pv.time != this._previous_time) { if (this._mixer) { this._mixer.setTime(this.pv.time); } this._previous_time = this.pv.time; } } static PARAM_CALLBACK_reset(node: AnimationMixerSopNode, param: BaseParamType) { param.setDirty(); node.reset_animation_mixer(); } async reset_animation_mixer() { this._mixer = undefined; this._previous_time = undefined; this.setDirty(); } }