// Native C++ Lua bytecode target. Only self/owner handles are visible. struct NgpValue { uint tag; float n; uint s; }; struct NgpTuple { NgpValue v[8]; int count; }; FProj ngp_proj; vec3 ngp_owner; float ngp_owner_id; bool ngp_failed, ngp_loaded; uint ngp_line; uvec4 ngp_error; vec3 ngp_surface(vec2 start,vec2 end); NgpValue ngp_nil() { return NgpValue(0u,0.0,0u); } NgpValue ngp_num(float n) { return NgpValue(1u,n,0u); } NgpValue ngp_bool(bool b) { return NgpValue(2u,b?1.0:0.0,0u); } NgpValue ngp_string(uint s) { return NgpValue(3u,0.0,s); } NgpTuple ngp_empty() { NgpTuple t;t.count=0;for(int i=0;i<8;i++)t.v[i]=ngp_nil();return t; } NgpTuple ngp_one(NgpValue v) { NgpTuple t=ngp_empty();t.count=1;t.v[0]=v;return t; } void ngp_fault(uint code) {if(!ngp_failed)ngp_error=uvec4(code,ngp_line,1u,0u);ngp_failed=true;} bool ngp_truth(NgpValue v) {return v.tag!=0u&&!(v.tag==2u&&v.n==0.0);} bool ngp_equal(NgpValue a,NgpValue b) {return a.tag==b.tag&&(a.tag==0u||(a.tag>=3u?a.s==b.s:a.n==b.n));} float ngp_number(NgpValue v) { float n;if(v.tag==1u)return v.n; if(v.tag==3u&&ngp_parse_number(v.s,n))return n; ngp_fault(1u);return 0.0; } bool ngp_less(NgpValue a,NgpValue b,bool equal) { if(a.tag==3u&&b.tag==3u)return equal?ngp_rank(a.s)<=ngp_rank(b.s):ngp_rank(a.s)=10u&&api<=15u){ int count=(api==12u||api==15u)?2:1; if(a.count!=count){ngp_fault(2u);return ngp_empty();} float x=ngp_number(a.v[0]), y=count==2?ngp_number(a.v[1]):0.0, value=0.0; if(api==10u)value=abs(x); if(api==11u)value=sqrt(x); // GLSL atan(0,0) is undefined; LuaJIT/libm returns signed zero or pi. if(api==12u){ if(x==0.0)value=(floatBitsToUint(y)&0x80000000u)!=0u?3.141592653589793:0.0; else if(y==0.0)value=1.5707963267948966; else value=atan(abs(x),y); if((floatBitsToUint(x)&0x80000000u)!=0u)value=-value; } if(api==13u)value=cos(x); if(api==14u)value=sin(x); if(api==15u)value=max(x,y); return ngp_one(ngp_num(value)); } ngp_fault(3u);return ngp_empty(); }