twn_draw: draw_camera_unproject()
This commit is contained in:
@ -5,6 +5,7 @@
|
||||
#include "twn_types.h"
|
||||
#include "twn_util.h"
|
||||
#include "twn_vec.h"
|
||||
#include "twn_vec_c.h"
|
||||
#include "twn_deferred_commands.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
@ -497,6 +498,69 @@ DrawCameraFromPrincipalAxesResult draw_camera_from_principal_axes(Vec3 position,
|
||||
}
|
||||
|
||||
|
||||
|
||||
DrawCameraUnprojectResult draw_camera_unproject(Vec2 point,
|
||||
Vec3 position,
|
||||
Vec3 direction,
|
||||
Vec3 up,
|
||||
float fov,
|
||||
float zoom,
|
||||
float draw_distance)
|
||||
{
|
||||
bool const orthographic = fabsf(0.0f - fov) < 0.00001f;
|
||||
if (!orthographic && fov >= (float)(M_PI))
|
||||
log_warn("Invalid fov given (%f)", (double)fov);
|
||||
|
||||
/* inital zoom = 1.0 correlates to perspective from this */
|
||||
zoom *= 0.1f;
|
||||
|
||||
float const aspect = (float)ctx.base_render_width / (float)ctx.base_render_height;
|
||||
Camera const camera = {
|
||||
.fov = fov,
|
||||
.pos = position,
|
||||
.target = vec3_norm(direction),
|
||||
.up = up,
|
||||
.viewbox = {
|
||||
aspect/-zoom, aspect/zoom,
|
||||
1/zoom, 1/-zoom
|
||||
},
|
||||
.far_z = draw_distance
|
||||
};
|
||||
|
||||
Matrix4 const projection_matrix = orthographic ? camera_orthographic(&camera) : camera_perspective(&camera);
|
||||
Matrix4 const look_at_matrix = camera_look_at(&camera);
|
||||
/* TODO: cache matrices for repeated camera inputs, those are expensive */
|
||||
Matrix4 const inverse_view_proj = matrix_inverse(matrix_multiply(projection_matrix, look_at_matrix));
|
||||
|
||||
point.y = (float)ctx.base_render_height - point.y;
|
||||
|
||||
if (!orthographic) {
|
||||
point = (Vec2) {
|
||||
point.x,
|
||||
point.y,
|
||||
};
|
||||
}
|
||||
|
||||
Vec4 v;
|
||||
v.x = 2.0f * point.x / (float)ctx.base_render_width - 1.0f;
|
||||
v.y = 2.0f * point.y / (float)ctx.base_render_height - 1.0f;
|
||||
v.z = 2.0f * 1.0f - 1.0f;
|
||||
v.w = 1.0f;
|
||||
|
||||
log_vec2(point, "point");
|
||||
|
||||
v = matrix_vector_multiply(inverse_view_proj, v);
|
||||
|
||||
/* TODO: is it even ever not equal to 1 in our case ? */
|
||||
v = vec4_scale(v, 1.0f / v.w);
|
||||
|
||||
return (DrawCameraUnprojectResult){
|
||||
.position = (Vec3){ v.x, v.y, v.z },
|
||||
.direction = vec3_norm(vec3_sub(position, (Vec3){ v.x, v.y, v.z })),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void set_depth_range(double low, double high) {
|
||||
depth_range_low = low;
|
||||
depth_range_high = high;
|
||||
|
Reference in New Issue
Block a user