rendering, physics, player and camera WIP

This commit is contained in:
Jonas H
2026-01-01 19:54:00 +01:00
commit 5d2eca0393
51 changed files with 8734 additions and 0 deletions

87
src/picking.rs Normal file
View File

@@ -0,0 +1,87 @@
use crate::camera::Camera;
use crate::mesh::Mesh;
use glam::{Mat4, Vec3, Vec4};
pub struct Ray
{
pub origin: Vec3,
pub direction: Vec3,
}
impl Ray
{
pub fn from_screen_position(
screen_x: f32,
screen_y: f32,
screen_width: u32,
screen_height: u32,
camera: &Camera,
) -> Self
{
let ndc_x = (2.0 * screen_x) / screen_width as f32 - 1.0;
let ndc_y = 1.0 - (2.0 * screen_y) / screen_height as f32;
let clip_coords = Vec4::new(ndc_x, ndc_y, -1.0, 1.0);
let view_matrix = camera.view_matrix();
let projection_matrix = camera.projection_matrix();
let inv_projection = projection_matrix.inverse();
let inv_view = view_matrix.inverse();
let eye_coords = inv_projection * clip_coords;
let eye_coords = Vec4::new(eye_coords.x, eye_coords.y, -1.0, 0.0);
let world_coords = inv_view * eye_coords;
let direction = Vec3::new(world_coords.x, world_coords.y, world_coords.z).normalize();
Ray {
origin: camera.position,
direction,
}
}
pub fn intersects_mesh(&self, mesh: &Mesh, transform: &Mat4) -> Option<f32>
{
let inv_transform = transform.inverse();
let local_origin = inv_transform.transform_point3(self.origin);
let local_direction = inv_transform.transform_vector3(self.direction).normalize();
let mut closest_distance = f32::MAX;
let mut hit = false;
for triangle_idx in (0..mesh.num_indices).step_by(3)
{
let distance =
self.intersects_triangle_local(local_origin, local_direction, mesh, triangle_idx);
if let Some(d) = distance
{
if d < closest_distance
{
closest_distance = d;
hit = true;
}
}
}
if hit
{
Some(closest_distance)
}
else
{
None
}
}
fn intersects_triangle_local(
&self,
local_origin: Vec3,
local_direction: Vec3,
_mesh: &Mesh,
_triangle_idx: u32,
) -> Option<f32>
{
None
}
}