diff --git a/bind/v4k.lua b/bind/v4k.lua index 8f1a310..fff0fd5 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -1461,11 +1461,11 @@ typedef struct skybox_t { typedef struct camera_t { mat44 view, proj; vec3 position, updir, lookdir; - float yaw, pitch; + float yaw, pitch, roll; float speed, fov; float move_friction, move_damping; float look_friction, look_damping; - vec2 last_look; vec3 last_move; + vec3 last_look; vec3 last_move; bool damping; bool orthographic; float distance; @@ -1475,6 +1475,7 @@ typedef struct camera_t { void camera_moveby(camera_t *cam, vec3 inc); void camera_fov(camera_t *cam, float fov); void camera_fps(camera_t *cam, float yaw, float pitch); + void camera_fps2(camera_t *cam, float yaw, float pitch, float roll); void camera_orbit(camera_t *cam, float yaw, float pitch, float inc_distance); void camera_lookat(camera_t *cam, vec3 target); void camera_enable(camera_t *cam); diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index f429410..2aee142 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -17760,12 +17760,12 @@ API bool gizmo_hover(); typedef struct camera_t { mat44 view, proj; vec3 position, updir, lookdir; - float yaw, pitch; // mirror of (x,y) lookdir in deg; + float yaw, pitch, roll; // mirror of (x,y) lookdir in deg; float speed, fov; // fov in deg(45) float move_friction, move_damping; float look_friction, look_damping; - vec2 last_look; vec3 last_move; // used for friction and damping + vec3 last_look; vec3 last_move; // used for friction and damping bool damping; bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30º], isometric[if pitch == 35.264º] @@ -17779,6 +17779,7 @@ API void camera_teleport(camera_t *cam, vec3 pos); API void camera_moveby(camera_t *cam, vec3 inc); API void camera_fov(camera_t *cam, float fov); API void camera_fps(camera_t *cam, float yaw, float pitch); +API void camera_fps2(camera_t *cam, float yaw, float pitch, float roll); API void camera_orbit(camera_t *cam, float yaw, float pitch, float inc_distance); API void camera_lookat(camera_t *cam, vec3 target); API void camera_enable(camera_t *cam); @@ -374859,7 +374860,7 @@ camera_t camera() { cam.move_damping = 0.96f; cam.look_friction = 0.30f; cam.look_damping = 0.96f; - cam.last_look = vec2(0,0); + cam.last_look = vec3(0,0,0); cam.last_move = vec3(0,0,0); // update proj & view @@ -374958,7 +374959,7 @@ void camera_fov(camera_t *cam, float fov) { } } -void camera_fps(camera_t *cam, float yaw, float pitch) { +void camera_fps2(camera_t *cam, float yaw, float pitch, float roll) { last_camera = cam; // camera damping @@ -374966,23 +374967,43 @@ void camera_fps(camera_t *cam, float yaw, float pitch) { float fr = cam->look_friction; fr *= fr; fr *= fr; fr *= fr; float sm = clampf(cam->look_damping, 0, 0.999f); sm *= sm; sm *= sm; - cam->last_look = scale2(cam->last_look, 1 - fr); + cam->last_look = scale3(cam->last_look, 1 - fr); yaw = cam->last_look.y = yaw * (1 - sm) + cam->last_look.y * sm; pitch = cam->last_look.x = pitch * (1 - sm) + cam->last_look.x * sm; + roll = cam->last_look.z = roll * (1 - sm) + cam->last_look.z * sm; } cam->yaw += yaw; cam->yaw = fmod(cam->yaw, 360); cam->pitch += pitch; cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; + cam->roll += roll; + cam->roll += fmod(cam->roll, 360); - const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; + const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad, r = cam->roll * deg2rad; cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + vec3 up = vec3(0,1,0); + // calculate updir + { + float cosfa = cosf(r); + float sinfa = sinf(r); + vec3 right = cross3(cam->lookdir, up); + float th = dot3(cam->lookdir, up); + + cam->updir.x = up.x * cosfa + right.x * sinfa + cam->lookdir.x * th * (1.0f - cosfa); + cam->updir.y = up.y * cosfa + right.y * sinfa + cam->lookdir.y * th * (1.0f - cosfa); + cam->updir.z = up.z * cosfa + right.z * sinfa + cam->lookdir.z * th * (1.0f - cosfa); + } + lookat44(cam->view, cam->position, add3(cam->position, cam->lookdir), cam->updir); // eye,center,up camera_fov(cam, cam->fov); } +void camera_fps(camera_t *cam, float yaw, float pitch) { + camera_fps2(cam, yaw, pitch, 0.0f); +} + void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { last_camera = cam; diff --git a/engine/split/v4k_scene.c b/engine/split/v4k_scene.c index 96a417c..c49c35c 100644 --- a/engine/split/v4k_scene.c +++ b/engine/split/v4k_scene.c @@ -20,7 +20,7 @@ camera_t camera() { cam.move_damping = 0.96f; cam.look_friction = 0.30f; cam.look_damping = 0.96f; - cam.last_look = vec2(0,0); + cam.last_look = vec3(0,0,0); cam.last_move = vec3(0,0,0); // update proj & view @@ -119,7 +119,7 @@ void camera_fov(camera_t *cam, float fov) { } } -void camera_fps(camera_t *cam, float yaw, float pitch) { +void camera_fps2(camera_t *cam, float yaw, float pitch, float roll) { last_camera = cam; // camera damping @@ -127,23 +127,43 @@ void camera_fps(camera_t *cam, float yaw, float pitch) { float fr = cam->look_friction; fr *= fr; fr *= fr; fr *= fr; float sm = clampf(cam->look_damping, 0, 0.999f); sm *= sm; sm *= sm; - cam->last_look = scale2(cam->last_look, 1 - fr); + cam->last_look = scale3(cam->last_look, 1 - fr); yaw = cam->last_look.y = yaw * (1 - sm) + cam->last_look.y * sm; pitch = cam->last_look.x = pitch * (1 - sm) + cam->last_look.x * sm; + roll = cam->last_look.z = roll * (1 - sm) + cam->last_look.z * sm; } cam->yaw += yaw; cam->yaw = fmod(cam->yaw, 360); cam->pitch += pitch; cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; + cam->roll += roll; + cam->roll += fmod(cam->roll, 360); - const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; + const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad, r = cam->roll * deg2rad; cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + vec3 up = vec3(0,1,0); + // calculate updir + { + float cosfa = cosf(r); + float sinfa = sinf(r); + vec3 right = cross3(cam->lookdir, up); + float th = dot3(cam->lookdir, up); + + cam->updir.x = up.x * cosfa + right.x * sinfa + cam->lookdir.x * th * (1.0f - cosfa); + cam->updir.y = up.y * cosfa + right.y * sinfa + cam->lookdir.y * th * (1.0f - cosfa); + cam->updir.z = up.z * cosfa + right.z * sinfa + cam->lookdir.z * th * (1.0f - cosfa); + } + lookat44(cam->view, cam->position, add3(cam->position, cam->lookdir), cam->updir); // eye,center,up camera_fov(cam, cam->fov); } +void camera_fps(camera_t *cam, float yaw, float pitch) { + camera_fps2(cam, yaw, pitch, 0.0f); +} + void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { last_camera = cam; diff --git a/engine/split/v4k_scene.h b/engine/split/v4k_scene.h index 0052f93..e4fed0f 100644 --- a/engine/split/v4k_scene.h +++ b/engine/split/v4k_scene.h @@ -7,12 +7,12 @@ typedef struct camera_t { mat44 view, proj; vec3 position, updir, lookdir; - float yaw, pitch; // mirror of (x,y) lookdir in deg; + float yaw, pitch, roll; // mirror of (x,y) lookdir in deg; float speed, fov; // fov in deg(45) float move_friction, move_damping; float look_friction, look_damping; - vec2 last_look; vec3 last_move; // used for friction and damping + vec3 last_look; vec3 last_move; // used for friction and damping bool damping; bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30º], isometric[if pitch == 35.264º] @@ -26,6 +26,7 @@ API void camera_teleport(camera_t *cam, vec3 pos); API void camera_moveby(camera_t *cam, vec3 inc); API void camera_fov(camera_t *cam, float fov); API void camera_fps(camera_t *cam, float yaw, float pitch); +API void camera_fps2(camera_t *cam, float yaw, float pitch, float roll); API void camera_orbit(camera_t *cam, float yaw, float pitch, float inc_distance); API void camera_lookat(camera_t *cam, vec3 target); API void camera_enable(camera_t *cam); diff --git a/engine/v4k.c b/engine/v4k.c index c1d3e4d..9371da1 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -21997,7 +21997,7 @@ camera_t camera() { cam.move_damping = 0.96f; cam.look_friction = 0.30f; cam.look_damping = 0.96f; - cam.last_look = vec2(0,0); + cam.last_look = vec3(0,0,0); cam.last_move = vec3(0,0,0); // update proj & view @@ -22096,7 +22096,7 @@ void camera_fov(camera_t *cam, float fov) { } } -void camera_fps(camera_t *cam, float yaw, float pitch) { +void camera_fps2(camera_t *cam, float yaw, float pitch, float roll) { last_camera = cam; // camera damping @@ -22104,23 +22104,43 @@ void camera_fps(camera_t *cam, float yaw, float pitch) { float fr = cam->look_friction; fr *= fr; fr *= fr; fr *= fr; float sm = clampf(cam->look_damping, 0, 0.999f); sm *= sm; sm *= sm; - cam->last_look = scale2(cam->last_look, 1 - fr); + cam->last_look = scale3(cam->last_look, 1 - fr); yaw = cam->last_look.y = yaw * (1 - sm) + cam->last_look.y * sm; pitch = cam->last_look.x = pitch * (1 - sm) + cam->last_look.x * sm; + roll = cam->last_look.z = roll * (1 - sm) + cam->last_look.z * sm; } cam->yaw += yaw; cam->yaw = fmod(cam->yaw, 360); cam->pitch += pitch; cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; + cam->roll += roll; + cam->roll += fmod(cam->roll, 360); - const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; + const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad, r = cam->roll * deg2rad; cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + vec3 up = vec3(0,1,0); + // calculate updir + { + float cosfa = cosf(r); + float sinfa = sinf(r); + vec3 right = cross3(cam->lookdir, up); + float th = dot3(cam->lookdir, up); + + cam->updir.x = up.x * cosfa + right.x * sinfa + cam->lookdir.x * th * (1.0f - cosfa); + cam->updir.y = up.y * cosfa + right.y * sinfa + cam->lookdir.y * th * (1.0f - cosfa); + cam->updir.z = up.z * cosfa + right.z * sinfa + cam->lookdir.z * th * (1.0f - cosfa); + } + lookat44(cam->view, cam->position, add3(cam->position, cam->lookdir), cam->updir); // eye,center,up camera_fov(cam, cam->fov); } +void camera_fps(camera_t *cam, float yaw, float pitch) { + camera_fps2(cam, yaw, pitch, 0.0f); +} + void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { last_camera = cam; diff --git a/engine/v4k.h b/engine/v4k.h index 4ac0a70..a3db514 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -3827,12 +3827,12 @@ API bool gizmo_hover(); typedef struct camera_t { mat44 view, proj; vec3 position, updir, lookdir; - float yaw, pitch; // mirror of (x,y) lookdir in deg; + float yaw, pitch, roll; // mirror of (x,y) lookdir in deg; float speed, fov; // fov in deg(45) float move_friction, move_damping; float look_friction, look_damping; - vec2 last_look; vec3 last_move; // used for friction and damping + vec3 last_look; vec3 last_move; // used for friction and damping bool damping; bool orthographic; // 0 perspective, 1 orthographic; when ortho: dimetric[if pitch == -30º], isometric[if pitch == 35.264º] @@ -3846,6 +3846,7 @@ API void camera_teleport(camera_t *cam, vec3 pos); API void camera_moveby(camera_t *cam, vec3 inc); API void camera_fov(camera_t *cam, float fov); API void camera_fps(camera_t *cam, float yaw, float pitch); +API void camera_fps2(camera_t *cam, float yaw, float pitch, float roll); API void camera_orbit(camera_t *cam, float yaw, float pitch, float inc_distance); API void camera_lookat(camera_t *cam, vec3 target); API void camera_enable(camera_t *cam);