diff --git a/module/libmat.nas b/module/libmat.nas new file mode 100644 index 0000000..f82a1f4 --- /dev/null +++ b/module/libmat.nas @@ -0,0 +1,58 @@ +var libmat=func(){ + var dl=dylib.dlopen("libmat."~(os.platform()=="windows"?"dll":"so")); + var vec2=dylib.dlsym(dl,"nas_vec2"); + var vec3=dylib.dlsym(dl,"nas_vec3"); + var (vec2add,vec2sub,vec2mul,vec2div,vec2neg,vec2norm,vec2len,vec2dot)=( + dylib.dlsym(dl,"nas_vec2_add"), + dylib.dlsym(dl,"nas_vec2_sub"), + dylib.dlsym(dl,"nas_vec2_mult"), + dylib.dlsym(dl,"nas_vec2_div"), + dylib.dlsym(dl,"nas_vec2_neg"), + dylib.dlsym(dl,"nas_vec2_norm"), + dylib.dlsym(dl,"nas_vec2_len"), + dylib.dlsym(dl,"nas_vec2_dot") + ); + var (vec3add,vec3sub,vec3mul,vec3div,vec3neg,vec3norm,vec3len,vec3dot)=( + dylib.dlsym(dl,"nas_vec3_add"), + dylib.dlsym(dl,"nas_vec3_sub"), + dylib.dlsym(dl,"nas_vec3_mult"), + dylib.dlsym(dl,"nas_vec3_div"), + dylib.dlsym(dl,"nas_vec3_neg"), + dylib.dlsym(dl,"nas_vec3_norm"), + dylib.dlsym(dl,"nas_vec3_len"), + dylib.dlsym(dl,"nas_vec3_dot") + ); + var (rotate_x,rotate_y,rotate_z)=( + dylib.dlsym(dl,"nas_rotate_x"), + dylib.dlsym(dl,"nas_rotate_y"), + dylib.dlsym(dl,"nas_rotate_z") + ); + var call=dylib.dlcall; + return { + vec2:{ + new:func(x,y){return call(vec2,x,y);}, + add:func(v0,v1){return call(vec2add,v0,v1);}, + sub:func(v0,v1){return call(vec2sub,v0,v1);}, + mul:func(v0,v1){return call(vec2mul,v0,v1);}, + div:func(v0,v1){return call(vec2div,v0,v1);}, + neg:func(v0){return call(vec2neg,v0);}, + norm:func(v0){return call(vec2norm,v0);}, + len:func(v0){return call(vec2len,v0);}, + dot:func(v0,v1){return call(vec2dot,v0,v1);} + }, + vec3:{ + new:func(x,y,z){return call(vec3,x,y,z);}, + add:func(v0,v1){return call(vec3add,v0,v1);}, + sub:func(v0,v1){return call(vec3sub,v0,v1);}, + mul:func(v0,v1){return call(vec3mul,v0,v1);}, + div:func(v0,v1){return call(vec3div,v0,v1);}, + neg:func(v0){return call(vec3neg,v0);}, + norm:func(v0){return call(vec3norm,v0);}, + len:func(v0){return call(vec3len,v0);}, + rx:func(v0,angle){return call(rotate_x,v0,angle);}, + ry:func(v0,angle){return call(rotate_y,v0,angle);}, + rz:func(v0,angle){return call(rotate_z,v0,angle);}, + dot:func(v0,v1){return call(vec3dot,v0,v1);} + } + }; +}(); \ No newline at end of file diff --git a/module/makefile b/module/makefile index ea14aff..0b78959 100644 --- a/module/makefile +++ b/module/makefile @@ -1,7 +1,7 @@ .PHONY=clean all mingw-all -dynamic_libs=libfib.so libkey.so libnasock.so -dynamic_libs_dll=libfib.dll libkey.dll libnasock.dll +dynamic_libs_so=libfib.so libkey.so libnasock.so libmat.so +dynamic_libs_dll=libfib.dll libkey.dll libnasock.dll libmat.dll STD=c++14 @@ -38,13 +38,24 @@ libnasock.dll: nasocket.cpp @ $(CXX) -shared -o libnasock.dll nasocket.o -lwsock32 -static @ del nasocket.o +libmat.so: matrix.cpp + @ echo "[Compiling] libmat.so" + @ $(CXX) -std=$(STD) -c -O3 matrix.cpp -fPIC -o matrix.o + @ $(CXX) -shared -o libmat.so matrix.o + @ rm matrix.o +libmat.dll: matrix.cpp + @ echo [Compiling] libmat.dll + @ $(CXX) -std=$(STD) -c -O3 matrix.cpp -fPIC -o matrix.o -static + @ $(CXX) -shared -o libmat.dll matrix.o -static + @ del matrix.o + clean: @ echo "[clean] so" - -@ rm $(dynamic_libs) + -@ rm $(dynamic_libs_so) @ echo "[clean] dll" -@ rm $(dynamic_libs_dll) -all: libfib.so libkey.so libnasock.so +all: $(dynamic_libs_so) @ echo "[Compiling] done" -winall: libfib.dll libkey.dll libnasock.dll +winall: $(dynamic_libs_dll) @ echo [Compiling] done diff --git a/module/matrix.cpp b/module/matrix.cpp new file mode 100644 index 0000000..e3511ec --- /dev/null +++ b/module/matrix.cpp @@ -0,0 +1,314 @@ +#include "../nasal.h" +#include + +var nas_vec2(var* args,usize size,gc* ngc){ + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(args[0]); + res.vec().elems.push_back(args[1]); + return res; +} + +var nas_vec3(var* args,usize size,gc* ngc){ + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(args[0]); + res.vec().elems.push_back(args[1]); + res.vec().elems.push_back(args[2]); + return res; +} + +var nas_vec2_add(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=2 || v1.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()+v1[0].num()}); + res.vec().elems.push_back({vm_num,v0[1].num()+v1[1].num()}); + return res; +} + +var nas_vec2_sub(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=2 || v1.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()-v1[0].num()}); + res.vec().elems.push_back({vm_num,v0[1].num()-v1[1].num()}); + return res; +} + +var nas_vec2_mult(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=2 || v1.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()*v1[0].num()}); + res.vec().elems.push_back({vm_num,v0[1].num()*v1[1].num()}); + return res; +} + +var nas_vec2_div(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=2 || v1.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()/v1[0].num()}); + res.vec().elems.push_back({vm_num,v0[1].num()/v1[1].num()}); + return res; +} + +var nas_vec2_neg(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,-v0[0].num()}); + res.vec().elems.push_back({vm_num,-v0[1].num()}); + return res; +} + +var nas_vec2_norm(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=2) + return nil; + auto x=v0[0].num(); + auto y=v0[1].num(); + auto t=std::sqrt(x*x+y*y); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,x/t}); + res.vec().elems.push_back({vm_num,y/t}); + return res; +} + +var nas_vec2_len(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=2) + return nil; + auto x=v0[0].num(); + auto y=v0[1].num(); + return {vm_num,std::sqrt(x*x+y*y)}; +} + +var nas_vec2_dot(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=2 || v1.size()!=2) + return nil; + return {vm_num,v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()}; +} + +var nas_vec3_add(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=3 || v1.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()+v1[0].num()}); + res.vec().elems.push_back({vm_num,v0[1].num()+v1[1].num()}); + res.vec().elems.push_back({vm_num,v0[2].num()+v1[2].num()}); + return res; +} + +var nas_vec3_sub(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=3 || v1.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()-v1[0].num()}); + res.vec().elems.push_back({vm_num,v0[1].num()-v1[1].num()}); + res.vec().elems.push_back({vm_num,v0[2].num()-v1[2].num()}); + return res; +} + +var nas_vec3_mult(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=3 || v1.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()*v1[0].num()}); + res.vec().elems.push_back({vm_num,v0[1].num()*v1[1].num()}); + res.vec().elems.push_back({vm_num,v0[2].num()*v1[2].num()}); + return res; +} + +var nas_vec3_div(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=3 || v1.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()/v1[0].num()}); + res.vec().elems.push_back({vm_num,v0[1].num()/v1[1].num()}); + res.vec().elems.push_back({vm_num,v0[2].num()/v1[2].num()}); + return res; +} + +var nas_vec3_neg(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,-v0[0].num()}); + res.vec().elems.push_back({vm_num,-v0[1].num()}); + res.vec().elems.push_back({vm_num,-v0[2].num()}); + return res; +} + +var nas_vec3_norm(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=3) + return nil; + auto x=v0[0].num(); + auto y=v0[1].num(); + auto z=v0[2].num(); + auto t=std::sqrt(x*x+y*y+z*z); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,x/t}); + res.vec().elems.push_back({vm_num,y/t}); + res.vec().elems.push_back({vm_num,z/t}); + return res; +} + +var nas_vec3_len(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=3) + return nil; + auto x=v0[0].num(); + auto y=v0[1].num(); + auto z=v0[2].num(); + return {vm_num,std::sqrt(x*x+y*y+z*z)}; +} + +var nas_rotate_x(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=3) + return nil; + auto angle=args[1].num(); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()}); + res.vec().elems.push_back({vm_num,v0[2].num()*std::sin(angle)+v0[1].num()*std::cos(angle)}); + res.vec().elems.push_back({vm_num,v0[2].num()*std::cos(angle)-v0[1].num()*std::sin(angle)}); + return res; +} + +var nas_rotate_y(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=3) + return nil; + auto angle=args[1].num(); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()*std::cos(angle)-v0[2].num()*std::sin(angle)}); + res.vec().elems.push_back({vm_num,v0[1].num()}); + res.vec().elems.push_back({vm_num,v0[0].num()*std::sin(angle)+v0[2].num()*std::cos(angle)}); + return res; +} + +var nas_rotate_z(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if(v0.size()!=3) + return nil; + auto angle=args[1].num(); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back({vm_num,v0[0].num()*std::cos(angle)-v0[1].num()*std::sin(angle)}); + res.vec().elems.push_back({vm_num,v0[0].num()*std::sin(angle)+v0[1].num()*std::cos(angle)}); + res.vec().elems.push_back({vm_num,v0[2].num()}); + return res; +} + +var nas_vec3_dot(var* args,usize size,gc* ngc){ + if(args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if(v0.size()!=3 || v1.size()!=3) + return nil; + return {vm_num,v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()+v0[2].num()*v1[2].num()}; +} + +extern "C" mod get(const char* n){ + string name=n; + if(name=="nas_vec2") + return nas_vec2; + else if(name=="nas_vec2_add") + return nas_vec2_add; + else if(name=="nas_vec2_sub") + return nas_vec2_sub; + else if(name=="nas_vec2_mult") + return nas_vec2_mult; + else if(name=="nas_vec2_div") + return nas_vec2_div; + else if(name=="nas_vec2_neg") + return nas_vec2_neg; + else if(name=="nas_vec2_norm") + return nas_vec2_norm; + else if(name=="nas_vec2_len") + return nas_vec2_len; + else if(name=="nas_vec2_dot") + return nas_vec2_dot; + else if(name=="nas_vec3") + return nas_vec3; + else if(name=="nas_vec3_add") + return nas_vec3_add; + else if(name=="nas_vec3_sub") + return nas_vec3_sub; + else if(name=="nas_vec3_mult") + return nas_vec3_mult; + else if(name=="nas_vec3_div") + return nas_vec3_div; + else if(name=="nas_vec3_neg") + return nas_vec3_neg; + else if(name=="nas_vec3_norm") + return nas_vec3_norm; + else if(name=="nas_vec3_len") + return nas_vec3_len; + else if(name=="nas_rotate_x") + return nas_rotate_x; + else if(name=="nas_rotate_y") + return nas_rotate_y; + else if(name=="nas_rotate_z") + return nas_rotate_z; + else if(name=="nas_vec3_dot") + return nas_vec3_dot; + return nullptr; +} \ No newline at end of file diff --git a/nasal_vm.h b/nasal_vm.h index 54af6cb..596226d 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -972,7 +972,7 @@ void vm::run( typedef void (vm::*nafunc)(); const nafunc oprs[]= { - nullptr, &vm::o_intg, + nullptr, &vm::o_intg, &vm::o_intl, &vm::o_loadg, &vm::o_loadl, &vm::o_loadu, &vm::o_pnum, &vm::o_pnil, diff --git a/test/calc.nas b/test/calc.nas index 76a08fb..96c8628 100644 --- a/test/calc.nas +++ b/test/calc.nas @@ -86,9 +86,11 @@ var testfile=[ var module=[ "fib.cpp", "keyboard.cpp", + "matrix.cpp", "nasocket.cpp", "libfib.nas", "libkey.nas", + "libmat.nas", "libsock.nas" ]; diff --git a/test/console3D.nas b/test/console3D.nas index a7bf923..7259dd7 100644 --- a/test/console3D.nas +++ b/test/console3D.nas @@ -21,6 +21,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import.module.libmat; func(){ # allocate more spaces @@ -32,39 +33,49 @@ func(){ var (max,min,sqrt,sin,cos,abs)=(math.max,math.min,math.sqrt,math.sin,math.cos,math.abs); -var vec2=func(x,y){ - return [x,y]; -} -var vec2add=func(v1,v2){ - return [v1[0]+v2[0],v1[1]+v2[1]]; -} -var vec2sub=func(v1,v2){ - return [v1[0]-v2[0],v1[1]-v2[1]]; -} -var vec2mul=func(v1,v2){ - return [v1[0]*v2[0],v1[1]*v2[1]]; -} -var vec2div=func(v1,v2){ - return [v1[0]/v2[0],v1[1]/v2[1]]; -} +var (vec2,vec3)=(libmat.vec2.new,libmat.vec3.new); +var (vec2add,vec2sub,vec2mul,vec2div,vec2len)=( + libmat.vec2.add, + libmat.vec2.sub, + libmat.vec2.mul, + libmat.vec2.div, + libmat.vec2.len +); +var (vec3add,vec3sub,vec3mul,vec3div,vec3neg,vec3norm,vec3len,vec3dot)=( + libmat.vec3.add, + libmat.vec3.sub, + libmat.vec3.mul, + libmat.vec3.div, + libmat.vec3.neg, + libmat.vec3.norm, + libmat.vec3.len, + libmat.vec3.dot +); +var (rotateX,rotateY,rotateZ)=( + libmat.vec3.rx, + libmat.vec3.ry, + libmat.vec3.rz, +); -var vec3=func(x,y,z){ - return [x,y,z]; -} -var vec3add=func(v1,v2){ - return [v1[0]+v2[0],v1[1]+v2[1],v1[2]+v2[2]]; -} -var vec3sub=func(v1,v2){ - return [v1[0]-v2[0],v1[1]-v2[1],v1[2]-v2[2]]; -} -var vec3mul=func(v1,v2){ - return [v1[0]*v2[0],v1[1]*v2[1],v1[2]*v2[2]]; -} -var vec3div=func(v1,v2){ - return [v1[0]/v2[0],v1[1]/v2[1],v1[2]/v2[2]]; -} -var vec3neg=func(v){ - return [-v[0],-v[1],-v[2]]; +var use_raw=func(){ + vec2=func(x,y){return [x,y];} + vec2add=func(v1,v2){return [v1[0]+v2[0],v1[1]+v2[1]];} + vec2sub=func(v1,v2){return [v1[0]-v2[0],v1[1]-v2[1]];} + vec2mul=func(v1,v2){return [v1[0]*v2[0],v1[1]*v2[1]];} + vec2div=func(v1,v2){return [v1[0]/v2[0],v1[1]/v2[1]];} + vec3=func(x,y,z){return [x,y,z];} + vec3add=func(v1,v2){return [v1[0]+v2[0],v1[1]+v2[1],v1[2]+v2[2]];} + vec3sub=func(v1,v2){return [v1[0]-v2[0],v1[1]-v2[1],v1[2]-v2[2]];} + vec3mul=func(v1,v2){return [v1[0]*v2[0],v1[1]*v2[1],v1[2]*v2[2]];} + vec3div=func(v1,v2){return [v1[0]/v2[0],v1[1]/v2[1],v1[2]/v2[2]];} + vec3neg=func(v){return [-v[0],-v[1],-v[2]];} + vec2len=func(v){var (x,y)=(v[0],v[1]); return sqrt(x*x+y*y);} + vec3len=func(v){var (x,y,z)=(v[0],v[1],v[2]); return sqrt(x*x+y*y+z*z);} + vec3norm=func(v){var t=vec3len(v); return vec3div(v,[t,t,t]);} + vec3dot=func(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];} + rotateX=func(a,angle){return [a[0],a[2]*sin(angle)+a[1]*cos(angle),a[2]*cos(angle)-a[1]*sin(angle)];} + rotateY=func(a,angle){return [a[0]*cos(angle)-a[2]*sin(angle),a[1],a[0]*sin(angle)+a[2]*cos(angle)];} + rotateZ=func(a,angle){return [a[0]*cos(angle)-a[1]*sin(angle),a[0]*sin(angle)+a[1]*cos(angle),a[2]];} } var clamp=func(value,_min,_max){ @@ -76,20 +87,7 @@ var sign=func(a){ var step=func(edge,x){ return x>edge; } -var vec2len=func(v){ - return sqrt(v[0]*v[0]+v[1]*v[1]); -} -var vec3len=func(v){ - return sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); -} -var vec3norm=func(v){ - var t=vec3len(v); - return vec3div(v,[t,t,t]); -} -var vec3dot=func(a,b){ - return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]; -} var vec3abs=func(v){ return [abs(v[0]),abs(v[1]),abs(v[2])]; } @@ -104,32 +102,6 @@ var vec3reflect=func(rd,n){ return vec3sub(rd,vec3mul(n,vec3mul([2,2,2],[d,d,d]))); } -var rotateX=func(a,angle){ - return [ - a[0], - a[2]*sin(angle)+a[1]*cos(angle), - a[2]*cos(angle)-a[1]*sin(angle) - ]; -} - -var rotateY=func(a,angle) -{ - return [ - a[0]*cos(angle)-a[2]*sin(angle), - a[1], - a[0]*sin(angle)+a[2]*cos(angle) - ]; -} - -var rotateZ=func(a,angle) -{ - return [ - a[0]*cos(angle)-a[1]*sin(angle), - a[0]*sin(angle)+a[1]*cos(angle), - a[2] - ]; -} - var sphere=func(ro,rd,r) { var b=vec3dot(ro,rd); var c=vec3dot(ro,ro)-r*r; @@ -161,7 +133,7 @@ var plane=func(ro,rd,p,w) { return -(vec3dot(ro,p)+w)/vec3dot(rd,p); } -var main=func() { +var main=func(frame) { var height=15*2; var width=int(height*1600/900)*2; @@ -177,7 +149,7 @@ var main=func() { print("\e[2J"); var stamp=maketimestamp(); - for(var t=0;t<1e3;t+=1){ + for(var t=0;t