#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("sin", lib, "Sin"))->arg("x") );
mod.addFunction( (new BuiltInFn("cos", lib, "Cos"))->arg("x") );
mod.addFunction( (new BuiltInFn("tan", lib, "Tan"))->arg("x") );
}
template
void addFunctionCommonTyped(Module & mod, const ModuleLibrary & lib) {
// policy ret arg1 arg2 name
mod.addFunction( (new BuiltInFn("min", lib, "Min"))->args({"x","y"}) );
mod.addFunction( (new BuiltInFn("max", lib, "Max"))->args({"x","y"}) );
mod.addFunction( (new BuiltInFn("clamp", lib, "Clamp"))->args({"t","a","b"}) );
mod.addFunction( (new BuiltInFn("abs", lib, "Abs"))->arg("x") );
mod.addFunction( (new BuiltInFn("sign", lib, "Sign"))->arg("x") );
}
template
void addFunctionCommon(Module & mod, const ModuleLibrary & lib) {
// policy ret arg1 name
mod.addFunction( (new BuiltInFn("floor", lib, "Floor"))->arg("x") );
mod.addFunction( (new BuiltInFn("ceil", lib, "Ceil"))->arg("x") );
mod.addFunction( (new BuiltInFn("fract", lib, "Fract"))->arg("x") );
mod.addFunction( (new BuiltInFn("round", lib, "Round"))->arg("x") );
mod.addFunction( (new BuiltInFn("sqrt", lib, "Sqrt"))->arg("x") );
mod.addFunction( (new BuiltInFn("rsqrt", lib, "RSqrt"))->arg("x") );
mod.addFunction( (new BuiltInFn("rsqrt_est", lib, "RSqrtEst"))->arg("x") );
mod.addFunction( (new BuiltInFn("saturate", lib, "Sat"))->arg("x") );
}
template
void addFunctionCommonConversion(Module & mod, const ModuleLibrary & lib) {
// policy ret arg1 name
mod.addFunction( (new BuiltInFn("floori", lib, "Floori"))->arg("x") );
mod.addFunction( (new BuiltInFn("ceili", lib, "Ceili"))->arg("x") );
mod.addFunction( (new BuiltInFn("roundi", lib, "Roundi"))->arg("x") );
mod.addFunction( (new BuiltInFn("trunci", lib, "Trunci"))->arg("x") );
}
template
void addFunctionPow(Module & mod, const ModuleLibrary & lib) {
// policy ret arg1 name
mod.addFunction( (new BuiltInFn("exp", lib, "Exp"))->arg("x") );
mod.addFunction( (new BuiltInFn("log", lib, "Log"))->arg("x") );
mod.addFunction( (new BuiltInFn("exp2", lib, "Exp2"))->arg("x") );
mod.addFunction( (new BuiltInFn("log2", lib, "Log2"))->arg("x") );
mod.addFunction( (new BuiltInFn("rcp", lib, "Rcp"))->arg("x") );
mod.addFunction( (new BuiltInFn("rcp_est", lib, "RcpEst"))->arg("x") );
mod.addFunction( (new BuiltInFn("pow", lib, "Pow"))->args({"x","y"}) );
}
template
void addFunctionOp3i(Module & mod, const ModuleLibrary & lib) {
// policy ret arg1 arg2 arg3 name
mod.addFunction( (new BuiltInFn("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("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((float*)&mat);
}
void float3x4_identity ( float3x4 & mat ) {
matrix_identity((float*)&mat);
}
void float3x3_identity ( float3x3 & mat ) {
matrix_identity((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((float*)&mat);
return mat;
}
float3x4 float3x4_identity_m ( void ) {
float3x4 mat;
matrix_identity((float*)&mat);
return mat;
}
float3x3 float3x3_identity_m ( void ) {
float3x3 mat;
matrix_identity((float*)&mat);
return mat;
}
float4x4 float4x4_translation(float3 xyz) {
float4x4 mat;
matrix_identity((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::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("mad", lib, "MadS"))->args({"a","b","c"}) );
addFunction( (new BuiltInFn("mad", lib, "MadS"))->args({"a","b","c"}) );
addFunction( (new BuiltInFn("mad", lib, "MadS"))->args({"a","b","c"}) );
// op3i - int
addFunctionOp3i(*this,lib);
addFunctionOp3i(*this,lib);
addFunctionOp3i(*this,lib);
addFunctionOp3i(*this,lib);
addFunction( (new BuiltInFn("mad", lib, "MadS"))->args({"a","b","c"}) );
addFunction( (new BuiltInFn("mad", lib, "MadS"))->args({"a","b","c"}) );
addFunction( (new BuiltInFn("mad", lib, "MadS"))->args({"a","b","c"}) );
// op3i - uint
addFunctionOp3i(*this,lib);
addFunctionOp3i(*this,lib);
addFunctionOp3i(*this,lib);
addFunctionOp3i(*this,lib);
addFunction( (new BuiltInFn("mad", lib, "MadS"))->args({"a","b","c"}) );
addFunction( (new BuiltInFn("mad", lib, "MadS"))->args({"a","b","c"}) );
addFunction( (new BuiltInFn("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("floor", lib, "Floor"))->arg("x") );
addFunction( (new BuiltInFn("ceil", lib, "Ceil"))->arg("x") );
addFunction( (new BuiltInFn("fract", lib, "Fract"))->arg("x") );
addFunction( (new BuiltInFn("round", lib, "Round"))->arg("x") );
addFunction( (new BuiltInFn("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(*this, lib,
".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"});
addExtern(*this, lib,
".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"});
addExtern(*this, lib,
".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"});
addExtern(*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(*this, lib,
".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"});
addExtern(*this, lib,
".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"});
addExtern(*this, lib,
".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"});
addExtern(*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(*this, lib,
".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"});
addExtern(*this, lib,
".[]", SideEffects::none, "floatNxN_atci")->args({"m","i","context","at"});
addExtern(*this, lib,
".[]", SideEffects::modifyArgument, "floatNxN_ati")->args({"m","i","context","at"});
addExtern(*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