polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
102 lines (91 loc) • 2.9 kB
text/typescript
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();
}
}