add zoom option to camera to work around the orthographic camera

This commit is contained in:
veclavtalica 2025-01-27 03:25:14 +03:00
parent 791ab628ca
commit 6a87119c70
5 changed files with 24 additions and 10 deletions

View File

@ -83,7 +83,8 @@ TWN_API void draw_billboard(const char *texture,
TWN_API void draw_camera(Vec3 position,
Vec3 direction, /* optional, default: (0, 0, -1) */
Vec3 up, /* optional, default: (0, 1, 0) */
float fov); /* optional, default: PI / 6 * 3 (90 degrees) */
float fov, /* optional, default: PI / 6 * 3 (90 degrees) */
float zoom); /* optional, default: 1 */
/* same as draw_camera(), but with first person controller in mind */
/* direction and up vectors are inferred from roll, pitch and yaw parameters (in radians) */
@ -97,7 +98,8 @@ draw_camera_from_principal_axes(Vec3 position,
float roll, /* optional, default: 0 */
float pitch, /* optional, default: 0 */
float yaw, /* optional, default: 0 */
float fov); /* optional, default: PI / 6 * 3 (90 degrees) */
float fov, /* optional, default: PI / 6 * 3 (90 degrees) */
float zoom); /* optional, default: 1 */
/* expects '*' masks that will be expanded to 6 names: 'up', 'down', 'east', 'west', 'north' and 'south' */
TWN_API void draw_skybox(const char *textures);

View File

@ -181,7 +181,8 @@
{ "name": "position", "type": "Vec3" },
{ "name": "direction", "type": "Vec3", "default": { "x": 0, "y": 0, "z": -1 } },
{ "name": "up", "type": "Vec3", "default": { "x": 0, "y": 1, "z": 0 } },
{ "name": "fov", "type": "float", "default": 1.57079632679 }
{ "name": "fov", "type": "float", "default": 1.57079632679 },
{ "name": "zoom", "type": "float", "default": 1 }
]
},
@ -194,7 +195,8 @@
{ "name": "roll", "type": "float", "default": 0 },
{ "name": "pitch", "type": "float", "default": 0 },
{ "name": "yaw", "type": "float", "default": 0 },
{ "name": "fov", "type": "float", "default": 1.57079632679 }
{ "name": "fov", "type": "float", "default": 1.57079632679 },
{ "name": "zoom", "type": "float", "default": 1 }
],
"return": {
"fields": [

View File

@ -413,7 +413,7 @@ void render(void) {
}
void draw_camera(Vec3 position, Vec3 direction, Vec3 up, float fov) {
void draw_camera(Vec3 position, Vec3 direction, Vec3 up, float fov, float zoom) {
bool const orthographic = fabsf(0.0f - fov) < 0.00001f;
if (!orthographic && fov >= M_PIf)
log_warn("Invalid fov given (%f)", (double)fov);
@ -423,6 +423,10 @@ void draw_camera(Vec3 position, Vec3 direction, Vec3 up, float fov) {
.pos = position,
.target = direction,
.up = up,
.viewbox = {
(Vec2){ 1/-zoom, 1/zoom },
(Vec2){ 1/zoom, 1/-zoom }
},
};
if (!orthographic)
@ -439,7 +443,8 @@ DrawCameraFromPrincipalAxesResult draw_camera_from_principal_axes(Vec3 position,
float roll,
float pitch,
float yaw,
float fov)
float fov,
float zoom)
{
bool const orthographic = fabsf(0.0f - fov) < 0.00001f;
if (!orthographic && fov >= M_PIf)
@ -460,6 +465,10 @@ DrawCameraFromPrincipalAxesResult draw_camera_from_principal_axes(Vec3 position,
yaws * pitchc,
})),
.up = (Vec3){0, 1, 0},
.viewbox = {
(Vec2){ 1/-zoom, 1/zoom },
(Vec2){ 1/zoom, 1/-zoom }
},
};
if (!orthographic)

View File

@ -59,15 +59,15 @@ Matrix4 camera_orthographic(const Camera *const camera) {
Matrix4 result = {0};
const float rl = 1.0f / (float)1;
const float tb = 1.0f / (float)1;
const float rl = 1.0f / (camera->viewbox[0].y - camera->viewbox[0].x);
const float tb = 1.0f / (camera->viewbox[1].x - camera->viewbox[1].y);
const float fn = -1.0f / (CAMERA_FAR_Z - CAMERA_NEAR_Z);
result.row[0].x = 2.0f * rl;
result.row[1].y = 2.0f * tb;
result.row[2].z = 2.0f * fn;
result.row[3].x = -(float)1 * rl;
result.row[3].y = -(float)1 * tb;
result.row[3].x = -(camera->viewbox[0].y + camera->viewbox[0].x) * rl;
result.row[3].y = -(camera->viewbox[1].x + camera->viewbox[1].y) * tb;
result.row[3].z = (CAMERA_FAR_Z + CAMERA_NEAR_Z) * fn;
result.row[3].w = 1.0f;

View File

@ -13,6 +13,7 @@ typedef struct Camera {
Vec3 target; /* normalized target vector */
Vec3 up; /* normalized up vector */
float fov; /* field of view, in radians */
Vec2 viewbox[2]; /* othrographic aabb, ((left, right), (top, bottom)) */
} Camera;
Matrix4 camera_look_at(const Camera *camera);