import Node, { IntegerType, NumType } from "../core/Node.js"; import TempNode from "../core/TempNode.js"; export type OperatorNodeOp = | "%" | "&" | "|" | "^" | ">>" | "<<" | "==" | "!=" | "&&" | "||" | "^^" | "<" | ">" | "<=" | ">=" | "+" | "-" | "*" | "/"; export default class OperatorNode extends TempNode { aNode: Node; bNode: Node; op: OperatorNodeOp; readonly isOperatorNode: true; constructor(op: OperatorNodeOp, ...params: [Node, Node, ...Node[]]); } type Vec2OrLess = Node<"vec2">; type Vec3OrLess = Vec2OrLess | Node<"vec3">; type Vec4OrLess = Vec3OrLess | Node<"vec4">; interface NumberToVec { float: "vec"; int: "ivec"; uint: "uvec"; } type NumberToVec2 = `${NumberToVec[TNum]}2`; type NumberToVec3 = `${NumberToVec[TNum]}3`; type NumberToVec4 = `${NumberToVec[TNum]}4`; type Number = AnyNumber; // FIXME Number | number type Vec2OrLessOrNumber = Number | Node>; type Vec3OrLessOrNumber = Vec2OrLessOrNumber | Node>; type Vec4OrLessOrNumber = Vec3OrLessOrNumber | Node>; type AnyNumber = Node<"float"> | Node<"int"> | Node<"uint"> | number; // add/sub/mul/div // add/sub/mul/div numbers and/or vecs // Every parameter gets converted to the longest type // If the parameters are the same length, it gets converted to the first type // FIXME We handle the case of converting number types, but not converting between vectors of different number types interface AddSubMulDivNumberVec { (a: Number, b: AnyNumber, ...params: AnyNumber[]): Node; ( a: Vec2OrLessOrNumber, b: Vec2OrLessOrNumber, ...params: Vec2OrLessOrNumber[] ): Node>; ( a: Vec3OrLessOrNumber, b: Vec3OrLessOrNumber, ...params: Vec3OrLessOrNumber[] ): Node>; ( a: Vec4OrLessOrNumber, b: Vec4OrLessOrNumber, ...params: Vec4OrLessOrNumber[] ): Node>; } interface AddSubMulDivNumberVecNumExtensions { (b: AnyNumber, ...params: AnyNumber[]): Node; (b: Vec2OrLessOrNumber, ...params: Vec2OrLessOrNumber[]): Node>; (b: Vec3OrLessOrNumber, ...params: Vec3OrLessOrNumber[]): Node>; (b: Vec4OrLessOrNumber, ...params: Vec4OrLessOrNumber[]): Node>; } interface AddSubMulDivNumberVecNumberAssignExtensions { ( b: Vec4OrLessOrNumber<"float"> | Vec4OrLessOrNumber<"int"> | Vec4OrLessOrNumber<"uint">, ...params: (Vec4OrLessOrNumber<"float"> | Vec4OrLessOrNumber<"int"> | Vec4OrLessOrNumber<"uint">)[] ): this; } interface AddSubMulDivNumberVecVec2Extensions { (b: Vec2OrLessOrNumber, ...params: Vec2OrLessOrNumber[]): Node>; (b: Vec3OrLessOrNumber, ...params: Vec3OrLessOrNumber[]): Node>; (b: Vec4OrLessOrNumber, ...params: Vec4OrLessOrNumber[]): Node>; } interface AddSubMulDivNumberVecVec2AssignExtensions { (b: Vec4OrLessOrNumber, ...params: Vec4OrLessOrNumber[]): this; } interface AddSubMulDivNumberVecVec3Extensions { (b: Vec3OrLessOrNumber, ...params: Vec3OrLessOrNumber[]): Node>; (b: Vec4OrLessOrNumber, ...params: Vec4OrLessOrNumber[]): Node>; } interface AddSubMulDivNumberVecVec3AssignExtensions { (b: Vec4OrLessOrNumber, ...params: Vec4OrLessOrNumber[]): this; } interface AddSubMulDivNumberVecVec4Extensions { (b: Vec4OrLessOrNumber, ...params: Vec4OrLessOrNumber[]): Node>; } interface AddSubMulDivNumberVecVec4AssignExtensions { (b: Vec4OrLessOrNumber, ...params: Vec4OrLessOrNumber[]): this; } // add/sub/mul mats interface AddSubMulMat { (a: Node<"mat2">, b: Node<"mat2">): Node<"mat2">; (a: Node<"mat3">, b: Node<"mat3">): Node<"mat3">; (a: Node<"mat4">, b: Node<"mat4">): Node<"mat4">; } interface AddSubMulMat2Extensions { (b: Node<"mat2">): Node<"mat2">; } interface AddSubMulMat2AssignExtensions { (b: Node<"mat2">): this; } interface AddSubMulMat3Extensions { (b: Node<"mat3">): Node<"mat3">; } interface AddSubMulMat3AssignExtensions { (b: Node<"mat3">): this; } interface AddSubMulMat4Extensions { (b: Node<"mat4">): Node<"mat4">; } interface AddSubMulMat4AssignExtensions { (b: Node<"mat3">): this; } // mut mats and vecs // The vec parameter gets converted to matrix length interface MulMatVec { (a: Node<"mat2">, b: Vec4OrLess): Node<"vec2">; (a: Node<"mat3">, b: Vec4OrLess): Node<"vec3">; (a: Node<"mat4">, b: Vec4OrLess): Node<"vec4">; (a: Vec4OrLess, b: Node<"mat2">): Node<"vec2">; (a: Vec4OrLess, b: Node<"mat3">): Node<"vec3">; (a: Vec4OrLess, b: Node<"mat4">): Node<"vec4">; } interface MulVecMatMat2Extensions { (b: Vec4OrLess): Node<"vec2">; } interface MulVecMatMat3Extensions { (b: Vec4OrLess): Node<"vec3">; } interface MulVecMatMat4Extensions { (b: Vec4OrLess): Node<"vec4">; } interface MulVecMatVecExtensions { (b: Node<"mat2">): Node<"vec2">; (b: Node<"mat3">): Node<"vec3">; (b: Node<"mat4">): Node<"vec4">; } // Exports interface AddSub extends AddSubMulDivNumberVec<"float">, AddSubMulDivNumberVec<"int">, AddSubMulDivNumberVec<"uint">, AddSubMulMat {} export const add: AddSub; export const sub: AddSub; interface Mul extends AddSubMulDivNumberVec<"float">, AddSubMulDivNumberVec<"int">, AddSubMulDivNumberVec<"uint">, AddSubMulMat, MulMatVec { } interface MulVec2Extensions extends AddSubMulDivNumberVecVec2Extensions, MulVecMatVecExtensions { } interface MulVec3Extensions extends AddSubMulDivNumberVecVec3Extensions, MulVecMatVecExtensions { } interface MulVec4Extensions extends AddSubMulDivNumberVecVec4Extensions, MulVecMatVecExtensions { } interface MulMat2Extensions extends AddSubMulMat2Extensions, MulVecMatMat2Extensions { } interface MulMat3Extensions extends AddSubMulMat3Extensions, MulVecMatMat3Extensions { } interface MulMat4Extensions extends AddSubMulMat4Extensions, MulVecMatMat4Extensions { } export const mul: Mul; interface Div extends AddSubMulDivNumberVec<"float">, AddSubMulDivNumberVec<"int">, AddSubMulDivNumberVec<"uint"> { } export const div: Div; declare module "../core/Node.js" { interface FloatExtensions { mul: (b: Node<"color">) => Node<"vec3">; } interface NumExtensions { add: AddSubMulDivNumberVecNumExtensions; sub: AddSubMulDivNumberVecNumExtensions; mul: AddSubMulDivNumberVecNumExtensions; div: AddSubMulDivNumberVecNumExtensions; addAssign: AddSubMulDivNumberVecNumberAssignExtensions; subAssign: AddSubMulDivNumberVecNumberAssignExtensions; mulAssign: AddSubMulDivNumberVecNumberAssignExtensions; divAssign: AddSubMulDivNumberVecNumberAssignExtensions; } interface Vec2Extensions { add: (b: Node<"color">) => Node<"vec3">; mul: (b: Node<"color">) => Node<"vec3">; } interface Vec3Extensions { add: (b: Node<"color">) => Node<"vec3">; mul: (b: Node<"color">) => Node<"vec3">; } interface Vec4Extensions { add: (b: Node<"color">) => Node<"vec4">; mul: (b: Node<"color">) => Node<"vec4">; } interface ColorExtensions { add: (b: Number<"float">) => Node<"vec3">; sub: (b: Number<"float">) => Node<"vec3">; mul: (b: Number<"float">) => Node<"vec3">; div: (b: Number<"float">) => Node<"vec3">; } interface NumVec2Extensions { add: AddSubMulDivNumberVecVec2Extensions; sub: AddSubMulDivNumberVecVec2Extensions; mul: MulVec2Extensions; div: AddSubMulDivNumberVecVec2Extensions; addAssign: AddSubMulDivNumberVecVec2AssignExtensions; subAssign: AddSubMulDivNumberVecVec2AssignExtensions; mulAssign: AddSubMulDivNumberVecVec2AssignExtensions; divAssign: AddSubMulDivNumberVecVec2AssignExtensions; } interface NumVec3Extensions { add: AddSubMulDivNumberVecVec3Extensions; sub: AddSubMulDivNumberVecVec3Extensions; mul: MulVec3Extensions; div: AddSubMulDivNumberVecVec3Extensions; addAssign: AddSubMulDivNumberVecVec3AssignExtensions; subAssign: AddSubMulDivNumberVecVec3AssignExtensions; mulAssign: AddSubMulDivNumberVecVec3AssignExtensions; divAssign: AddSubMulDivNumberVecVec3AssignExtensions; } interface NumVec4Extensions { add: AddSubMulDivNumberVecVec4Extensions; sub: AddSubMulDivNumberVecVec4Extensions; mul: MulVec4Extensions; div: AddSubMulDivNumberVecVec4Extensions; addAssign: AddSubMulDivNumberVecVec4AssignExtensions; subAssign: AddSubMulDivNumberVecVec4AssignExtensions; mulAssign: AddSubMulDivNumberVecVec4AssignExtensions; divAssign: AddSubMulDivNumberVecVec4AssignExtensions; } interface Mat2Extensions { add: AddSubMulMat2Extensions; sub: AddSubMulMat2Extensions; mul: MulMat2Extensions; addAssign: AddSubMulMat2AssignExtensions; subAssign: AddSubMulMat2AssignExtensions; mulAssign: AddSubMulMat2AssignExtensions; } interface Mat3Extensions { add: AddSubMulMat3Extensions; sub: AddSubMulMat3Extensions; mul: MulMat3Extensions; addAssign: AddSubMulMat3AssignExtensions; subAssign: AddSubMulMat3AssignExtensions; mulAssign: AddSubMulMat3AssignExtensions; } interface Mat4Extensions { add: AddSubMulMat4Extensions; sub: AddSubMulMat4Extensions; mul: MulMat4Extensions; addAssign: AddSubMulMat4AssignExtensions; subAssign: AddSubMulMat4AssignExtensions; mulAssign: AddSubMulMat4AssignExtensions; } } // mod interface Mod { (a: Number<"float">, b: Vec4OrLessOrNumber<"float">): Node<"float">; (a: Node<"vec2">, b: Vec4OrLessOrNumber<"float">): Node<"vec2">; (a: Node<"vec3">, b: Vec4OrLessOrNumber<"float">): Node<"vec3">; (a: Node<"vec4">, b: Vec4OrLessOrNumber<"float">): Node<"vec4">; (a: Number<"int">, b: Vec4OrLessOrNumber<"int">): Node<"int">; (a: Node<"ivec2">, b: Vec4OrLessOrNumber<"int">): Node<"ivec2">; (a: Node<"ivec3">, b: Vec4OrLessOrNumber<"int">): Node<"ivec3">; (a: Node<"ivec4">, b: Vec4OrLessOrNumber<"int">): Node<"ivec4">; (a: Number<"uint">, b: Vec4OrLessOrNumber<"uint">): Node<"uint">; (a: Node<"uvec2">, b: Vec4OrLessOrNumber<"uint">): Node<"uvec2">; (a: Node<"uvec3">, b: Vec4OrLessOrNumber<"uint">): Node<"uvec3">; (a: Node<"uvec4">, b: Vec4OrLessOrNumber<"uint">): Node<"uvec4">; } export const mod: Mod; declare module "../core/Node.js" { interface NumExtensions { mod: (b: Vec4OrLessOrNumber) => Node; modAssign: (b: Vec4OrLessOrNumber) => this; } interface NumVec2Extensions { mod: (b: Vec4OrLessOrNumber) => Node>; modAssign: (b: Vec4OrLessOrNumber) => this; } interface NumVec3Extensions { mod: (b: Vec4OrLessOrNumber) => Node>; modAssign: (b: Vec4OrLessOrNumber) => this; } interface NumVec4Extensions { mod: (b: Vec4OrLessOrNumber) => Node>; modAssign: (b: Vec4OrLessOrNumber) => this; } } // Comparison operators interface ComparisonOperator { (a: Number<"float">, b: Number<"float">): Node<"bool">; (a: Number<"int"> | Number<"uint">, b: Number<"int"> | Number<"uint">): Node<"bool">; } export const equal: ComparisonOperator; export const notEqual: ComparisonOperator; export const lessThan: ComparisonOperator; export const greaterThan: ComparisonOperator; export const lessThanEqual: ComparisonOperator; export const greaterThanEqual: ComparisonOperator; interface ComparisonOperatorNumExtensions { (b: Number): Node<"bool">; } declare module "../core/Node.js" { interface FloatExtensions { equal: ComparisonOperatorNumExtensions<"float">; notEqual: ComparisonOperatorNumExtensions<"float">; lessThan: ComparisonOperatorNumExtensions<"float">; greaterThan: ComparisonOperatorNumExtensions<"float">; lessThanEqual: ComparisonOperatorNumExtensions<"float">; greaterThanEqual: ComparisonOperatorNumExtensions<"float">; } interface IntExtensions { equal: (b: Number<"int"> | Number<"uint">) => Node<"bool">; notEqual: (b: Number<"int"> | Number<"uint">) => Node<"bool">; lessThan: (b: Number<"int"> | Number<"uint">) => Node<"bool">; greaterThan: (b: Number<"int"> | Number<"uint">) => Node<"bool">; lessThanEqual: (b: Number<"int"> | Number<"uint">) => Node<"bool">; greaterThanEqual: (b: Number<"int"> | Number<"uint">) => Node<"bool">; } interface UintExtensions { equal: (b: Number<"int"> | Number<"uint">) => Node<"bool">; notEqual: (b: Number<"int"> | Number<"uint">) => Node<"bool">; lessThan: (b: Number<"int"> | Number<"uint">) => Node<"bool">; greaterThan: (b: Number<"int"> | Number<"uint">) => Node<"bool">; lessThanEqual: (b: Number<"int"> | Number<"uint">) => Node<"bool">; greaterThanEqual: (b: Number<"int"> | Number<"uint">) => Node<"bool">; } } // and/or/not/xor interface AndOr { (a: Node<"bool">, b: Node<"bool">, ...params: Node<"bool">[]): Node<"bool">; } export const and: AndOr; export const or: AndOr; interface AndOrBoolExtensions { (b: Node<"bool">, ...params: Node<"bool">[]): Node<"bool">; } export const not: (a: Node<"bool">) => Node<"bool">; export const xor: (a: Node<"bool">, b: Node<"bool">) => Node<"bool">; declare module "../core/Node.js" { interface BoolExtensions { and: AndOrBoolExtensions; or: AndOrBoolExtensions; not: () => Node<"bool">; xor: (b: Node<"bool">) => Node<"bool">; } } // bit operators interface UnaryBitOperator { (a: Number<"int">): Node<"int">; (a: Number<"uint">): Node<"uint">; } interface BinaryBitOperator { (a: Number<"int">, b: Number<"int">): Node<"int">; (a: Number<"uint">, b: Number<"uint">): Node<"uint">; } export const bitAnd: BinaryBitOperator; export const bitNot: UnaryBitOperator; export const bitOr: BinaryBitOperator; export const bitXor: BinaryBitOperator; export const shiftLeft: BinaryBitOperator; export const shiftRight: BinaryBitOperator; interface BinaryBitOperatorIntegerExtensions { (b: Number): Node; } interface BinaryBitOperatorIntegerAssignExtensions { (b: Number): this; } declare module "../core/Node.js" { interface IntegerExtensions { bitAnd: BinaryBitOperatorIntegerExtensions; bitNot: () => Node; bitOr: BinaryBitOperatorIntegerExtensions; bitXor: BinaryBitOperatorIntegerExtensions; shiftLeft: BinaryBitOperatorIntegerExtensions; shiftRight: BinaryBitOperatorIntegerExtensions; bitAndAssign: BinaryBitOperatorIntegerAssignExtensions; bitNotAssign: () => this; bitOrAssign: BinaryBitOperatorIntegerAssignExtensions; bitXorAssign: BinaryBitOperatorIntegerAssignExtensions; shiftLeftAssign: BinaryBitOperatorIntegerAssignExtensions; shiftRightAssign: BinaryBitOperatorIntegerAssignExtensions; } } // increment/decrement interface IncrementDecrement { (a: Number<"int">): Node<"int">; (a: Number<"uint">): Node<"uint">; } export const incrementBefore: IncrementDecrement; export const decrementBefore: IncrementDecrement; export const increment: IncrementDecrement; export const decrement: IncrementDecrement; interface IncrementDecrementIntegerExtensions { (): Node; } declare module "../core/Node.js" { interface IntegerExtensions { incrementBefore: IncrementDecrementIntegerExtensions; decrementBefore: IncrementDecrementIntegerExtensions; increment: IncrementDecrementIntegerExtensions; decrement: IncrementDecrementIntegerExtensions; } } /** * @deprecated "modInt()" is deprecated. Use "mod( int( ... ) )" instead. */ export const modInt: Mod; declare module "../core/Node.js" { interface NumExtensions { /** * @deprecated "modInt()" is deprecated. Use "mod( int( ... ) )" instead. */ modInt: (b: Number) => Node; /** * @deprecated "modInt()" is deprecated. Use "mod( int( ... ) )" instead. */ modIntAssign: (b: Number) => this; } } export {};