UNPKG

@polygonjs/polygonjs

Version:

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

356 lines (355 loc) 11.8 kB
"use strict"; import { NodeParamsConfig, ParamConfig } from "./../utils/params/ParamsConfig"; import { TypedJsNode } from "./_Base"; import { JsConnectionPointType } from "../utils/io/connections/Js"; import { sampleData, sampleData0 } from "../../../core/keyframes/KeyframeSamples"; import { rangeStartEnd } from "../../../core/ArrayUtils"; import { ConstantJsDefinition } from "./utils/JsDefinition"; import { Poly } from "../../Poly"; import { JsType } from "../../poly/registers/nodes/types/Js"; import { channelDataToString } from "../../../core/keyframes/KeyframeSerialize"; import { createVariable } from "./code/assemblers/_BaseJsPersistedConfigUtils"; import { isArray } from "../../../core/Type"; import { _setArrayLength } from "../../functions/_ArrayUtils"; var KeyframesJsNodeInputName = /* @__PURE__ */ ((KeyframesJsNodeInputName2) => { KeyframesJsNodeInputName2["time"] = "time"; return KeyframesJsNodeInputName2; })(KeyframesJsNodeInputName || {}); export const AVAILABLE_JS_CONNECTION_POINT_TYPES = [ JsConnectionPointType.FLOAT, JsConnectionPointType.VECTOR2, JsConnectionPointType.VECTOR3, JsConnectionPointType.VECTOR4 ]; export const ARRAY_SIZE_BY_TYPE = { [JsConnectionPointType.FLOAT]: 1, [JsConnectionPointType.VECTOR2]: 2, [JsConnectionPointType.VECTOR3]: 3, [JsConnectionPointType.VECTOR4]: 4 }; export const CHANNEL_SUFFIX_BY_CHANNEL_INDEX = ["x", "y", "z", "w"]; function visibleIfChannelsCountAtLeast(index) { return { visibleIf: rangeStartEnd(index + 1, 10).map((i) => ({ channelsCount: i })) }; } function channelTypeParam(index) { return ParamConfig.INTEGER(AVAILABLE_JS_CONNECTION_POINT_TYPES.indexOf(JsConnectionPointType.FLOAT), { menu: { entries: AVAILABLE_JS_CONNECTION_POINT_TYPES.map((name, i) => { return { name, value: i }; }) }, separatorBefore: true, ...visibleIfChannelsCountAtLeast(index) }); } function channelNameParam(index) { return ParamConfig.STRING(`channel${index}`, { ...visibleIfChannelsCountAtLeast(index) }); } function channelDataParam(index) { return ParamConfig.STRING(channelDataToString(sampleData()), { ...visibleIfChannelsCountAtLeast(index) }); } export function channelDataInputName(index) { return `data${index}`; } class KeyframesJsParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); // main = ParamConfig.FOLDER(); // time = ParamConfig.FLOAT(0, { // step: 0.001, // }); this.channels = ParamConfig.FOLDER(); this.channelsCount = ParamConfig.INTEGER(1, { range: [0, 10], rangeLocked: [true, true] }); this.channelType0 = channelTypeParam(0); this.channelName0 = channelNameParam(0); this.data0 = channelDataParam(0); this.channelType1 = channelTypeParam(1); this.channelName1 = channelNameParam(1); this.data1 = channelDataParam(1); this.channelType2 = channelTypeParam(2); this.channelName2 = channelNameParam(2); this.data2 = channelDataParam(2); this.channelType3 = channelTypeParam(3); this.channelName3 = channelNameParam(3); this.data3 = channelDataParam(3); this.channelType4 = channelTypeParam(4); this.channelName4 = channelNameParam(4); this.data4 = channelDataParam(4); this.channelType5 = channelTypeParam(5); this.channelName5 = channelNameParam(5); this.data5 = channelDataParam(5); this.channelType6 = channelTypeParam(6); this.channelName6 = channelNameParam(6); this.data6 = channelDataParam(6); this.channelType7 = channelTypeParam(7); this.channelName7 = channelNameParam(7); this.data7 = channelDataParam(7); this.channelType8 = channelTypeParam(8); this.channelName8 = channelNameParam(8); this.data8 = channelDataParam(8); this.channelType9 = channelTypeParam(9); this.channelName9 = channelNameParam(9); this.data9 = channelDataParam(9); this.spare = ParamConfig.FOLDER(); } } const ParamsConfig = new KeyframesJsParamsConfig(); export class KeyframesJsNode extends TypedJsNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return JsType.KEYFRAMES; } initializeNode() { super.initializeNode(); this.io.connection_points.set_input_name_function(this._expectedInputName.bind(this)); this.io.connection_points.set_expected_input_types_function(this._expectedInputTypes.bind(this)); this.io.connection_points.set_expected_output_types_function(this._expectedOutputTypes.bind(this)); this.io.connection_points.set_output_name_function(this._expectedOutputName.bind(this)); } channelTypeParams() { return [ this.p.channelType0, this.p.channelType1, this.p.channelType2, this.p.channelType3, this.p.channelType4, this.p.channelType5, this.p.channelType6, this.p.channelType7, this.p.channelType8, this.p.channelType9 ]; } channelNameParams() { return [ this.p.channelName0, this.p.channelName1, this.p.channelName2, this.p.channelName3, this.p.channelName4, this.p.channelName5, this.p.channelName6, this.p.channelName7, this.p.channelName8, this.p.channelName9 ]; } channelDataParams() { return [ this.p.data0, this.p.data1, this.p.data2, this.p.data3, this.p.data4, this.p.data5, this.p.data6, this.p.data7, this.p.data8, this.p.data9 ]; } // dataParam(channelName: string) { // const paramIndex = this.channelNameParams().findIndex((param) => param.value === channelName); // return this.channelDataParams()[paramIndex]; // } // channelsData(target: ChannelsData) { // // const data: ChannelsData = {}; // const existingChannelNames = Object.keys(target); // for (const channelName of existingChannelNames) { // delete target[channelName]; // } // const count = this.pv.channelsCount; // for (let i = 0; i < count; i++) { // const channelName = this._channelNameParams()[i].value; // const channelData = JSON.parse(this.channelDataParams()[i].value); // target[channelName] = channelData; // } // } setChannelType(index, type) { const param = this.channelTypeParams()[index]; if (!param) { return; } param.set(AVAILABLE_JS_CONNECTION_POINT_TYPES.indexOf(type)); } setChannelName(index, inputName) { const param = this.channelNameParams()[index]; if (!param) { return; } param.set(inputName); } setChannelData(index, data) { const param = this.channelDataParams()[index]; if (!param) { return; } const expectedArraySize = ARRAY_SIZE_BY_TYPE[this._expectedOutputTypes()[index]]; if (expectedArraySize > 1) { param.set(JSON.stringify(data)); } else { const firstElem = data[0]; param.set(JSON.stringify(firstElem)); } } channelData(index) { const param = this.channelDataParams()[index]; if (!param) { return; } const data = JSON.parse(param.value); const expectedArraySize = ARRAY_SIZE_BY_TYPE[this._expectedOutputTypes()[index]]; if (expectedArraySize > 1) { if (isArray(data)) { if (data.length != expectedArraySize) { _setArrayLength(data, expectedArraySize, sampleData0); } return data; } else { const newData = [data]; _setArrayLength(newData, expectedArraySize, sampleData0); return newData; } } else { if (isArray(data)) { return data[0]; } else { return data; } } } _channelsCount() { return this.pv.channelsCount; } _expectedInputTypes() { return [JsConnectionPointType.FLOAT]; } _expectedInputName(index) { return ["time" /* time */][index]; } _expectedOutputTypes() { const count = this._channelsCount(); const params = this.channelTypeParams(); return rangeStartEnd(0, count).map((value, i) => AVAILABLE_JS_CONNECTION_POINT_TYPES[params[i].value]); } _expectedOutputName(index) { const params = this.channelNameParams(); return params[index].value; } setLines(linesController) { const time = this.variableForInput(linesController, "time" /* time */); const usedOutputNames = this.io.outputs.used_output_names(); const _f = (outputName, channelIndex) => { if (!usedOutputNames.includes(outputName)) { return; } const funcCurve = Poly.namedFunctionsRegister.getFunction("channelFloat", this, linesController); const funcCurveValue = Poly.namedFunctionsRegister.getFunction("channelValueFloat", this, linesController); const curve = this.jsVarName(`${outputName}_CURVE`); const out = this.jsVarName(outputName); linesController.addDefinitions(this, [ new ConstantJsDefinition( this, linesController, JsConnectionPointType.FLOAT, curve, funcCurve.asString(this.channelDataParams()[channelIndex].value) ) ]); linesController.addBodyOrComputed(this, [ { dataType: JsConnectionPointType.FLOAT, varName: out, value: funcCurveValue.asString(linesController.assembler().memberReference(curve), time) } ]); }; const _v = (options) => { const { outputName, channelIndex, dataType, channelCreate, channelGetValue } = options; if (!usedOutputNames.includes(outputName)) { return; } const funcCurve = Poly.namedFunctionsRegister.getFunction(channelCreate, this, linesController); const funcCurveValue = Poly.namedFunctionsRegister.getFunction(channelGetValue, this, linesController); const variable = createVariable(dataType); const curve = this.jsVarName(`${outputName}_CURVE`); const out = this.jsVarName(outputName); linesController.addDefinitions(this, [ new ConstantJsDefinition( this, linesController, dataType, curve, funcCurve.asString(this.channelDataParams()[channelIndex].value) ) ]); if (variable) { const tmpVarName = linesController.addVariable(this, variable); linesController.addBodyOrComputed(this, [ { dataType, varName: out, value: funcCurveValue.asString( linesController.assembler().memberReference(curve), time, tmpVarName ) } ]); } }; const channelsCount = this._channelsCount(); for (let channelIndex = 0; channelIndex < channelsCount; channelIndex++) { const outputName = this._expectedOutputName(channelIndex); const channelType = this._expectedOutputTypes()[channelIndex]; switch (channelType) { case JsConnectionPointType.FLOAT: { _f(outputName, channelIndex); break; } case JsConnectionPointType.VECTOR2: { _v({ outputName, channelIndex, dataType: channelType, channelCreate: "channelVector2", channelGetValue: "channelValueVector2" }); break; } case JsConnectionPointType.VECTOR3: { _v({ outputName, channelIndex, dataType: channelType, channelCreate: "channelVector3", channelGetValue: "channelValueVector3" }); break; } case JsConnectionPointType.VECTOR4: { _v({ outputName, channelIndex, dataType: channelType, channelCreate: "channelVector4", channelGetValue: "channelValueVector4" }); break; } } } } }