import { Dictionary } from "../common" ; import { Quaternion , Vector2 , Vector3 } from "../common" ; import * as Specification from "../specification" ; export type IntrinsicFunction = ( ... args : Specification . Value [ ] ) => Specification . Value ; export interface IntrinsicFunctionInfo { internalName ? : string ; name : string ; argTypes : string [ ] ; returnType : string ; javascriptImplementation : ( ... args : Specification . Value [ ] ) => Specification . Value ; } export interface TypeConversionInfo { internalName : string ; rank : number ; } export interface ConstantInfo { name : string ; type : string ; value : Specification . Value ; } let intrinsicFunctions = new Dictionary < IntrinsicFunctionInfo > ( ) ; let intrinsicFunctionList = [ ] ; let typeConversions = new Dictionary < TypeConversionInfo > ( ) ; let constants = new Dictionary < ConstantInfo > ( ) ; export function getInternalName ( func ) { return `@${ func . name }:${ func . argTypes . join ( "," ) }:${ func . returnType }` ; } export function getIntrinsicFunction ( internalName ) { if ( ! intrinsicFunctions . has ( internalName ) ) { console . log ( internalName ) ; } return intrinsicFunctions . get ( internalName ) ; } export function forEachIntrinsicFunction ( callback ) { intrinsicFunctionList . forEach ( callback ) ; } export function addIntrinsicFunction ( func ) { func . internalName = getInternalName ( func ) ; intrinsicFunctions . set ( func . internalName , func ) ; intrinsicFunctionList . push ( func ) ; } export function addConstant ( name , type , value ) { let constant = { name : name , type : type , value : value } ; constants . set ( name , constant ) ; } export function forEachConstant ( callback ) { constants . forEach ( callback ) ; } export function forEachTypeConversion ( callback ) { typeConversions . forEach ( callback ) ; } export function getTypeConversion ( srcType , destType ) { return typeConversions . get ( `${ srcType }:${ destType }` ) ; } function RegisterTypeConversion ( srcType , destType , rank , func ) { let name = `cast:${ srcType }:${ destType }` ; let info = { name : name , argTypes : [ srcType ] , returnType : destType , javascriptImplementation : func } ; addIntrinsicFunction ( info ) ; typeConversions . set ( `${ srcType }:${ destType }` , { internalName : info . internalName , rank : rank } ) ; } function RegisterFunction ( name , argTypes , returnType , func ) { addIntrinsicFunction ( { name : name , argTypes : argTypes , returnType : returnType , javascriptImplementation : func } ) ; } function RegisterOperator ( name , argTypes , returnType , func ) { addIntrinsicFunction ( { name : `@${ name }` , argTypes : argTypes , returnType : returnType , javascriptImplementation : func } ) ; } function not_implemented ( ) { throw new Error ( "not implemented" ) ; } let RegisterConstructor = ( type , srcTypes , func ) => RegisterFunction ( type , srcTypes , type , func ) ; RegisterOperator ( "+" , [ "float" , "float" ] , "float" , ( a , b ) => a + b ) ; RegisterOperator ( "-" , [ "float" , "float" ] , "float" , ( a , b ) => a - b ) ; RegisterOperator ( "*" , [ "float" , "float" ] , "float" , ( a , b ) => a * b ) ; RegisterOperator ( "/" , [ "float" , "float" ] , "float" , ( a , b ) => a / b ) ; RegisterOperator ( "+" , [ "float" ] , "float" , ( a ) => + a ) ; RegisterOperator ( "-" , [ "float" ] , "float" , ( a ) => - a ) ; RegisterOperator ( "%" , [ "int" , "int" ] , "int" , ( a , b ) => a % b ) ; RegisterOperator ( "%" , [ "float" , "float" ] , "float" , ( a , b ) => a % b ) ; RegisterOperator ( "+" , [ "int" , "int" ] , "int" , ( a , b ) => a + b ) ; RegisterOperator ( "-" , [ "int" , "int" ] , "int" , ( a , b ) => a - b ) ; RegisterOperator ( "*" , [ "int" , "int" ] , "int" , ( a , b ) => a * b ) ; RegisterOperator ( "/" , [ "int" , "int" ] , "int" , ( a , b ) => a / b ) ; RegisterOperator ( "+" , [ "int" ] , "int" , ( a ) => + a ) ; RegisterOperator ( "-" , [ "int" ] , "int" , ( a ) => - a ) ; RegisterOperator ( "+" , [ "Vector2" , "Vector2" ] , "Vector2" , ( a , b ) => [ a [ 0 ] + b [ 0 ] , a [ 1 ] + b [ 1 ] ] ) ; RegisterOperator ( "-" , [ "Vector2" , "Vector2" ] , "Vector2" , ( a , b ) => [ a [ 0 ] - b [ 0 ] , a [ 1 ] - b [ 1 ] ] ) ; RegisterOperator ( "*" , [ "Vector2" , "Vector2" ] , "Vector2" , ( a , b ) => [ a [ 0 ] * b [ 0 ] , a [ 1 ] * b [ 1 ] ] ) ; RegisterOperator ( "/" , [ "Vector2" , "Vector2" ] , "Vector2" , ( a , b ) => [ a [ 0 ] / b [ 0 ] , a [ 1 ] / b [ 1 ] ] ) ; RegisterOperator ( "+" , [ "Vector2" ] , "Vector2" , ( a ) => a ) ; RegisterOperator ( "-" , [ "Vector2" ] , "Vector2" , ( a ) => [ - a [ 0 ] , - a [ 1 ] ] ) ; RegisterOperator ( "+" , [ "Vector3" , "Vector3" ] , "Vector3" , ( a , b ) => [ a [ 0 ] + b [ 0 ] , a [ 1 ] + b [ 1 ] , a [ 2 ] + b [ 2 ] ] ) ; RegisterOperator ( "-" , [ "Vector3" , "Vector3" ] , "Vector3" , ( a , b ) => [ a [ 0 ] - b [ 0 ] , a [ 1 ] - b [ 1 ] , a [ 2 ] - b [ 2 ] ] ) ; RegisterOperator ( "*" , [ "Vector3" , "Vector3" ] , "Vector3" , ( a , b ) => [ a [ 0 ] * b [ 0 ] , a [ 1 ] * b [ 1 ] , a [ 2 ] * b [ 2 ] ] ) ; RegisterOperator ( "/" , [ "Vector3" , "Vector3" ] , "Vector3" , ( a , b ) => [ a [ 0 ] / b [ 0 ] , a [ 1 ] / b [ 1 ] , a [ 2 ] / b [ 2 ] ] ) ; RegisterOperator ( "+" , [ "Vector3" ] , "Vector3" , ( a ) => a ) ; RegisterOperator ( "-" , [ "Vector3" ] , "Vector3" , ( a ) => [ - a [ 0 ] , - a [ 1 ] , - a [ 2 ] ] ) ; RegisterOperator ( "+" , [ "Vector4" , "Vector4" ] , "Vector4" , ( a , b ) => [ a [ 0 ] + b [ 0 ] , a [ 1 ] + b [ 1 ] , a [ 2 ] + b [ 2 ] , a [ 3 ] + b [ 3 ] ] ) ; RegisterOperator ( "-" , [ "Vector4" , "Vector4" ] , "Vector4" , ( a , b ) => [ a [ 0 ] - b [ 0 ] , a [ 1 ] - b [ 1 ] , a [ 2 ] - b [ 2 ] , a [ 3 ] - b [ 3 ] ] ) ; RegisterOperator ( "*" , [ "Vector4" , "Vector4" ] , "Vector4" , ( a , b ) => [ a [ 0 ] * b [ 0 ] , a [ 1 ] * b [ 1 ] , a [ 2 ] * b [ 2 ] , a [ 3 ] * b [ 3 ] ] ) ; RegisterOperator ( "/" , [ "Vector4" , "Vector4" ] , "Vector4" , ( a , b ) => [ a [ 0 ] / b [ 0 ] , a [ 1 ] / b [ 1 ] , a [ 2 ] / b [ 2 ] , a [ 3 ] / b [ 3 ] ] ) ; RegisterOperator ( "+" , [ "Vector4" ] , "Vector4" , ( a ) => a ) ; RegisterOperator ( "-" , [ "Vector4" ] , "Vector4" , ( a ) => [ - a [ 0 ] , - a [ 1 ] , - a [ 2 ] , - a [ 3 ] ] ) ; RegisterOperator ( "*" , [ "float" , "Vector2" ] , "Vector2" , ( a , b ) => [ a * b [ 0 ] , a * b [ 1 ] ] ) ; RegisterOperator ( "*" , [ "Vector2" , "float" ] , "Vector2" , ( a , b ) => [ a [ 0 ] * b , a [ 1 ] * b ] ) ; RegisterOperator ( "*" , [ "Vector2" , "float" ] , "Vector2" , ( a , b ) => [ a [ 0 ] / b , a [ 1 ] / b ] ) ; RegisterOperator ( "*" , [ "float" , "Vector3" ] , "Vector3" , ( a , b ) => [ a * b [ 0 ] , a * b [ 1 ] , a * b [ 2 ] ] ) ; RegisterOperator ( "*" , [ "Vector3" , "float" ] , "Vector3" , ( a , b ) => [ a [ 0 ] * b , a [ 1 ] * b , a [ 2 ] * b ] ) ; RegisterOperator ( "*" , [ "Vector3" , "float" ] , "Vector3" , ( a , b ) => [ a [ 0 ] / b , a [ 1 ] / b , a [ 2 ] / b ] ) ; RegisterOperator ( "*" , [ "float" , "Vector4" ] , "Vector4" , ( a , b ) => [ a * b [ 0 ] , a * b [ 1 ] , a * b [ 2 ] , a * b [ 3 ] ] ) ; RegisterOperator ( "*" , [ "Vector4" , "float" ] , "Vector4" , ( a , b ) => [ a [ 0 ] * b , a [ 1 ] * b , a [ 2 ] * b , a [ 3 ] * b ] ) ; RegisterOperator ( "*" , [ "Vector4" , "float" ] , "Vector4" , ( a , b ) => [ a [ 0 ] / b , a [ 1 ] / b , a [ 2 ] / b , a [ 3 ] / b ] ) ; RegisterOperator ( "==" , [ "float" , "float" ] , "bool" , ( a , b ) => a == b ? 1 : 0 ) ; RegisterOperator ( ">" , [ "float" , "float" ] , "bool" , ( a , b ) => a > b ? 1 : 0 ) ; RegisterOperator ( "<" , [ "float" , "float" ] , "bool" , ( a , b ) => a < b ? 1 : 0 ) ; RegisterOperator ( ">=" , [ "float" , "float" ] , "bool" , ( a , b ) => a >= b ? 1 : 0 ) ; RegisterOperator ( "<=" , [ "float" , "float" ] , "bool" , ( a , b ) => a <= b ? 1 : 0 ) ; RegisterOperator ( "==" , [ "int" , "int" ] , "bool" , ( a , b ) => a == b ? 1 : 0 ) ; RegisterOperator ( ">" , [ "int" , "int" ] , "bool" , ( a , b ) => a > b ? 1 : 0 ) ; RegisterOperator ( "<" , [ "int" , "int" ] , "bool" , ( a , b ) => a < b ? 1 : 0 ) ; RegisterOperator ( ">=" , [ "int" , "int" ] , "bool" , ( a , b ) => a >= b ? 1 : 0 ) ; RegisterOperator ( "<=" , [ "int" , "int" ] , "bool" , ( a , b ) => a <= b ? 1 : 0 ) ; RegisterOperator ( "==" , [ "bool" , "bool" ] , "bool" , ( a , b ) => a == b ? 1 : 0 ) ; RegisterOperator ( "!" , [ "bool" ] , "bool" , ( a ) => ! a ? 1 : 0 ) ; RegisterOperator ( "&&" , [ "bool" , "bool" ] , "bool" , ( a , b ) => a && b ? 1 : 0 ) ; RegisterOperator ( "||" , [ "bool" , "bool" ] , "bool" , ( a , b ) => a || b ? 1 : 0 ) ; RegisterConstructor ( "Vector2" , [ "float" , "float" ] , ( a , b ) => [ a , b ] ) ; RegisterConstructor ( "Vector3" , [ "float" , "float" , "float" ] , ( a , b , c ) => [ a , b , c ] ) ; RegisterConstructor ( "Vector4" , [ "float" , "float" , "float" , "float" ] , ( a , b , c , d ) => [ a , b , c , d ] ) ; RegisterConstructor ( "Color" , [ "float" , "float" , "float" , "float" ] , ( a , b , c , d ) => [ a , b , c , d ] ) ; RegisterConstructor ( "Quaternion" , [ "float" , "float" , "float" , "float" ] , ( a , b , c , d ) => [ a , b , c , d ] ) ; RegisterFunction ( "abs" , [ "float" ] , "float" , ( a ) => Math . abs ( a ) ) ; RegisterFunction ( "sqrt" , [ "float" ] , "float" , ( a ) => Math . sqrt ( a ) ) ; RegisterFunction ( "exp" , [ "float" ] , "float" , ( a ) => Math . exp ( a ) ) ; RegisterFunction ( "log" , [ "float" ] , "float" , ( a ) => Math . log ( a ) ) ; RegisterFunction ( "sin" , [ "float" ] , "float" , ( a ) => Math . sin ( a ) ) ; RegisterFunction ( "cos" , [ "float" ] , "float" , ( a ) => Math . cos ( a ) ) ; RegisterFunction ( "tan" , [ "float" ] , "float" , ( a ) => Math . tan ( a ) ) ; RegisterFunction ( "asin" , [ "float" ] , "float" , ( a ) => Math . asin ( a ) ) ; RegisterFunction ( "acos" , [ "float" ] , "float" , ( a ) => Math . acos ( a ) ) ; RegisterFunction ( "atan" , [ "float" ] , "float" , ( a ) => Math . atan ( a ) ) ; RegisterFunction ( "atan2" , [ "float" , "float" ] , "float" , ( a , b ) => Math . atan2 ( a , b ) ) ; RegisterFunction ( "abs" , [ "int" ] , "int" , ( a ) => Math . abs ( a ) ) ; RegisterFunction ( "min" , [ "int" , "int" ] , "int" , ( a , b ) => Math . min ( a , b ) ) ; RegisterFunction ( "max" , [ "int" , "int" ] , "int" , ( a , b ) => Math . max ( a , b ) ) ; RegisterFunction ( "min" , [ "float" , "float" ] , "float" , ( a , b ) => Math . min ( a , b ) ) ; RegisterFunction ( "max" , [ "float" , "float" ] , "float" , ( a , b ) => Math . max ( a , b ) ) ; RegisterFunction ( "ceil" , [ "float" ] , "float" , ( a , b ) => Math . ceil ( a ) ) ; RegisterFunction ( "floor" , [ "float" ] , "float" , ( a , b ) => Math . floor ( a ) ) ; RegisterFunction ( "mix" , [ "float" , "float" , "float" ] , "float" , ( a , b , t ) => a + ( b - a ) * t ) ; RegisterFunction ( "mix" , [ "Vector2" , "Vector2" , "float" ] , "Vector2" , null ) ; RegisterFunction ( "mix" , [ "Vector3" , "Vector3" , "float" ] , "Vector3" , null ) ; RegisterFunction ( "mix" , [ "Vector4" , "Vector4" , "float" ] , "Vector4" , null ) ; RegisterFunction ( "mix" , [ "Color" , "Color" , "float" ] , "Color" , null ) ; RegisterFunction ( "clamp" , [ "float" ] , "float" , ( a ) => Math . max ( 0 , Math . min ( 1 , a ) ) ) ; RegisterFunction ( "dot" , [ "Vector2" , "Vector2" ] , "float" , ( a , b ) => a [ 0 ] * b [ 0 ] + a [ 1 ] * b [ 1 ] ) ; RegisterFunction ( "dot" , [ "Vector3" , "Vector3" ] , "float" , ( a , b ) => a [ 0 ] * b [ 0 ] + a [ 1 ] * b [ 1 ] + a [ 2 ] * b [ 2 ] ) ; RegisterFunction ( "dot" , [ "Vector4" , "Vector4" ] , "float" , ( a , b ) => a [ 0 ] * b [ 0 ] + a [ 1 ] * b [ 1 ] + a [ 2 ] * b [ 2 ] + a [ 3 ] * b [ 3 ] ) ; RegisterFunction ( "length" , [ "Vector2" ] , "float" , ( a ) => Vector2 . FromArray ( a ) . normalize ( ) . toArray ( ) ) ; RegisterFunction ( "length" , [ "Vector3" ] , "float" , ( a ) => Vector3 . FromArray ( a ) . normalize ( ) . toArray ( ) ) ; RegisterFunction ( "length" , [ "Vector4" ] , "float" , ( a ) => Quaternion . FromArray ( a ) . normalize ( ) . toArray ( ) ) ; RegisterFunction ( "length" , [ "Quaternion" ] , "float" , ( a ) => Quaternion . FromArray ( a ) . normalize ( ) . toArray ( ) ) ; RegisterFunction ( "normalize" , [ "Vector2" ] , "Vector2" , ( a ) => Vector2 . FromArray ( a ) . length ( ) ) ; RegisterFunction ( "normalize" , [ "Vector3" ] , "Vector3" , ( a ) => Vector3 . FromArray ( a ) . length ( ) ) ; RegisterFunction ( "normalize" , [ "Vector4" ] , "Vector4" , ( a ) => Quaternion . FromArray ( a ) . length ( ) ) ; RegisterFunction ( "normalize" , [ "Quaternion" ] , "Quaternion" , ( a ) => Quaternion . FromArray ( a ) . length ( ) ) ; RegisterFunction ( "cross" , [ "Vector3" , "Vector3" ] , "Vector3" , ( a , b ) => { return Vector3 . FromArray ( a ) . cross ( Vector3 . FromArray ( b ) ) . toArray ( ) ; } ) ; RegisterFunction ( "quat_mul" , [ "Quaternion" , "Quaternion" ] , "Quaternion" , ( a , b ) => { return Quaternion . FromArray ( a ) . mul ( Quaternion . FromArray ( b ) ) . toArray ( ) ; } ) ; RegisterFunction ( "quat_conj" , [ "Quaternion" ] , "Quaternion" , ( a ) => { return Quaternion . FromArray ( a ) . conj ( ) . toArray ( ) ; } ) ; RegisterFunction ( "quat_slerp" , [ "Quaternion" , "Quaternion" , "float" ] , "Quaternion" , ( a , b , t ) => { return Quaternion . Slerp ( Quaternion . FromArray ( a ) , Quaternion . FromArray ( b ) , t ) . toArray ( ) ; } ) ; RegisterFunction ( "quat_rotate" , [ "Quaternion" , "Vector3" ] , "Vector3" , ( q , v ) => { return Quaternion . FromArray ( q ) . rotate ( Vector3 . FromArray ( v ) ) . toArray ( ) ; } ) ; RegisterFunction ( "quat_rotation" , [ "Vector3" , "float" ] , "Quaternion" , ( axis , angle ) => { return Quaternion . Rotation ( Vector3 . FromArray ( axis ) , angle ) . toArray ( ) ; } ) ; RegisterConstructor ( "Color" , [ "float" , "float" , "float" , "float" ] , ( r , g , b , a ) => [ r , g , b , a ] ) ; RegisterConstructor ( "Color" , [ "float" , "float" , "float" ] , ( r , g , b ) => [ r , g , b , 1 ] ) ; RegisterConstructor ( "Color" , [ "float" , "float" ] , ( v , a ) => [ v , v , v , a ] ) ; RegisterConstructor ( "Color" , [ "float" ] , ( v ) => [ v , v , v , 1 ] ) ; RegisterFunction ( "lab2rgb" , [ "Color" ] , "Color" , ( color ) => color ) ; RegisterFunction ( "hcl2rgb" , [ "Color" ] , "Color" , ( color ) => color ) ; RegisterTypeConversion ( "bool" , "int" , 1 , ( a ) => a ) ; RegisterTypeConversion ( "int" , "float" , 1 , ( a ) => a ) ; RegisterFunction ( "int" , [ "float" ] , "int" , ( a ) => Math . floor ( a ) ) ; RegisterFunction ( "float" , [ "int" ] , "float" , ( a ) => a ) ; RegisterTypeConversion ( "Quaternion" , "Vector4" , 0 , ( a ) => a ) ; RegisterTypeConversion ( "Vector4" , "Quaternion" , 0 , ( a ) => a ) ; RegisterTypeConversion ( "Color" , "Vector4" , 0 , ( a ) => a ) ; RegisterTypeConversion ( "Vector4" , "Color" , 0 , ( a ) => a ) ; RegisterTypeConversion ( "Vector4Array" , "ColorArray" , 0 , ( a ) => a ) ; RegisterTypeConversion ( "ColorArray" , "Vector4Array" , 0 , ( a ) => a ) ; RegisterTypeConversion ( "Vector4Array2D" , "Image" , 0 , ( a ) => a ) ; RegisterTypeConversion ( "Image" , "Vector4Image" , 0 , ( a ) => a ) ; addConstant ( "PI" , "float" , Math . PI ) ; addConstant ( "SQRT2" , "float" , Math . SQRT2 ) ; addConstant ( "SQRT1_2" , "float" , Math . SQRT1_2 ) ; addConstant ( "RED" , "Color" , [ 1 , 0 , 0 , 1 ] ) ; RegisterFunction ( "array" , [ "FloatArray" , "float" ] , "float" , not_implemented ) ; RegisterFunction ( "array" , [ "Vector2Array" , "float" ] , "Vector2" , not_implemented ) ; RegisterFunction ( "array" , [ "Vector3Array" , "float" ] , "Vector3" , not_implemented ) ; RegisterFunction ( "array" , [ "Vector4Array" , "float" ] , "Vector4" , not_implemented ) ; RegisterFunction ( "array" , [ "ColorArray" , "float" ] , "Color" , not_implemented ) ; RegisterFunction ( "image" , [ "Image" , "Vector2" ] , "Color" , not_implemented ) ; RegisterFunction ( "image" , [ "Vector4Image" , "Vector2" ] , "Vector4" , not_implemented ) ; RegisterFunction ( "image" , [ "Vector3Image" , "Vector2" ] , "Vector3" , not_implemented ) ; RegisterFunction ( "image" , [ "Vector2Image" , "Vector2" ] , "Vector2" , not_implemented ) ; RegisterFunction ( "image" , [ "FloatImage" , "Vector2" ] , "float" , not_implemented ) ; RegisterFunction ( "get_camera_position" , [ ] , "Vector3" , not_implemented ) ; RegisterFunction ( "get_camera_direction" , [ "Vector3" ] , "Vector3" , not_implemented ) ;