UNPKG

hydra-synth

Version:
146 lines (129 loc) 5.1 kB
import arrayUtils from './lib/array-utils.js' // [WIP] how to treat different dimensions (?) const DEFAULT_CONVERSIONS = { float: { 'vec4': { name: 'sum', args: [[1, 1, 1, 1]] }, 'vec2': { name: 'sum', args: [[1, 1]] } } } function fillArrayWithDefaults(arr, len) { // fill the array with default values if it's too short while (arr.length < len) { if (arr.length === 3) { // push a 1 as the default for .a in vec4 arr.push(1.0) } else { arr.push(0.0) } } return arr.slice(0, len) } const ensure_decimal_dot = (val) => { val = val.toString() if (val.indexOf('.') < 0) { val += '.' } return val } export default function formatArguments(transform, startIndex, synthContext) { const defaultArgs = transform.transform.inputs const userArgs = transform.userArgs const { generators } = transform.synth const { src } = generators // depends on synth having src() function return defaultArgs.map((input, index) => { const typedArg = { value: input.default, type: input.type, // isUniform: false, name: input.name, vecLen: 0 // generateGlsl: null // function for creating glsl } if (typedArg.type === 'float') typedArg.value = ensure_decimal_dot(input.default) if (input.type.startsWith('vec')) { try { typedArg.vecLen = Number.parseInt(input.type.substr(3)) } catch (e) { console.log(`Error determining length of vector input type ${input.type} (${input.name})`) } } // if user has input something for this argument if (userArgs.length > index) { typedArg.value = userArgs[index] // do something if a composite or transform if (typeof userArgs[index] === 'function') { // if (typedArg.vecLen > 0) { // expected input is a vector, not a scalar // typedArg.value = (context, props, batchId) => (fillArrayWithDefaults(userArgs[index](props), typedArg.vecLen)) // } else { typedArg.value = (context, props, batchId) => { try { const val = userArgs[index](props) if(typeof val === 'number') { return val } else { console.warn('function does not return a number', userArgs[index]) } return input.default } catch (e) { console.warn('ERROR', e) return input.default } } // } typedArg.isUniform = true } else if (userArgs[index].constructor === Array) { // if (typedArg.vecLen > 0) { // expected input is a vector, not a scalar // typedArg.isUniform = true // typedArg.value = fillArrayWithDefaults(typedArg.value, typedArg.vecLen) // } else { // console.log("is Array") // filter out values that are not a number // const filteredArray = userArgs[index].filter((val) => typeof val === 'number') // typedArg.value = (context, props, batchId) => arrayUtils.getValue(filteredArray)(props) typedArg.value = (context, props, batchId) => arrayUtils.getValue(userArgs[index])(props) typedArg.isUniform = true // } } } if (startIndex < 0) { } else { if (typedArg.value && typedArg.value.transforms) { const final_transform = typedArg.value.transforms[typedArg.value.transforms.length - 1] if (final_transform.transform.glsl_return_type !== input.type) { const defaults = DEFAULT_CONVERSIONS[input.type] if (typeof defaults !== 'undefined') { const default_def = defaults[final_transform.transform.glsl_return_type] if (typeof default_def !== 'undefined') { const { name, args } = default_def typedArg.value = typedArg.value[name](...args) } } } typedArg.isUniform = false } else if (typedArg.type === 'float' && typeof typedArg.value === 'number') { typedArg.value = ensure_decimal_dot(typedArg.value) } else if (typedArg.type.startsWith('vec') && typeof typedArg.value === 'object' && Array.isArray(typedArg.value)) { typedArg.isUniform = false typedArg.value = `${typedArg.type}(${typedArg.value.map(ensure_decimal_dot).join(', ')})` } else if (input.type === 'sampler2D') { // typedArg.tex = typedArg.value var x = typedArg.value typedArg.value = () => (x.getTexture()) typedArg.isUniform = true } else { // if passing in a texture reference, when function asks for vec4, convert to vec4 if (typedArg.value.getTexture && input.type === 'vec4') { var x1 = typedArg.value typedArg.value = src(x1) typedArg.isUniform = false } } // add tp uniform array if is a function that will pass in a different value on each render frame, // or a texture/ external source if (typedArg.isUniform) { typedArg.name += startIndex // shaderParams.uniforms.push(typedArg) } } return typedArg }) }