UNPKG

@polygonjs/polygonjs

Version:

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

236 lines (235 loc) 8.07 kB
"use strict"; import { Quaternion, Color, Vector2, Vector3, Vector4 } from "three"; import { ParamType } from "../../engine/poly/ParamType"; import { Poly } from "../../engine/Poly"; import { isNumber, isEuler, isVector, isColor, isQuaternion } from "../Type"; import { animBuilderCommonVars } from "./vars/Common"; import { animBuilderStartTimeline } from "./vars/StartTimeline"; import { populateVarsForParamVector4 } from "./vars/type/Vector4"; import { populateVarsForColor, populateVarsForParamColor } from "./vars/type/Color"; import { populateVarsForParamVector3 } from "./vars/type/Vector3"; import { populateVarsForParamVector2 } from "./vars/type/Vector2"; import { populateVarsForNumber, populateVarsForSingleNumber } from "./vars/type/Number"; import { populateVarsForVector } from "./vars/type/Vector"; import { populateVarsAndCreateProxyForQuaternion } from "./vars/type/Quaternion"; import { populateVarsForEuler } from "./vars/type/Euler"; const PROPERTY_SEPARATOR = "."; export class TimelineBuilderProperty { constructor() { this._debug = false; } setName(name) { this._propertyName = name; } setTargetValue(value) { this._targetValue = value; } name() { return this._propertyName; } targetValue() { return this._targetValue; } setDebug(debug) { this._debug = debug; } _printDebug(message) { if (!this._debug) { return; } console.log(message); } clone() { const cloned = new TimelineBuilderProperty(); if (this._propertyName) { cloned.setName(this._propertyName); } if (this._targetValue != null) { const newTargetValue = isNumber(this._targetValue) ? this._targetValue : this._targetValue.clone(); cloned.setTargetValue(newTargetValue); } return cloned; } addToTimeline(options) { const target = options.propertyTarget || options.target; const objects = target.objects(); const node = target.node(); this._printDebug(["addToTimeline", target, objects, node]); if (objects) { this._populateWithObjects(objects, options); } if (node) { this._populateWithNode(node, options); } } _populateWithObjects(objects, options) { const { timelineBuilder } = options; this._printDebug(["_populateWithObjects", objects]); if (!this._propertyName) { Poly.warn("no property name given"); return; } if (this._targetValue == null) { Poly.warn("no target value given"); return; } const operation = timelineBuilder.operation(); const updateCallback = timelineBuilder.updateCallback(); for (const object3d of objects) { const props = this._sceneGraphProps(object3d, this._propertyName); if (props) { const registerableProp = { object: object3d, propertyName: this._propertyName }; let { targetProperty, toTarget, propertyNames } = props; const vars = animBuilderCommonVars(timelineBuilder); if (updateCallback && updateCallback.updateMatrix()) { const oldMatrixAutoUpdate = object3d.matrixAutoUpdate; vars.onUpdate = () => { object3d.matrixAutoUpdate = true; }; vars.onComplete = () => { object3d.matrixAutoUpdate = oldMatrixAutoUpdate; if (!object3d.matrixAutoUpdate) { object3d.updateMatrix(); } }; } if (targetProperty instanceof Quaternion && this._targetValue instanceof Quaternion) { toTarget = populateVarsAndCreateProxyForQuaternion({ targetValue: this._targetValue, vars, targetProperty }); } this._populateVarsForObjectProperty({ targetValue: this._targetValue, vars, targetProperty, propertyNames, operation }); if (toTarget) { animBuilderStartTimeline({ ...options, vars, target: toTarget, registerableProp }); } } } } _populateVarsForObjectProperty(options) { const { vars, targetValue, targetProperty, propertyNames, operation } = options; function warnMismatch(expectedType) { Poly.warn( `mismatch between targetValue and targetProperty (expected ${expectedType})`, targetValue, targetProperty ); } if (isNumber(targetProperty)) { if (isNumber(targetValue)) { return populateVarsForNumber({ targetValue, vars, targetProperty, propertyNames, operation }); } return warnMismatch("number"); } if (isEuler(targetProperty)) { if (targetValue instanceof Vector3) { return populateVarsForEuler({ targetValue, vars, targetProperty, propertyNames, operation }); } return warnMismatch("euler"); } if (isVector(targetProperty)) { if (isVector(targetValue)) { return populateVarsForVector({ targetValue, vars, targetProperty, propertyNames, operation }); } return warnMismatch("vector"); } if (isColor(targetProperty)) { if (isColor(targetValue)) { return populateVarsForColor({ targetValue, vars, targetProperty, propertyNames, operation }); } return warnMismatch("color"); } if (isQuaternion(targetProperty)) { } Poly.warn(`targetValue and targetProp are not recognized types`, targetValue, targetProperty); } _sceneGraphProps(object, propertyName) { const elements = propertyName.split(PROPERTY_SEPARATOR); if (elements.length > 1) { const firstElement = elements.shift(); const subObject = object[firstElement]; if (subObject) { const subPropertyName = elements.join(PROPERTY_SEPARATOR); return this._sceneGraphProps(subObject, subPropertyName); } else { Poly.warn(`property ${firstElement} not found on object`, object); } } else { const targetProperty = object[propertyName]; let toTarget = null; const propertyNames = []; if (isNumber(targetProperty)) { toTarget = object; propertyNames.push(propertyName); } else { toTarget = targetProperty; if (this._targetValue instanceof Vector2) { propertyNames.push("x", "y"); } if (this._targetValue instanceof Vector3) { propertyNames.push("x", "y", "z"); } if (this._targetValue instanceof Vector4) { propertyNames.push("x", "y", "z", "w"); } if (this._targetValue instanceof Color) { propertyNames.push("r", "g", "b"); } if (this._targetValue instanceof Quaternion) { } } return { targetProperty, toTarget, propertyNames }; } } _populateWithNode(node, options) { this._printDebug(["_populateWithNode", node]); const targetParam = node.p[this._propertyName]; this._printDebug(["targetParam", targetParam]); if (!targetParam) { Poly.warn(`${this._propertyName} not found on node ${node.path()}`); return; } if (targetParam) { this._populateVarsForParam(targetParam, options); } } _populateVarsForParam(param, options) { this._printDebug(["_populateVarsForParam", param]); if (this._targetValue == null) { return; } switch (param.type()) { case ParamType.INTEGER: case ParamType.FLOAT: { return populateVarsForSingleNumber(param, this._targetValue, options); } case ParamType.VECTOR2: { return populateVarsForParamVector2(param, this._targetValue, options); } case ParamType.VECTOR3: { return populateVarsForParamVector3(param, this._targetValue, options); } case ParamType.COLOR: { return populateVarsForParamColor(param, this._targetValue, options); } case ParamType.VECTOR4: { return populateVarsForParamVector4(param, this._targetValue, options); } } Poly.warn(`param type cannot be animated (yet): '${param.type()}' '${param.path()}'`); } }