#include "daScript/misc/platform.h" #include "module_builtin.h" #include "daScript/simulate/simulate_nodes.h" #include "daScript/ast/ast_interop.h" #include "daScript/ast/ast_policy_types.h" #include "daScript/ast/ast_simulate.h" #include "daScript/ast/ast_handle.h" #include "daScript/simulate/sim_policy.h" #include "daScript/simulate/aot_builtin_math.h" #include "daScript/simulate/simulate_visit_op.h" #include "daScript/misc/performance_time.h" namespace das { #define MATH_FUN_OP1(fun)\ DEFINE_POLICY(fun);\ IMPLEMENT_OP1_FUNCTION_POLICY(fun,Float,float); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, float2); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, float3); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, float4); #define MATH_FUN_OP1_INT(fun)\ DEFINE_POLICY(fun);\ IMPLEMENT_OP1_FUNCTION_POLICY_EX(fun,Int,int32_t,Float,float);\ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, float2); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, float3); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, float4); #define MATH_FUN_OP2(fun)\ DEFINE_POLICY(fun);\ IMPLEMENT_OP2_FUNCTION_POLICY(fun,Float,float); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, float2); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, float3); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, float4); #define MATH_FUN_OP1I(fun)\ DEFINE_POLICY(fun);\ IMPLEMENT_OP1_FUNCTION_POLICY(fun,Int,int32_t); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, int2); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, int3); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, int4); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, uint2); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, uint3); \ IMPLEMENT_OP1_EVAL_FUNCTION_POLICY(fun, uint4); #define MATH_FUN_OP2I(fun)\ IMPLEMENT_OP2_FUNCTION_POLICY(fun,Int,int32_t); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, int2); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, int3); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, int4); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, uint2); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, uint3); \ IMPLEMENT_OP2_EVAL_FUNCTION_POLICY(fun, uint4); #define MATH_FUN_OP3I(fun)\ IMPLEMENT_OP3_FUNCTION_POLICY(fun,Int,int32_t); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, int2); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, int3); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, int4); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, uint2); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, uint3); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, uint4); #define MATH_FUN_OP3(fun)\ DEFINE_POLICY(fun);\ IMPLEMENT_OP3_FUNCTION_POLICY(fun,Float,float); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, float2); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, float3); \ IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(fun, float4); #define MATH_FUN_OP1A(fun) \ DEFINE_POLICY(fun); \ MATH_FUN_OP1(fun); \ MATH_FUN_OP1I(fun); \ IMPLEMENT_OP1_FUNCTION_POLICY(fun,UInt,uint32_t); \ IMPLEMENT_OP1_FUNCTION_POLICY(fun,Int64,int64_t); \ IMPLEMENT_OP1_FUNCTION_POLICY(fun,UInt64,uint64_t); \ IMPLEMENT_OP1_FUNCTION_POLICY(fun,Double,double); #define MATH_FUN_OP2A(fun) \ MATH_FUN_OP2(fun); \ MATH_FUN_OP2I(fun); \ IMPLEMENT_OP2_FUNCTION_POLICY(fun,UInt,uint32_t); \ IMPLEMENT_OP2_FUNCTION_POLICY(fun,Int64,int64_t); \ IMPLEMENT_OP2_FUNCTION_POLICY(fun,UInt64,uint64_t); \ IMPLEMENT_OP2_FUNCTION_POLICY(fun,Double,double); #define MATH_FUN_OP3A(fun) \ MATH_FUN_OP3(fun); \ MATH_FUN_OP3I(fun); \ IMPLEMENT_OP3_FUNCTION_POLICY(fun,UInt,uint32_t); \ IMPLEMENT_OP3_FUNCTION_POLICY(fun,Int64,int64_t); \ IMPLEMENT_OP3_FUNCTION_POLICY(fun,UInt64,uint64_t); \ IMPLEMENT_OP3_FUNCTION_POLICY(fun,Double,double); // everything MATH_FUN_OP2A(Min) MATH_FUN_OP2A(Max) MATH_FUN_OP3A(Clamp) MATH_FUN_OP1A(Sign) MATH_FUN_OP1A(Abs) //common MATH_FUN_OP1(Floor) MATH_FUN_OP1(Ceil) MATH_FUN_OP1(Fract) MATH_FUN_OP1(Round) MATH_FUN_OP1(Sqrt) MATH_FUN_OP1(RSqrt) MATH_FUN_OP1(RSqrtEst) MATH_FUN_OP1(Sat) MATH_FUN_OP3(Lerp) IMPLEMENT_OP3_FUNCTION_POLICY(Lerp,Double,double); //common - double IMPLEMENT_OP1_FUNCTION_POLICY(Floor,Double,double); IMPLEMENT_OP1_FUNCTION_POLICY(Ceil,Double,double); IMPLEMENT_OP1_FUNCTION_POLICY(Fract,Double,double); IMPLEMENT_OP1_FUNCTION_POLICY(Round,Double,double); IMPLEMENT_OP1_FUNCTION_POLICY(Sat,Double,double); // mad MATH_FUN_OP3A(Mad) MATH_FUN_OP1_INT(Trunci) MATH_FUN_OP1_INT(Floori) MATH_FUN_OP1_INT(Ceili) MATH_FUN_OP1_INT(Roundi) IMPLEMENT_OP1_FUNCTION_POLICY_EX(Trunci,Int,int32_t,Double,double); IMPLEMENT_OP1_FUNCTION_POLICY_EX(Floori,Int,int32_t,Double,double); IMPLEMENT_OP1_FUNCTION_POLICY_EX(Ceili,Int,int32_t,Double,double); IMPLEMENT_OP1_FUNCTION_POLICY_EX(Roundi,Int,int32_t,Double,double); //exp MATH_FUN_OP1(Exp) MATH_FUN_OP1(Log) MATH_FUN_OP1(Exp2) MATH_FUN_OP1(Log2) MATH_FUN_OP2(Pow) MATH_FUN_OP1(Rcp) MATH_FUN_OP1(RcpEst) //trig MATH_FUN_OP1(Sin) MATH_FUN_OP1(Cos) MATH_FUN_OP1(Tan) DEFINE_POLICY(MadS) // vector_a*scalar_b + vector_c IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,float2); IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,float3); IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,float4); IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,int2); IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,int3); IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,int4); IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,uint2); IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,uint3); IMPLEMENT_OP3_EVAL_FUNCTION_POLICY(MadS,uint4); // trig types template void addFunctionTrig(Module & mod, const ModuleLibrary & lib) { // policy ret arg1 arg2 name mod.addFunction( (new BuiltInFn, TT, TT>("sin", lib, "Sin"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("cos", lib, "Cos"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("tan", lib, "Tan"))->arg("x") ); } template void addFunctionCommonTyped(Module & mod, const ModuleLibrary & lib) { // policy ret arg1 arg2 name mod.addFunction( (new BuiltInFn, TT, TT, TT>("min", lib, "Min"))->args({"x","y"}) ); mod.addFunction( (new BuiltInFn, TT, TT, TT>("max", lib, "Max"))->args({"x","y"}) ); mod.addFunction( (new BuiltInFn,TT, TT, TT, TT>("clamp", lib, "Clamp"))->args({"t","a","b"}) ); mod.addFunction( (new BuiltInFn, TT, TT>("abs", lib, "Abs"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("sign", lib, "Sign"))->arg("x") ); } template void addFunctionCommon(Module & mod, const ModuleLibrary & lib) { // policy ret arg1 name mod.addFunction( (new BuiltInFn, TT, TT>("floor", lib, "Floor"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("ceil", lib, "Ceil"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("fract", lib, "Fract"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("round", lib, "Round"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("sqrt", lib, "Sqrt"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("rsqrt", lib, "RSqrt"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("rsqrt_est", lib, "RSqrtEst"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("saturate", lib, "Sat"))->arg("x") ); } template void addFunctionCommonConversion(Module & mod, const ModuleLibrary & lib) { // policy ret arg1 name mod.addFunction( (new BuiltInFn, Ret, TT>("floori", lib, "Floori"))->arg("x") ); mod.addFunction( (new BuiltInFn, Ret, TT>("ceili", lib, "Ceili"))->arg("x") ); mod.addFunction( (new BuiltInFn, Ret, TT>("roundi", lib, "Roundi"))->arg("x") ); mod.addFunction( (new BuiltInFn, Ret, TT>("trunci", lib, "Trunci"))->arg("x") ); } template void addFunctionPow(Module & mod, const ModuleLibrary & lib) { // policy ret arg1 name mod.addFunction( (new BuiltInFn, TT, TT>("exp", lib, "Exp"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("log", lib, "Log"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("exp2", lib, "Exp2"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("log2", lib, "Log2"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("rcp", lib, "Rcp"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT>("rcp_est", lib, "RcpEst"))->arg("x") ); mod.addFunction( (new BuiltInFn, TT, TT, TT>("pow", lib, "Pow"))->args({"x","y"}) ); } template void addFunctionOp3i(Module & mod, const ModuleLibrary & lib) { // policy ret arg1 arg2 arg3 name mod.addFunction( (new BuiltInFn, TT, TT, TT, TT>("mad", lib, "Mad"))->args({"a","b","c"}) ); } template void addFunctionOp3(Module & mod, const ModuleLibrary & lib) { addFunctionOp3i(mod, lib); // policy ret arg1 arg2 arg3 name mod.addFunction( (new BuiltInFn, TT, TT, TT, TT>("lerp", lib, "Lerp"))->args({"a","b","t"}) ); } template class MatrixAnnotation : public ManagedStructureAnnotation> { enum { ColC = sizeof(VecT) / sizeof(float) }; public: MatrixAnnotation(ModuleLibrary & lib) : ManagedStructureAnnotation>( "float" + to_string(ColC) + "x" + to_string(RowC), lib, "float" + to_string(ColC) + "x" + to_string(RowC)) { const char * fieldNames [] = {"x","y","z","w"}; for ( int r=0; r!=RowC; ++r ) { this->addFieldEx(fieldNames[r], "m[" + to_string(r) + "]", r*ColC*sizeof(float), new TypeDecl(TypeDecl::getVectorType(Type::tFloat, ColC))); } } virtual bool isIndexable ( const TypeDeclPtr & decl ) const override { return decl->isIndex(); } virtual TypeDeclPtr makeIndexType ( ExpressionPtr, ExpressionPtr idx ) const override { auto decl = idx->type; if ( !decl->isIndex() ) return nullptr; auto bt = TypeDecl::getVectorType(Type::tFloat, ColC); auto pt = new TypeDecl(bt); pt->ref = true; return pt; } SimNode * trySimulate ( Context & context, ExpressionPtr subexpr, ExpressionPtr index, const TypeDeclPtr & r2vType, uint32_t ofs ) const { if ( index->rtti_isConstant() ) { // if its constant index, like a[3]..., we try to let node bellow simulate auto idxCE = static_cast(index); uint32_t idxC = cast::to(idxCE->value); if ( idxC >= RowC ) { context.thisProgram->error("matrix index out of range", "", "", subexpr->at, CompilationError::exceeds_array_index); return nullptr; } uint32_t stride = sizeof(float)*ColC; auto tnode = trySimulateExpression(context, subexpr, idxC*stride + ofs, r2vType); if ( tnode ) { return tnode; } } return nullptr; } virtual SimNode * simulateGetAt ( Context & context, const LineInfo & at, const TypeDeclPtr &, ExpressionPtr rv, ExpressionPtr idx, uint32_t ofs ) const override { gc_local none = new TypeDecl(Type::none); if ( auto tnode = trySimulate(context, rv, idx, none.ptr, ofs) ) { return tnode; } else { return context.code->makeNode(at, simulateExpression(context, rv), simulateExpression(context, idx), uint32_t(sizeof(float)*ColC), ofs, RowC, "matrix[index]"); } } virtual SimNode * simulateGetAtR2V ( Context & context, const LineInfo & at, const TypeDeclPtr & readType, ExpressionPtr rv, ExpressionPtr idx, uint32_t ofs ) const override { auto r2vType = readType->baseType; gc_local r2vTypeDecl = new TypeDecl(r2vType); if ( auto tnode = trySimulate(context, rv, idx, r2vTypeDecl.ptr, ofs) ) { return tnode; } else { return context.code->makeValueNode( r2vType, at, simulateExpression(context, rv), simulateExpression(context, idx), uint32_t(sizeof(float)*ColC), ofs, RowC, "matrix[index]"); } } virtual bool isRawPod() const override { return true; } virtual bool isPod() const override { return true; } }; typedef MatrixAnnotation float4x4_ann; typedef MatrixAnnotation float3x4_ann; typedef MatrixAnnotation float3x3_ann; template struct SimNode_MatrixCtor : SimNode_CallBase { SimNode_MatrixCtor(const LineInfo & at) : SimNode_CallBase(at,"") {} virtual SimNode * visit ( SimVisitor & vis ) override { V_BEGIN(); V_OP(MatrixCtor); V_CALL(); V_END(); } DAS_EVAL_ABI virtual vec4f eval(Context & context) override { auto cmres = cmresEval->evalPtr(context); memset ( cmres, 0, sizeof(MatT) ); return cast::from(cmres); } }; template __forceinline void matrix_identity ( float * mat ) { for ( int y=0; y!=r; ++y ) { for ( int x=0; x!=c; ++x ) { *mat++ = x==y ? 1.0f : 0.0f; } } } float4x4 float4x4_from_float34 ( const float3x4 & mat ) { mat44f res; v_mat44_make_from_43ca(res, (const float*)&mat); return reinterpret_cast(res); } float3x3 float3x3_from_float44 ( const float4x4 & mat ) { float3x3 res; res.m[0] = vec4f(mat.m[0]); res.m[1] = vec4f(mat.m[1]); res.m[2] = vec4f(mat.m[2]); return res; } float3x3 float3x3_from_float34 ( const float3x4 & mat ) { float3x3 res; res.m[0] = vec4f(mat.m[0]); res.m[1] = vec4f(mat.m[1]); res.m[2] = vec4f(mat.m[2]); return res; } float3x4 float3x4_from_float44 ( const float4x4 & mat ) { float3x4 res; res.m[0] = vec4f(mat.m[0]); res.m[1] = vec4f(mat.m[1]); res.m[2] = vec4f(mat.m[2]); res.m[3] = vec4f(mat.m[3]); return res; } void float4x4_identity ( float4x4 & mat ) { matrix_identity<4,4>((float*)&mat); } void float3x4_identity ( float3x4 & mat ) { matrix_identity<4,3>((float*)&mat); } void float3x3_identity ( float3x3 & mat ) { matrix_identity<3,3>((float*)&mat); } float3x3 float3x3_neg ( const float3x3 & mat ) { float3x3 res; res.m[0] = v_neg(mat.m[0]); res.m[1] = v_neg(mat.m[1]); res.m[2] = v_neg(mat.m[2]); return res; } float float3x3_det ( const float3x3 & a ) { mat33f va; va.col0 = a.m[0]; va.col1 = a.m[1]; va.col2 = a.m[2]; return v_extract_x(v_mat33_det(va)); } float3x4 float3x4_neg ( const float3x4 & mat ) { float3x4 res; res.m[0] = v_neg(mat.m[0]); res.m[1] = v_neg(mat.m[1]); res.m[2] = v_neg(mat.m[2]); res.m[3] = v_neg(mat.m[3]); return res; } float float4x4_det(const float4x4 &a) { mat44f va; memcpy(&va,&a,sizeof(float4x4)); return v_extract_x(v_mat44_det(va)); } float4x4 float4x4_identity_m ( void ) { float4x4 mat; matrix_identity<4,4>((float*)&mat); return mat; } float3x4 float3x4_identity_m ( void ) { float3x4 mat; matrix_identity<4,3>((float*)&mat); return mat; } float3x3 float3x3_identity_m ( void ) { float3x3 mat; matrix_identity<3,3>((float*)&mat); return mat; } float4x4 float4x4_translation(float3 xyz) { float4x4 mat; matrix_identity<4,4>((float*)&mat); mat.m[3].x = xyz.x; mat.m[3].y = xyz.y; mat.m[3].z = xyz.z; return mat; } float4x4 float4x4_mul(const float4x4 &a, const float4x4 &b) { mat44f va,vb,res; memcpy(&va,&a,sizeof(float4x4)); memcpy(&vb,&b,sizeof(float4x4)); v_mat44_mul(res,va,vb); return reinterpret_cast(res); } float3x3 float3x3_mul(const float3x3 &a, const float3x3 &b) { float3x3 res; mat33f va; va.col0 = a.m[0]; va.col1 = a.m[1]; va.col2 = a.m[2]; res.m[0] = v_mat33_mul_vec3(va, b.m[0]); res.m[1] = v_mat33_mul_vec3(va, b.m[1]); res.m[2] = v_mat33_mul_vec3(va, b.m[2]); return res; } float4x4 float4x4_transpose ( const float4x4 & src ) { mat44f res; memcpy ( &res, &src, sizeof(float4x4) ); v_mat44_transpose(res.col0, res.col1, res.col2, res.col3); return reinterpret_cast(res); } float4x4 float4x4_neg( const float4x4 & src) { mat44f res; res.col0 = v_neg(src.m[0]); res.col1 = v_neg(src.m[1]); res.col2 = v_neg(src.m[2]); res.col3 = v_neg(src.m[3]); return reinterpret_cast(res); } float4x4 float4x4_inverse( const float4x4 & src) { mat44f mat, invMat; memcpy(&mat, &src, sizeof(float4x4)); v_mat44_inverse(invMat, mat); return reinterpret_cast(invMat); } float3x3 float3x3_inverse( const float3x3 & src) { mat33f mat, invMat; memcpy(&mat, &src, sizeof(float3x3)); v_mat33_inverse(invMat, mat); return reinterpret_cast(invMat); } float3x3 float3x3_orthonormal_inverse( const float3x3 & src) { mat33f mat, invMat; memcpy(&mat, &src, sizeof(float3x3)); v_mat33_orthonormal_inverse(invMat, mat); return reinterpret_cast(invMat); } float4x4 float4x4_persp_forward(float wk, float hk, float zn, float zf) { mat44f mat; v_mat44_make_persp_forward(mat, wk, hk, zn, zf); return reinterpret_cast(mat); } float4x4 float4x4_persp_reverse(float wk, float hk, float zn, float zf) { mat44f mat; v_mat44_make_persp_reverse(mat, wk, hk, zn, zf); return reinterpret_cast(mat); } float4x4 float4x4_look_at(float3 eye, float3 at, float3 up) { mat44f mat; v_mat44_make_look_at(mat, eye, at, up); return reinterpret_cast(mat); } float4x4 float4x4_compose(float3 pos, float4 rot, float3 scale) { mat44f mat; v_mat44_compose(mat, pos, rot, scale); return reinterpret_cast(mat); } void float4x4_decompose(const float4x4 & mat, float3 & pos, float4 & rot, float3 & scale) { mat44f gmat; memcpy(&gmat, &mat, sizeof(float4x4)); vec3f gpos; quat4f grot; vec4f gscale; v_mat4_decompose(gmat, gpos, grot, gscale); pos = gpos; rot = grot; scale = gscale; } float4 quat_from_unit_arc(float3 v0, float3 v1) { return v_quat_from_unit_arc(v_ldu_p3(&v0.x), v_ldu_p3(&v1.x)); } float4 quat_from_unit_vec_ang(float3 v, float ang) { return v_quat_from_unit_vec_ang(v_ldu_p3(&v.x), v_splats(ang)); } float4 quat_from_euler_vec(float3 v) { return v_quat_from_euler(v_ldu_p3(&v.x)); } float4 quat_from_euler(float x, float y, float z) { return v_quat_from_euler(v_make_vec4f(x, y, z, 0.f)); } float3 euler_from_quat_vec(float4 v) { return v_euler_from_quat(v); } float4 quat_from_float3x3(const float3x3 & a) { mat33f va; va.col0 = a.m[0]; va.col1 = a.m[1]; va.col2 = a.m[2]; return v_quat_from_mat33(va); } float4 quat_from_float3x4(const float3x4 & a) { mat44f tm; v_mat44_make_from_43cu_unsafe(tm, &a.m[0].x); return v_quat_from_mat43(tm); } float4 quat_from_float4x4(const float4x4 & a) { mat44f va; memcpy(&va,&a,sizeof(float4x4)); return v_quat_from_mat43(va); } float4 quat_mul(float4 q1, float4 q2) { return v_quat_mul_quat(q1, q2); } float3 quat_mul_vec(float4 q, float3 v) { return v_quat_mul_vec3(q, v); } float4 quat_conjugate(float4 q) { return v_quat_conjugate(q); } float4 quat_slerp(float t, float4 a, float4 b) { return v_quat_slerp(v_splats(t), a, b); } struct floatNxNIndexFn : defaultTempFn { floatNxNIndexFn() : defaultTempFn() {} ___noinline bool operator () ( Function * fn ) { defaultTempFn::operator()(fn); if ( !fn->arguments.empty() ) { fn->arguments[0]->type->explicitConst = true; } fn->builtIn = true; fn->generated = true; fn->jitOnly = true; return true; } }; template class MatrixCTorFn : public BuiltInFunction { public: __forceinline MatrixCTorFn(const char * fn, const ModuleLibrary & lib, const char * cna = nullptr, bool pbas = true) : BuiltInFunction(fn,cna) { this->policyBased = pbas; construct(makeBuiltinArgs(lib)); } virtual SimNode * makeSimNode ( Context & context, const vector & ) override { return context.code->makeNode(at); } static RetT ctorFn() { RetT res; memset(&res, 0, sizeof(RetT)); return res; } virtual void * getBuiltinAddress() const override { constexpr bool IS_CMRES = true; return ImplWrapCall::value, RetT(*)(), &ctorFn>::get_builtin_address(); } }; class Module_Math : public Module { public: Module_Math() : Module("math") { DAS_PROFILE_SECTION("Module_Math"); ModuleLibrary lib(this); lib.addBuiltInModule(); // constants addConstant(*this,"PI",(float)M_PI); addConstant(*this,"DBL_PI",(double)M_PI); addConstant(*this,"FLT_EPSILON",FLT_EPSILON); addConstant(*this,"DBL_EPSILON",DBL_EPSILON); // trigonometry functions addFunctionTrig(*this, lib); addFunctionTrig(*this,lib); addFunctionTrig(*this,lib); addFunctionTrig(*this,lib); // exp functions addFunctionPow(*this, lib); addFunctionPow(*this,lib); addFunctionPow(*this,lib); addFunctionPow(*this,lib); // op3 addFunctionOp3(*this,lib); addFunctionOp3(*this,lib); addFunctionOp3(*this,lib); addFunctionOp3(*this,lib); addFunction( (new BuiltInFn, float2, float2, float, float2>("mad", lib, "MadS"))->args({"a","b","c"}) ); addFunction( (new BuiltInFn, float3, float3, float, float3>("mad", lib, "MadS"))->args({"a","b","c"}) ); addFunction( (new BuiltInFn, float4, float4, float, float4>("mad", lib, "MadS"))->args({"a","b","c"}) ); // op3i - int addFunctionOp3i(*this,lib); addFunctionOp3i(*this,lib); addFunctionOp3i(*this,lib); addFunctionOp3i(*this,lib); addFunction( (new BuiltInFn, int2, int2, int, int2>("mad", lib, "MadS"))->args({"a","b","c"}) ); addFunction( (new BuiltInFn, int3, int3, int, int3>("mad", lib, "MadS"))->args({"a","b","c"}) ); addFunction( (new BuiltInFn, int4, int4, int, int4>("mad", lib, "MadS"))->args({"a","b","c"}) ); // op3i - uint addFunctionOp3i(*this,lib); addFunctionOp3i(*this,lib); addFunctionOp3i(*this,lib); addFunctionOp3i(*this,lib); addFunction( (new BuiltInFn, uint2, uint2, uint32_t, uint2>("mad", lib, "MadS"))->args({"a","b","c"}) ); addFunction( (new BuiltInFn, uint3, uint3, uint32_t, uint3>("mad", lib, "MadS"))->args({"a","b","c"}) ); addFunction( (new BuiltInFn, uint4, uint4, uint32_t, uint4>("mad", lib, "MadS"))->args({"a","b","c"}) ); // and double addFunctionOp3(*this,lib); // double common (sqrt/rsqrt/rcp already registered as externs below) addFunction( (new BuiltInFn, double, double>("floor", lib, "Floor"))->arg("x") ); addFunction( (new BuiltInFn, double, double>("ceil", lib, "Ceil"))->arg("x") ); addFunction( (new BuiltInFn, double, double>("fract", lib, "Fract"))->arg("x") ); addFunction( (new BuiltInFn, double, double>("round", lib, "Round"))->arg("x") ); addFunction( (new BuiltInFn, double, double>("saturate", lib, "Sat"))->arg("x") ); //common addFunctionCommon(*this, lib); addFunctionCommon(*this,lib); addFunctionCommon(*this,lib); addFunctionCommon(*this,lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addFunctionCommonTyped(*this, lib); addExtern(*this, lib, "uint32_hash", SideEffects::none, "uint32_hash")->arg("seed"); addExtern(*this, lib, "uint_noise_1D", SideEffects::none, "uint_noise1D")->args({"position","seed"}); addExtern(*this, lib, "uint_noise_2D", SideEffects::none, "uint_noise2D_int2")->args({"position","seed"}); addExtern(*this, lib, "uint_noise_3D", SideEffects::none, "uint_noise3D_int3")->args({"position","seed"}); addExternEx(*this, lib, "dot", SideEffects::none, "dot2")->args({"x","y"}); addExternEx(*this, lib, "dot", SideEffects::none, "dot3")->args({"x","y"}); addExternEx(*this, lib, "dot", SideEffects::none, "dot4")->args({"x","y"}); addExternEx(*this, lib, "hmin", SideEffects::none, "hmin2")->arg("a"); addExternEx(*this, lib, "hmin", SideEffects::none, "hmin3")->arg("a"); addExternEx(*this, lib, "hmin", SideEffects::none, "hmin4")->arg("a"); addExternEx(*this, lib, "hmax", SideEffects::none, "hmax2")->arg("a"); addExternEx(*this, lib, "hmax", SideEffects::none, "hmax3")->arg("a"); addExternEx(*this, lib, "hmax", SideEffects::none, "hmax4")->arg("a"); addExternEx(*this, lib, "hadd", SideEffects::none, "hadd2")->arg("a"); addExternEx(*this, lib, "hadd", SideEffects::none, "hadd3")->arg("a"); addExternEx(*this, lib, "hadd", SideEffects::none, "hadd4")->arg("a"); addExternEx(*this, lib, "cross", SideEffects::none, "cross3")->args({"x","y"}); addExternEx(*this, lib, "fast_normalize", SideEffects::none, "normalize2")->arg("x"); addExternEx(*this, lib, "fast_normalize", SideEffects::none, "normalize3")->arg("x"); addExternEx(*this, lib, "fast_normalize", SideEffects::none, "normalize4")->arg("x"); addExternEx(*this, lib, "normalize", SideEffects::none, "safe_normalize2")->arg("x"); addExternEx(*this, lib, "normalize", SideEffects::none, "safe_normalize3")->arg("x"); addExternEx(*this, lib, "normalize", SideEffects::none, "safe_normalize4")->arg("x"); addExternEx(*this, lib, "length", SideEffects::none, "length2")->arg("x"); addExternEx(*this, lib, "length", SideEffects::none, "length3")->arg("x"); addExternEx(*this, lib, "length", SideEffects::none, "length4")->arg("x"); addExternEx(*this, lib, "inv_length", SideEffects::none,"invlength2")->arg("x"); addExternEx(*this, lib, "inv_length", SideEffects::none,"invlength3")->arg("x"); addExternEx(*this, lib, "inv_length", SideEffects::none,"invlength4")->arg("x"); addExternEx(*this, lib, "inv_length_sq", SideEffects::none, "invlengthSq2")->arg("x"); addExternEx(*this, lib, "inv_length_sq", SideEffects::none, "invlengthSq3")->arg("x"); addExternEx(*this, lib, "inv_length_sq", SideEffects::none, "invlengthSq4")->arg("x"); addExternEx(*this, lib, "length_sq", SideEffects::none, "lengthSq2")->arg("x"); addExternEx(*this, lib, "length_sq", SideEffects::none, "lengthSq3")->arg("x"); addExternEx(*this, lib, "length_sq", SideEffects::none, "lengthSq4")->arg("x"); addExternEx(*this, lib, "distance", SideEffects::none, "distance2")->args({"x","y"}); addExternEx(*this, lib, "distance_sq", SideEffects::none, "distanceSq2")->args({"x","y"}); addExternEx(*this, lib, "inv_distance", SideEffects::none, "invdistance2")->args({"x","y"}); addExternEx(*this, lib, "inv_distance_sq", SideEffects::none, "invdistanceSq2")->args({"x","y"}); addExternEx(*this, lib, "distance", SideEffects::none, "distance3")->args({"x","y"}); addExternEx(*this, lib, "distance_sq", SideEffects::none, "distanceSq3")->args({"x","y"}); addExternEx(*this, lib, "inv_distance", SideEffects::none, "invdistance3")->args({"x","y"}); addExternEx(*this, lib, "inv_distance_sq", SideEffects::none, "invdistanceSq3")->args({"x","y"}); addExternEx(*this, lib, "distance", SideEffects::none, "distance4")->args({"x","y"}); addExternEx(*this, lib, "distance_sq", SideEffects::none, "distanceSq4")->args({"x","y"}); addExternEx(*this, lib, "inv_distance", SideEffects::none, "invdistance4")->args({"x","y"}); addExternEx(*this, lib, "inv_distance_sq", SideEffects::none, "invdistanceSq4")->args({"x","y"}); addExternEx(*this, lib, "lerp", SideEffects::none, "lerp_vec_float")->args({"a", "b", "t"}); addExternEx(*this, lib, "lerp", SideEffects::none, "lerp_vec_float")->args({"a", "b", "t"}); addExternEx(*this, lib, "lerp", SideEffects::none, "lerp_vec_float")->args({"a", "b", "t"}); addExternEx(*this, lib, "step", SideEffects::none, "step_float")->args({"edge","x"}); addExternEx(*this, lib, "step", SideEffects::none, "step_vec")->args({"edge","x"}); addExternEx(*this, lib, "step", SideEffects::none, "step_vec")->args({"edge","x"}); addExternEx(*this, lib, "step", SideEffects::none, "step_vec")->args({"edge","x"}); addExternEx(*this, lib, "smoothstep", SideEffects::none, "smoothstep_float")->args({"edge0","edge1","x"}); addExternEx(*this, lib, "smoothstep", SideEffects::none, "smoothstep_vec")->args({"edge0","edge1","x"}); addExternEx(*this, lib, "smoothstep", SideEffects::none, "smoothstep_vec")->args({"edge0","edge1","x"}); addExternEx(*this, lib, "smoothstep", SideEffects::none, "smoothstep_vec")->args({"edge0","edge1","x"}); addExternEx(*this, lib, "radians", SideEffects::none, "radians_float")->arg("deg"); addExternEx(*this, lib, "radians", SideEffects::none, "radians_vec")->arg("deg"); addExternEx(*this, lib, "radians", SideEffects::none, "radians_vec")->arg("deg"); addExternEx(*this, lib, "radians", SideEffects::none, "radians_vec")->arg("deg"); addExternEx(*this, lib, "degrees", SideEffects::none, "degrees_float")->arg("rad"); addExternEx(*this, lib, "degrees", SideEffects::none, "degrees_vec")->arg("rad"); addExternEx(*this, lib, "degrees", SideEffects::none, "degrees_vec")->arg("rad"); addExternEx(*this, lib, "degrees", SideEffects::none, "degrees_vec")->arg("rad"); // unique float functions addExtern(*this, lib, "is_nan", SideEffects::none, "fisnan")->arg("x"); addExtern(*this, lib, "is_finite", SideEffects::none, "fisfinite")->arg("x"); //double functions addExtern(*this, lib, "is_nan", SideEffects::none, "disnan")->arg("x"); addExtern(*this, lib, "is_finite", SideEffects::none, "disfinite")->arg("x"); addExtern(*this, lib, "sqrt", SideEffects::none, "dsqrt")->arg("x"); addExtern(*this, lib, "exp", SideEffects::none, "dexp")->arg("x"); addExtern(*this, lib, "rcp", SideEffects::none, "drcp")->arg("x"); addExtern(*this, lib, "log", SideEffects::none, "dlog")->arg("x"); addExtern(*this, lib, "pow", SideEffects::none, "dpow")->args({"x","y"}); addExtern(*this, lib, "exp2", SideEffects::none, "dexp2")->arg("x"); addExtern(*this, lib, "log2", SideEffects::none, "dlog2")->arg("x"); addExtern(*this, lib, "sin", SideEffects::none, "dsin")->arg("x"); addExtern(*this, lib, "cos", SideEffects::none, "dcos")->arg("x"); addExtern(*this, lib, "asin", SideEffects::none, "dasin")->arg("x"); addExtern(*this, lib, "acos", SideEffects::none, "dacos")->arg("x"); addExtern(*this, lib, "safe_asin", SideEffects::none, "dsafe_asin")->arg("x"); addExtern(*this, lib, "safe_acos", SideEffects::none, "dsafe_acos")->arg("x"); addExtern(*this, lib, "tan", SideEffects::none, "dtan")->arg("x"); addExtern(*this, lib, "atan", SideEffects::none, "datan")->arg("x"); addExtern(*this, lib, "atan2", SideEffects::none, "datan2")->args({"y","x"}); addExtern(*this, lib, "sinh", SideEffects::none, "dsinh")->arg("x"); addExtern(*this, lib, "cosh", SideEffects::none, "dcosh")->arg("x"); addExtern(*this, lib, "tanh", SideEffects::none, "dtanh")->arg("x"); addExtern(*this, lib, "asinh", SideEffects::none, "dasinh")->arg("x"); addExtern(*this, lib, "acosh", SideEffects::none, "dacosh")->arg("x"); addExtern(*this, lib, "atanh", SideEffects::none, "datanh")->arg("x"); addExtern(*this, lib, "log10", SideEffects::none, "dlog10")->arg("x"); addExtern(*this, lib, "log1p", SideEffects::none, "dlog1p")->arg("x"); addExtern(*this, lib, "expm1", SideEffects::none, "dexpm1")->arg("x"); addExtern(*this, lib, "cbrt", SideEffects::none, "dcbrt")->arg("x"); addExtern(*this, lib, "trunc", SideEffects::none, "dtrunc")->arg("x"); addExtern(*this, lib, "hypot", SideEffects::none, "dhypot")->args({"x","y"}); addExtern(*this, lib, "fmod", SideEffects::none, "dfmod")->args({"x","y"}); addExtern(*this, lib, "remainder", SideEffects::none, "dremainder")->args({"x","y"}); addExtern(*this, lib, "sincos", SideEffects::modifyArgument, "sincosF")->args({"x","s","c"}); addExtern(*this, lib, "sincos", SideEffects::modifyArgument, "sincosD")->args({"x","s","c"}); // too big for intrinsic addExtern(*this, lib, "asin", SideEffects::none, "fasin")->arg("x"); addExtern(*this, lib, "acos", SideEffects::none, "facos")->arg("x"); addExtern(*this, lib, "safe_asin", SideEffects::none, "fsafe_asin")->arg("x"); addExtern(*this, lib, "safe_acos", SideEffects::none, "fsafe_acos")->arg("x"); addExtern(*this, lib, "atan", SideEffects::none, "fatan")->arg("x"); addExtern(*this, lib, "atan_est", SideEffects::none, "fatan_est")->arg("x"); addExtern(*this, lib, "atan2", SideEffects::none, "fatan2")->args({"y","x"}); addExtern(*this, lib, "atan2_est", SideEffects::none, "fatan2_est")->args({"y","x"}); addExtern(*this, lib, "sinh", SideEffects::none, "fsinh")->arg("x"); addExtern(*this, lib, "cosh", SideEffects::none, "fcosh")->arg("x"); addExtern(*this, lib, "tanh", SideEffects::none, "ftanh")->arg("x"); addExtern(*this, lib, "asinh", SideEffects::none, "fasinh")->arg("x"); addExtern(*this, lib, "acosh", SideEffects::none, "facosh")->arg("x"); addExtern(*this, lib, "atanh", SideEffects::none, "fatanh")->arg("x"); addExtern(*this, lib, "log10", SideEffects::none, "flog10")->arg("x"); addExtern(*this, lib, "log1p", SideEffects::none, "flog1p")->arg("x"); addExtern(*this, lib, "expm1", SideEffects::none, "fexpm1")->arg("x"); addExtern(*this, lib, "cbrt", SideEffects::none, "fcbrt")->arg("x"); addExtern(*this, lib, "trunc", SideEffects::none, "ftrunc")->arg("x"); addExtern(*this, lib, "hypot", SideEffects::none, "fhypot")->args({"x","y"}); addExtern(*this, lib, "fmod", SideEffects::none, "ffmod")->args({"x","y"}); addExtern(*this, lib, "remainder", SideEffects::none, "fremainder")->args({"x","y"}); addExternEx(*this, lib, "asin", SideEffects::none, "vasin")->arg("x"); addExternEx(*this, lib, "asin", SideEffects::none, "vasin")->arg("x"); addExternEx(*this, lib, "asin", SideEffects::none, "vasin")->arg("x"); addExternEx(*this, lib, "acos", SideEffects::none, "vacos")->arg("x"); addExternEx(*this, lib, "acos", SideEffects::none, "vacos")->arg("x"); addExternEx(*this, lib, "acos", SideEffects::none, "vacos")->arg("x"); addExternEx(*this, lib, "safe_asin", SideEffects::none, "vsafe_asin")->arg("x"); addExternEx(*this, lib, "safe_asin", SideEffects::none, "vsafe_asin")->arg("x"); addExternEx(*this, lib, "safe_asin", SideEffects::none, "vsafe_asin")->arg("x"); addExternEx(*this, lib, "safe_acos", SideEffects::none, "vsafe_acos")->arg("x"); addExternEx(*this, lib, "safe_acos", SideEffects::none, "vsafe_acos")->arg("x"); addExternEx(*this, lib, "safe_acos", SideEffects::none, "vsafe_acos")->arg("x"); addExternEx(*this, lib, "atan", SideEffects::none, "vatan")->arg("x"); addExternEx(*this, lib, "atan", SideEffects::none, "vatan")->arg("x"); addExternEx(*this, lib, "atan", SideEffects::none, "vatan")->arg("x"); addExternEx(*this, lib, "atan_est", SideEffects::none, "vatan_est")->arg("x"); addExternEx(*this, lib, "atan_est", SideEffects::none, "vatan_est")->arg("x"); addExternEx(*this, lib, "atan_est", SideEffects::none, "vatan_est")->arg("x"); addExternEx(*this, lib, "atan2", SideEffects::none, "vatan2")->args({"y","x"}); addExternEx(*this, lib, "atan2", SideEffects::none, "vatan2")->args({"y","x"}); addExternEx(*this, lib, "atan2", SideEffects::none, "vatan2")->args({"y","x"}); addExternEx(*this, lib, "atan2_est", SideEffects::none, "vatan2_est")->args({"y","x"}); addExternEx(*this, lib, "atan2_est", SideEffects::none, "vatan2_est")->args({"y","x"}); addExternEx(*this, lib, "atan2_est", SideEffects::none, "vatan2_est")->args({"y","x"}); addExternEx(*this, lib, "sinh", SideEffects::none, "vsinh")->arg("x"); addExternEx(*this, lib, "sinh", SideEffects::none, "vsinh")->arg("x"); addExternEx(*this, lib, "sinh", SideEffects::none, "vsinh")->arg("x"); addExternEx(*this, lib, "cosh", SideEffects::none, "vcosh")->arg("x"); addExternEx(*this, lib, "cosh", SideEffects::none, "vcosh")->arg("x"); addExternEx(*this, lib, "cosh", SideEffects::none, "vcosh")->arg("x"); addExternEx(*this, lib, "tanh", SideEffects::none, "vtanh")->arg("x"); addExternEx(*this, lib, "tanh", SideEffects::none, "vtanh")->arg("x"); addExternEx(*this, lib, "tanh", SideEffects::none, "vtanh")->arg("x"); addExternEx(*this, lib, "asinh", SideEffects::none, "vasinh")->arg("x"); addExternEx(*this, lib, "asinh", SideEffects::none, "vasinh")->arg("x"); addExternEx(*this, lib, "asinh", SideEffects::none, "vasinh")->arg("x"); addExternEx(*this, lib, "acosh", SideEffects::none, "vacosh")->arg("x"); addExternEx(*this, lib, "acosh", SideEffects::none, "vacosh")->arg("x"); addExternEx(*this, lib, "acosh", SideEffects::none, "vacosh")->arg("x"); addExternEx(*this, lib, "atanh", SideEffects::none, "vatanh")->arg("x"); addExternEx(*this, lib, "atanh", SideEffects::none, "vatanh")->arg("x"); addExternEx(*this, lib, "atanh", SideEffects::none, "vatanh")->arg("x"); addExternEx(*this, lib, "log10", SideEffects::none, "vlog10")->arg("x"); addExternEx(*this, lib, "log10", SideEffects::none, "vlog10")->arg("x"); addExternEx(*this, lib, "log10", SideEffects::none, "vlog10")->arg("x"); addExternEx(*this, lib, "log1p", SideEffects::none, "vlog1p")->arg("x"); addExternEx(*this, lib, "log1p", SideEffects::none, "vlog1p")->arg("x"); addExternEx(*this, lib, "log1p", SideEffects::none, "vlog1p")->arg("x"); addExternEx(*this, lib, "expm1", SideEffects::none, "vexpm1")->arg("x"); addExternEx(*this, lib, "expm1", SideEffects::none, "vexpm1")->arg("x"); addExternEx(*this, lib, "expm1", SideEffects::none, "vexpm1")->arg("x"); addExternEx(*this, lib, "cbrt", SideEffects::none, "vcbrt")->arg("x"); addExternEx(*this, lib, "cbrt", SideEffects::none, "vcbrt")->arg("x"); addExternEx(*this, lib, "cbrt", SideEffects::none, "vcbrt")->arg("x"); addExternEx(*this, lib, "trunc", SideEffects::none, "vtrunc")->arg("x"); addExternEx(*this, lib, "trunc", SideEffects::none, "vtrunc")->arg("x"); addExternEx(*this, lib, "trunc", SideEffects::none, "vtrunc")->arg("x"); addExternEx(*this, lib, "hypot", SideEffects::none, "vhypot")->args({"x","y"}); addExternEx(*this, lib, "hypot", SideEffects::none, "vhypot")->args({"x","y"}); addExternEx(*this, lib, "hypot", SideEffects::none, "vhypot")->args({"x","y"}); addExternEx(*this, lib, "fmod", SideEffects::none, "vfmod")->args({"x","y"}); addExternEx(*this, lib, "fmod", SideEffects::none, "vfmod")->args({"x","y"}); addExternEx(*this, lib, "fmod", SideEffects::none, "vfmod")->args({"x","y"}); addExternEx(*this, lib, "remainder", SideEffects::none, "vremainder")->args({"x","y"}); addExternEx(*this, lib, "remainder", SideEffects::none, "vremainder")->args({"x","y"}); addExternEx(*this, lib, "remainder", SideEffects::none, "vremainder")->args({"x","y"}); addExternEx(*this, lib, "reflect", SideEffects::none, "reflect")->args({"v","n"}); addExternEx(*this, lib, "reflect", SideEffects::none, "reflect2")->args({"v","n"}); addExternEx(*this, lib, "refract", SideEffects::none, "refract")->args({"v","n","nint"}); addExternEx(*this, lib, "refract", SideEffects::none, "refract2")->args({"v","n","nint"}); addFunctionCommonConversion (*this, lib); addFunctionCommonConversion (*this, lib); addFunctionCommonConversion(*this,lib); addFunctionCommonConversion(*this,lib); addFunctionCommonConversion(*this,lib); // structure annotations addAnnotation(new float4x4_ann(lib)); addAnnotation(new float3x4_ann(lib)); addAnnotation(new float3x3_ann(lib)); // c-tor addFunction ( new MatrixCTorFn< SimNode_MatrixCtor,float3x3 >("float3x3",lib) ); addFunction ( new MatrixCTorFn< SimNode_MatrixCtor,float3x4 >("float3x4",lib) ); addFunction ( new MatrixCTorFn< SimNode_MatrixCtor,float4x4 >("float4x4",lib) ); // 4x4 addExtern(*this, lib, "float4x4", SideEffects::none,"float4x4_from_float34"); addExtern(*this, lib, "identity", SideEffects::modifyArgument, "float4x4_identity")->arg("x"); addExtern(*this, lib, "identity4x4", SideEffects::none,"float4x4_identity_m"); addExtern(*this, lib, "translation", SideEffects::none, "float4x4_translation")->arg("xyz"); addExtern(*this, lib, "transpose", SideEffects::none, "float4x4_transpose")->arg("x"); addExtern(*this, lib, "persp_forward", SideEffects::none, "float4x4_persp_forward")->args({"wk", "hk", "zn", "zf"}); addExtern(*this, lib, "persp_reverse", SideEffects::none, "float4x4_persp_reverse")->args({"wk", "hk", "zn", "zf"}); addExtern(*this, lib, "look_at", SideEffects::none, "float4x4_look_at")->args({"eye", "at", "up"}); addExtern(*this, lib, "compose", SideEffects::none, "float4x4_compose")->args({"pos", "rot", "scale"}); addExtern(*this, lib, "*", SideEffects::none,"float4x4_mul")->args({"x", "y"}); addExtern(*this, lib, "decompose", SideEffects::modifyArgument, "float4x4_decompose")->args({"mat","pos","rot","scale"}); addExtern(*this, lib, "==", SideEffects::none, "float4x4_equ")->args({"x","y"}); addExtern(*this, lib, "!=", SideEffects::none, "float4x4_nequ")->args({"x","y"}); addExtern(*this, lib, "-", SideEffects::none,"float4x4_neg")->arg("x"); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"}); // 3x4 addExtern(*this, lib, "float3x4", SideEffects::none,"float3x4_from_float44"); addExtern(*this, lib, "identity", SideEffects::modifyArgument,"float3x4_identity")->arg("x"); addExtern(*this, lib, "identity3x4", SideEffects::none,"float3x4_identity_m"); addExtern(*this, lib, "*", SideEffects::none,"float3x4_mul")->args({"x","y"}); addExtern(*this, lib, "*", SideEffects::none,"float3x4_mul_vec3p")->args({"x","y"}); addExtern(*this, lib, "*", SideEffects::none,"float4x4_mul_vec4")->args({"x","y"}); addExtern(*this, lib, "determinant", SideEffects::none,"float4x4_det")->arg("x"); addExtern(*this, lib, "inverse", SideEffects::none, "float3x4_inverse")->arg("x"); addExtern(*this, lib, "inverse", SideEffects::none, "float4x4_inverse")->arg("m"); addExtern(*this, lib, "orthonormal_inverse", SideEffects::none, "float3x3_orthonormal_inverse")->arg("m"); addExtern(*this, lib, "orthonormal_inverse", SideEffects::none, "float3x4_orthonormal_inverse")->arg("m"); addExtern(*this, lib, "rotate", SideEffects::none, "rotate")->args({"x","y"}); addExtern(*this, lib, "==", SideEffects::none, "float3x4_equ")->args({"x","y"}); addExtern(*this, lib, "!=", SideEffects::none, "float3x4_nequ")->args({"x","y"}); addExtern(*this, lib, "-", SideEffects::none,"float3x4_neg")->arg("x"); addExtern(*this, lib, "determinant", SideEffects::none,"float3x4_det")->arg("x"); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"}); // quat addExtern(*this, lib, "quat_from_unit_arc", SideEffects::none, "quat_from_unit_arc")->args({"v0","v1"}); addExtern(*this, lib, "quat_from_unit_vec_ang", SideEffects::none, "quat_from_unit_vec_ang")->args({"v","ang"}); addExtern(*this, lib, "quat_from_euler", SideEffects::none, "quat_from_euler_vec")->args({"angles"}); addExtern(*this, lib, "quat_from_euler", SideEffects::none, "quat_from_euler")->args({"x", "y", "z"}); addExtern(*this, lib, "euler_from_quat", SideEffects::none, "euler_from_quat_vec")->args({"angles"}); addExtern(*this, lib, "quat", SideEffects::none, "quat_from_float3x3")->arg("m"); addExtern(*this, lib, "quat", SideEffects::none, "quat_from_float3x4")->arg("m"); addExtern(*this, lib, "quat", SideEffects::none, "quat_from_float4x4")->arg("m"); addExtern(*this, lib, "quat_mul", SideEffects::none, "quat_mul")->args({"q1","q2"}); addExtern(*this, lib, "quat_mul_vec", SideEffects::none, "quat_mul_vec")->args({"q","v"}); addExtern(*this, lib, "quat_conjugate", SideEffects::none, "quat_conjugate")->arg("q"); addExtern(*this, lib, "quat_slerp", SideEffects::none, "quat_slerp")->args({"t", "a", "b"}); // 3x3 addExtern(*this, lib, "float3x3", SideEffects::none,"float3x3_from_float44"); addExtern(*this, lib, "float3x3", SideEffects::none,"float3x3_from_float34"); addExtern(*this, lib, "identity", SideEffects::modifyArgument,"float3x3_identity")->arg("x"); addExtern(*this, lib, "identity3x3", SideEffects::none,"float3x3_identity_m"); addExtern(*this, lib, "*", SideEffects::none,"float3x3_mul")->args({"x", "y"}); addExtern(*this, lib, "*", SideEffects::none,"float3x3_mul_vec3")->args({"x","y"}); addExtern(*this, lib, "==", SideEffects::none, "float3x3_equ")->args({"x","y"}); addExtern(*this, lib, "!=", SideEffects::none, "float3x3_nequ")->args({"x","y"}); addExtern(*this, lib, "-", SideEffects::none,"float3x3_neg")->arg("x"); addExtern(*this, lib, "determinant", SideEffects::none,"float3x3_det")->arg("x"); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"}); addExtern)), SimNode_ExtFuncCallRef, floatNxNIndexFn>(*this, lib, ".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"}); // packing addExtern(*this, lib, "pack_float_to_byte", SideEffects::none,"pack_float_to_byte")->arg("x"); addExtern(*this, lib, "unpack_byte_to_float", SideEffects::none,"unpack_byte_to_float")->arg("x"); // and check everything verifyAotReady(); } virtual ModuleAotType aotRequire ( TextWriter & tw ) const override { tw << "#include \"daScript/simulate/aot_builtin_math.h\"\n"; return ModuleAotType::cpp; } }; } REGISTER_MODULE_IN_NAMESPACE(Module_Math,das); IMPLEMENT_EXTERNAL_TYPE_FACTORY(float4x4, das::float4x4) IMPLEMENT_EXTERNAL_TYPE_FACTORY(float3x4, das::float3x4) IMPLEMENT_EXTERNAL_TYPE_FACTORY(float3x3, das::float3x3)