diff --git a/run b/run index 03605cc..3d72582 100755 --- a/run +++ b/run @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -e ./lua_translate -gcc src/main.c -g -lSDL2 -llua5.3 -o engine -O3 -Werror -Wall +gcc src/main.c -g -lSDL2 -llua5.3 -lm -o engine -O3 -Werror -Wall exec ./engine diff --git a/src/3d.c b/src/3d.c new file mode 100644 index 0000000..84eb1f1 --- /dev/null +++ b/src/3d.c @@ -0,0 +1,49 @@ +#include + +void engine_3d_find_rotation(struct ENGINE_VECTOR_3D * rot,float x, float y, float z) { + float distance = sqrtf(x * x + y * y); + rot->x = atan2f(y,x) * (180.0/M_PI); + rot->y = atan2f(z,distance) * (180.0/M_PI); + rot->z = 0.0; +} + +void engine_3d_rotate_position(struct ENGINE_VECTOR_3D * pos,float x, float y, float z, float rx, float ry, float rz) { + rx = rx * (M_PI/180.0); + ry = ry * (M_PI/180.0); + rz = rz * (M_PI/180.0); + float sinX = sinf(rx); + float cosX = cosf(rx); + float sinY = sinf(ry); + float cosY = cosf(ry); + float sinZ = sinf(rz); + float cosZ = cosf(rz); + pos->x = x * (cosY * cosZ) + y * (sinX * sinY * cosZ - cosX * sinZ) + z * (cosX * sinY * cosZ + sinX * sinZ); + pos->y = x * (cosY * sinZ) + y * (sinX * sinY * sinZ + cosX * cosZ) + z * (cosX * sinY * sinZ - sinX * cosZ); + pos->z = x * (-sinY) + y * (sinX * cosY) + z * (cosX * cosY); +} + +void engine_3d_project(struct ENGINE_VECTOR_2D * screen,float x, float y, float z, float rx, float ry, float rz, float fov) { + struct ENGINE_VECTOR_3D pos; + pos.x = x; + pos.y = y; + pos.z = z; + + engine_3d_rotate_position(&pos,pos.x,pos.y,pos.z,0.0,ry,0.0); + engine_3d_rotate_position(&pos,pos.x,pos.y,pos.z,0.0,0.0,rx); + pos.x = -pos.x; pos.y = -pos.y; pos.z = -pos.z; + struct ENGINE_VECTOR_3D rot; + engine_3d_find_rotation(&rot,pos.x,pos.y,pos.z); + + // rot.y (screen X) + while (rot.y > 180.0) { rot.y -= 360.0; } + while (rot.y < -180.0) { rot.y += 360.0; } + rot.y = rot.y / (fov * 0.5); + + // rot.x (screen Y) + while (rot.x > 180.0) { rot.x -= 360.0; } + while (rot.x < -180.0) { rot.x += 360.0; } + rot.x = rot.x / (fov * 0.5); + + screen->x = rot.y; + screen->y = rot.x; +} \ No newline at end of file diff --git a/src/lua_manual.c b/src/lua_manual.c index 8e480e0..7f15930 100644 --- a/src/lua_manual.c +++ b/src/lua_manual.c @@ -36,6 +36,50 @@ int engine_luaf_window_texture_get(lua_State *L) { return 1; } +int engine_luaf_3d_find_rotation(lua_State *L) { + float x = luaL_checknumber(L,1); + float y = luaL_checknumber(L,2); + float z = luaL_checknumber(L,3); + + struct ENGINE_VECTOR_3D rot; + engine_3d_find_rotation(&rot,x,y,z); + lua_pushnumber(L,rot.x); + lua_pushnumber(L,rot.y); + lua_pushnumber(L,rot.z); + return 3; +} + +int engine_luaf_3d_rotate_position(lua_State *L) { + float x = luaL_checknumber(L,1); + float y = luaL_checknumber(L,2); + float z = luaL_checknumber(L,3); + float rx = luaL_checknumber(L,4); + float ry = luaL_checknumber(L,5); + float rz = luaL_checknumber(L,6); + + struct ENGINE_VECTOR_3D pos; + engine_3d_rotate_position(&pos,x,y,z,rx,ry,rz); + lua_pushnumber(L,pos.x); + lua_pushnumber(L,pos.y); + lua_pushnumber(L,pos.z); + return 3; +} + +int engine_luaf_3d_project(lua_State *L) { + float x = luaL_checknumber(L,1); + float y = luaL_checknumber(L,2); + float z = luaL_checknumber(L,3); + float rx = luaL_checknumber(L,4); + float ry = luaL_checknumber(L,5); + float rz = luaL_checknumber(L,6); + float fov = luaL_checknumber(L,7); + struct ENGINE_VECTOR_2D pos; + engine_3d_project(&pos,x,y,z,rx,ry,rz,fov); + lua_pushnumber(L,pos.x); + lua_pushnumber(L,pos.y); + return 2; +} + void engine_lua_init_manual() { lua_pushcfunction(engine_lua_state,engine_luaf_lua_event_get_data); lua_setglobal (engine_lua_state,"engine_lua_event_get_data"); @@ -43,4 +87,10 @@ void engine_lua_init_manual() { lua_setglobal (engine_lua_state,"engine_texture_color_get"); lua_pushcfunction(engine_lua_state,engine_luaf_window_texture_get); lua_setglobal (engine_lua_state,"engine_window_texture_get"); + lua_pushcfunction(engine_lua_state,engine_luaf_3d_find_rotation); + lua_setglobal (engine_lua_state,"engine_3d_find_rotation"); + lua_pushcfunction(engine_lua_state,engine_luaf_3d_rotate_position); + lua_setglobal (engine_lua_state,"engine_3d_rotate_position"); + lua_pushcfunction(engine_lua_state,engine_luaf_3d_project); + lua_setglobal (engine_lua_state,"engine_3d_project"); } diff --git a/src/main.c b/src/main.c index c212070..1e8f2b9 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include "frontend/sdl/structs.c" //#include "frontend/sdl/structs.c" #include "engine.c" +#include "3d.c" #include "frontend/sdl/main.c" #include "helpers.c" //#include "frontend/sdl/main.c" diff --git a/src/values/functions.toml b/src/values/functions.toml index 0ed4b49..285c70e 100644 --- a/src/values/functions.toml +++ b/src/values/functions.toml @@ -120,3 +120,25 @@ type = "void" arguments = ["struct ENGINE_WINDOW *"] argNames = ["window"] description = "Destroy a window." + +# 3D +[engine_3d_find_rotation] +type = "void" +arguments = ["struct ENGINE_VECTOR_3D *","float","float","float"] +argNames = ["rot", "x", "y", "z"] +description = "Find the rotation required to get from 0,0,0 to the coordinates (look at). Output is put into rot pointer. Pointer not required in Lua." +lua = "manual" + +[engine_3d_rotate_position] +type = "void" +arguments = ["struct ENGINE_VECTOR_3D *","float","float","float","float","float","float"] +argNames = ["pos", "x", "y", "z", "rx", "ry", "rz"] +description = "Rotate a point around 0,0,0 using rotation vectors. Output is put into pos pointer. Pointer not required in Lua." +lua = "manual" + +[engine_3d_project] +type = "void" +arguments = ["struct ENGINE_VECTOR_2D *","float","float","float","float","float","float","float"] +argNames = ["screen", "x", "y", "z", "rx", "ry", "rz", "fov"] +description = "Project a 3D point onto a 2D surface. -1. = Top/Left, 1. = Bottom/Right. Output is put into screen pointer. Pointer not required in Lua." +lua = "manual"