import { BinaryOp, Dyno, TrinaryOp, UnaryOp } from "./base"; import { type AddOutput, type ClampOutput, type DivOutput, type IModOutput, type IsInfOutput, type IsNanOutput, type MaxOutput, type MinOutput, type MixOutput, type ModOutput, type MulOutput, type SmoothstepOutput, type StepOutput, type SubOutput, absOutputType, addOutputType, ceilOutputType, clampOutputType, divOutputType, exp2OutputType, expOutputType, floorOutputType, fractOutputType, imodOutputType, inversesqrtOutputType, isInfOutputType, isNanOutputType, log2OutputType, logOutputType, maxOutputType, minOutputType, mixOutputType, modOutputType, modfOutputType, mulOutputType, negOutputType, powOutputType, roundOutputType, signOutputType, smoothstepOutputType, sqrOutputType, sqrtOutputType, stepOutputType, subOutputType, truncOutputType, } from "./mathTypes"; import type { AllIntTypes, AllSignedTypes, AllValueTypes, BoolTypes, FloatTypes, SignedTypes, ValueTypes, } from "./types"; import { type DynoVal, valType } from "./value"; export const add = ( a: DynoVal, b: DynoVal, ): DynoVal> => new Add({ a, b }); export const sub = ( a: DynoVal, b: DynoVal, ): DynoVal> => new Sub({ a, b }); export const mul = ( a: DynoVal, b: DynoVal, ): DynoVal> => new Mul({ a, b }); export const div = ( a: DynoVal, b: DynoVal, ): DynoVal> => new Div({ a, b }); export const imod = ( a: DynoVal, b: DynoVal, ): DynoVal> => new IMod({ a, b }); export const mod = ( a: DynoVal, b: DynoVal, ): DynoVal> => new Mod({ a, b }); export const modf = (a: DynoVal) => new Modf({ a }).outputs; export const neg = (a: DynoVal): DynoVal => new Neg({ a }); export const abs = (a: DynoVal): DynoVal => new Abs({ a }); export const sign = (a: DynoVal): DynoVal => new Sign({ a }); export const floor = (a: DynoVal): DynoVal => new Floor({ a }); export const ceil = (a: DynoVal): DynoVal => new Ceil({ a }); export const trunc = (a: DynoVal): DynoVal => new Trunc({ a }); export const round = (a: DynoVal): DynoVal => new Round({ a }); export const fract = (a: DynoVal): DynoVal => new Fract({ a }); export const pow = ( a: DynoVal, b: DynoVal, ): DynoVal => new Pow({ a, b }); export const exp = (a: DynoVal): DynoVal => new Exp({ a }); export const exp2 = (a: DynoVal): DynoVal => new Exp2({ a }); export const log = (a: DynoVal): DynoVal => new Log({ a }); export const log2 = (a: DynoVal): DynoVal => new Log2({ a }); export const sqr = (a: DynoVal): DynoVal => new Sqr({ a }); export const sqrt = (a: DynoVal): DynoVal => new Sqrt({ a }); export const inversesqrt = (a: DynoVal): DynoVal => new InverseSqrt({ a }); export const min = ( a: DynoVal, b: DynoVal, ): DynoVal> => new Min({ a, b }); export const max = ( a: DynoVal, b: DynoVal, ): DynoVal> => new Max({ a, b }); export const clamp = ( a: DynoVal, min: DynoVal, max: DynoVal, ): DynoVal> => new Clamp({ a, min, max }); export const mix = ( a: DynoVal, b: DynoVal, t: DynoVal, ): DynoVal> => new Mix({ a, b, t }); export const step = ( edge: DynoVal, x: DynoVal, ): DynoVal> => new Step({ edge, x }); export const smoothstep = ( edge0: DynoVal, edge1: DynoVal, x: DynoVal, ): DynoVal> => new Smoothstep({ edge0, edge1, x }); export const isNan = ( a: DynoVal, ): DynoVal> => new IsNan({ a }); export const isInf = ( a: DynoVal, ): DynoVal> => new IsInf({ a }); export class Add< A extends AllValueTypes, B extends AllValueTypes, > extends BinaryOp, "sum"> { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "sum", outTypeFunc: addOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.sum} = ${inputs.a} + ${inputs.b};`]; }; } } export class Sub< A extends AllValueTypes, B extends AllValueTypes, > extends BinaryOp, "difference"> { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "difference", outTypeFunc: subOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.difference} = ${inputs.a} - ${inputs.b};`]; }; } } export class Mul< A extends AllValueTypes, B extends AllValueTypes, > extends BinaryOp, "product"> { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "product", outTypeFunc: mulOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.product} = ${inputs.a} * ${inputs.b};`]; }; } } export class Div< A extends AllValueTypes, B extends AllValueTypes, > extends BinaryOp, "quotient"> { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "quotient", outTypeFunc: divOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.quotient} = ${inputs.a} / ${inputs.b};`]; }; } } export class IMod< A extends AllIntTypes, B extends AllIntTypes, > extends BinaryOp, "remainder"> { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "remainder", outTypeFunc: imodOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.remainder} = ${inputs.a} % ${inputs.b};`]; }; } } export class Mod extends BinaryOp< A, B, ModOutput, "remainder" > { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "remainder", outTypeFunc: modOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.remainder} = mod(${inputs.a}, ${inputs.b});`]; }; } } export class Modf extends Dyno< { a: A }, { fract: A; integer: A } > { constructor({ a }: { a: DynoVal }) { const inTypes = { a: valType(a) }; const outType = modfOutputType(inTypes.a); const outTypes = { fract: outType, integer: outType, }; super({ inTypes, outTypes, inputs: { a } }); this.statements = ({ inputs, outputs }) => { return [`${outputs.fract} = modf(${inputs.a}, ${outputs.integer});`]; }; } } export class Neg extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "neg", outTypeFunc: negOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.neg} = -${inputs.a};`]; }; } } export class Abs extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "abs", outTypeFunc: absOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.abs} = abs(${inputs.a});`]; }; } } export class Sign extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "sign", outTypeFunc: signOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.sign} = sign(${inputs.a});`]; }; } } export class Floor extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "floor", outTypeFunc: floorOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.floor} = floor(${inputs.a});`]; }; } } export class Ceil extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "ceil", outTypeFunc: ceilOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.ceil} = ceil(${inputs.a});`]; }; } } export class Trunc extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "trunc", outTypeFunc: truncOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.trunc} = trunc(${inputs.a});`]; }; } } export class Round extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "round", outTypeFunc: roundOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.round} = round(${inputs.a});`]; }; } } export class Fract extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "fract", outTypeFunc: fractOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.fract} = fract(${inputs.a});`]; }; } } export class Pow extends BinaryOp { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "power", outTypeFunc: powOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.power} = pow(${inputs.a}, ${inputs.b});`]; }; } } export class Exp extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "exp", outTypeFunc: expOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.exp} = exp(${inputs.a});`]; }; } } export class Exp2 extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "exp2", outTypeFunc: exp2OutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.exp2} = exp2(${inputs.a});`]; }; } } export class Log extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "log", outTypeFunc: logOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.log} = log(${inputs.a});`]; }; } } export class Log2 extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "log2", outTypeFunc: log2OutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.log2} = log2(${inputs.a});`]; }; } } export class Sqr extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "sqr", outTypeFunc: sqrOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.sqr} = ${inputs.a} * ${inputs.a};`]; }; } } export class Sqrt extends UnaryOp { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "sqrt", outTypeFunc: sqrtOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.sqrt} = sqrt(${inputs.a});`]; }; } } export class InverseSqrt extends UnaryOp< A, A, "inversesqrt" > { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "inversesqrt", outTypeFunc: inversesqrtOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.inversesqrt} = inversesqrt(${inputs.a});`]; }; } } export class Min extends BinaryOp< A, B, MinOutput, "min" > { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "min", outTypeFunc: minOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.min} = min(${inputs.a}, ${inputs.b});`]; }; } } export class Max extends BinaryOp< A, B, MaxOutput, "max" > { constructor({ a, b }: { a: DynoVal; b: DynoVal }) { super({ a, b, outKey: "max", outTypeFunc: maxOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.max} = max(${inputs.a}, ${inputs.b});`]; }; } } export class Clamp< A extends ValueTypes, MinMax extends ValueTypes, > extends TrinaryOp, "clamp"> { constructor({ a, min, max, }: { a: DynoVal; min: DynoVal; max: DynoVal }) { super({ a, b: min, c: max, outKey: "clamp", outTypeFunc: clampOutputType, }); this.statements = ({ inputs, outputs }) => { const { a, b: min, c: max } = inputs; return [`${outputs.clamp} = clamp(${a}, ${min}, ${max});`]; }; } } export class Mix< A extends FloatTypes, T extends FloatTypes | BoolTypes, > extends TrinaryOp, "mix"> { constructor({ a, b, t }: { a: DynoVal; b: DynoVal; t: DynoVal }) { super({ a, b, c: t, outKey: "mix", outTypeFunc: mixOutputType }); this.statements = ({ inputs, outputs }) => { const { a, b, c: t } = inputs; return [`${outputs.mix} = mix(${a}, ${b}, ${t});`]; }; } } export class Step< Edge extends FloatTypes, X extends FloatTypes, > extends BinaryOp, "step"> { constructor({ edge, x }: { edge: DynoVal; x: DynoVal }) { super({ a: edge, b: x, outKey: "step", outTypeFunc: stepOutputType, }); this.statements = ({ inputs, outputs }) => { const { a: edge, b: x } = inputs; return [`${outputs.step} = step(${edge}, ${x});`]; }; } } export class Smoothstep< X extends FloatTypes, Edge extends X | "float", > extends TrinaryOp< Edge, Edge, X, SmoothstepOutput, "smoothstep" > { constructor({ edge0, edge1, x, }: { edge0: DynoVal; edge1: DynoVal; x: DynoVal }) { super({ a: edge0, b: edge1, c: x, outKey: "smoothstep", outTypeFunc: smoothstepOutputType, }); this.statements = ({ inputs, outputs }) => { const { a: edge0, b: edge1, c: x } = inputs; return [`${outputs.smoothstep} = smoothstep(${edge0}, ${edge1}, ${x});`]; }; } } export class IsNan extends UnaryOp< A, IsNanOutput, "isNan" > { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "isNan", outTypeFunc: isNanOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.isNan} = isNan(${inputs.a});`]; }; } } export class IsInf extends UnaryOp< A, IsInfOutput, "isInf" > { constructor({ a }: { a: DynoVal }) { super({ a, outKey: "isInf", outTypeFunc: isInfOutputType }); this.statements = ({ inputs, outputs }) => { return [`${outputs.isInf} = isInf(${inputs.a});`]; }; } }