# Indigo Shader Language standard library functions

def doti(vec2 a) real : e0(a)
def dotj(vec2 a) real : e1(a)

def doti(vec3 a) real : e0(a)
def dotj(vec3 a) real : e1(a)
def dotk(vec3 a) real : e2(a)

def mul(vec2 a, real b) vec2 : vec2(e0(a) * b, e1(a) * b)
def mul(vec3 a, real b) vec3 : vec3(e0(a) * b, e1(a) * b, e2(a) * b)

def fract(real x) real : x - floor(x)

def floorToInt(real x) int : truncateToInt(floor(x))
def ceilToInt(real x) int : truncateToInt(ceil(x))

def min(real a, real b) real : if(a < b, a, b)
def max(real a, real b) real : if(a > b, a, b)

def min(int a, int b) int : if(a < b, a, b)
def max(int a, int b) int : if(a > b, a, b)

def min(vec2 a, vec2 b) vec2 : vec2(min(e0(a), e0(b)), min(e1(a), e1(b)))
def max(vec2 a, vec2 b) vec2 : vec2(max(e0(a), e0(b)), max(e1(a), e1(b)))

def min(vec3 a, vec3 b) vec3: vec3(min(doti(a), doti(b)), min(dotj(a), dotj(b)), min(dotk(a), dotk(b)))
def max(vec3 a, vec3 b) vec3: vec3(max(doti(a), doti(b)), max(dotj(a), dotj(b)), max(dotk(a), dotk(b)))

def lerp(real a, real b, real t) real : a * (1.0 - t) + b * t
def lerp(vec2 a, vec2 b, real t) vec2 : a * (1.0 - t) + b * t
def lerp(vec3 a, vec3 b, real t) vec3 : a * (1.0 - t) + b * t

def clamp(int x, int lo, int hi) int : min(hi, max(x, lo))
def clamp(real x, real lo, real hi) real : min(hi, max(x, lo))
def clamp(vec2 x, vec2 lo, vec2 hi) vec2 : vec2(clamp(doti(x), doti(lo), doti(hi)), clamp(dotj(x), dotj(lo), dotj(hi)))
def clamp(vec3 x, vec3 lo, vec3 hi) vec3 : vec3(clamp(doti(x), doti(lo), doti(hi)), clamp(dotj(x), dotj(lo), dotj(hi)), clamp(dotk(x), dotk(lo), dotk(hi)))

def vec2(real x) vec2 : vec2(x, x)
def vec3(real x) vec3 : vec3(x, x, x)

def dot(vec2 a, vec2 b) real : e0(a) * e0(b) + e1(a) * e1(b)
def dot(vec3 a, vec3 b) real : e0(a) * e0(b) + e1(a) * e1(b) + e2(a) * e2(b)

def cross(vec3 a, vec3 b) vec3 : vec3(
	e1(a) * e2(b) - e2(a) * e1(b),
	e2(a) * e0(b) - e0(a) * e2(b),
	e0(a) * e1(b) - e1(a) * e0(b)
	)

def length(vec2 a) real : sqrt(dot(a, a))
def length(vec3 a) real : sqrt(dot(a, a))

def neg(real x) real : x * -1.0
def recip(real x) real : 1.0 / x

def neg(vec2 a) vec2 : vec2(neg(doti(a)), neg(dotj(a)))
def neg(vec3 a) vec3 : vec3(neg(doti(a)), neg(dotj(a)), neg(dotk(a)))

def normalise(vec2 a) vec2 : a * recip(length(a))
def normalise(vec3 a) vec3 : a * recip(length(a))

def eq(vec2 a, vec2 b) bool : e0(a) == e0(b) && e1(a) == e1(b)
def eq(vec3 a, vec3 b) bool : e0(a) == e0(b) && e1(a) == e1(b) && e2(a) == e2(b)
def eq(mat2x2 a, mat2x2 b) bool : e0(a) == e0(b) && e1(a) == e1(b) && e2(a) == e2(b) && e3(a) == e3(b)
def eq(mat3x3 a, mat3x3 b) bool : e0(a) == e0(b) && e1(a) == e1(b) && e2(a) == e2(b) && e3(a) == e3(b) && e4(a) == e4(b) && e5(a) == e5(b) && e6(a) == e6(b) && e7(a) == e7(b) && e8(a) == e8(b)
def neq(vec2 a, vec2 b) bool : not(a == b)
def neq(vec3 a, vec3 b) bool : not(a == b)

def noise(real x) real : noise(x, 0.0, 0.0)
def noise(vec2 a) real : noise(e0(a), e1(a), 0.0)
def noise(vec3 a) real : noise(e0(a), e1(a), e2(a))

def fbm(real x, int num_octaves) real : fbm(x, 0.0, 0.0, num_octaves)
def fbm(vec2 a, int num_octaves) real : fbm(e0(a), e1(a), 0.0, num_octaves)
def fbm(vec3 a, int num_octaves) real : fbm(e0(a), e1(a), e2(a), num_octaves)
