From c96625b8eb81ed49e14ba2b8cf958e7bc8ebb034 Mon Sep 17 00:00:00 2001 From: hheik <4469778+hheik@users.noreply.github.com> Date: Fri, 15 Dec 2023 17:18:02 +0200 Subject: [PATCH] Added software shadows --- src/game/darkness.rs | 30 +++++++++++++++++------------- src/util.rs | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/game/darkness.rs b/src/game/darkness.rs index 4147a04..4342144 100644 --- a/src/game/darkness.rs +++ b/src/game/darkness.rs @@ -11,7 +11,7 @@ use bevy_ecs_ldtk::{LdtkLevel, LevelEvent}; use bevy_prototype_debug_lines::DebugLines; use bevy_rapier2d::prelude::{Collider, QueryFilter, RapierContext}; -use crate::debug::DebugMode; +use crate::{debug::DebugMode, util::vec2_intersection}; mod material; @@ -349,6 +349,9 @@ fn calculate_shadow_map( for x in 0..SHADOWMAP_RESOLUTION { let angle = (x as f32 / SHADOWMAP_RESOLUTION as f32) * 2.0 * std::f32::consts::PI - std::f32::consts::PI; + while angle >= vertices[next_index % vertices.len()].angle && next_index < vertices.len() { + next_index += 1; + } let prev_vertex = if next_index == 0 { vertices[vertices.len() - 1] @@ -356,19 +359,20 @@ fn calculate_shadow_map( vertices[(next_index - 1) % vertices.len()] }; let next_vertex = vertices[next_index % vertices.len()]; - if angle >= next_vertex.angle && next_index < vertices.len() { - next_index += 1; - } - let mut relative_angle = angle - prev_vertex.angle; - // Technically not correct, but works - if relative_angle < 0.0 { - relative_angle = - (std::f32::consts::PI - prev_vertex.angle) + (angle + std::f32::consts::PI); - } - - // TODO: Calculate between-points - let distance = (next_vertex.point - global_position).length(); + let distance = match vec2_intersection( + global_position, + global_position + + Vec2 { + x: angle.cos(), + y: angle.sin(), + }, + prev_vertex.point, + next_vertex.point, + ) { + Some(point) => global_position.distance(point), + None => global_position.distance(prev_vertex.point), + }; shadow_map[x] = distance; } shadow_map diff --git a/src/util.rs b/src/util.rs index 3f52d4c..9c6704a 100644 --- a/src/util.rs +++ b/src/util.rs @@ -124,6 +124,23 @@ pub fn move_towards_vec3(from: Vec3, to: Vec3, amount: f32) -> Vec3 { from + diff.normalize() * length.min(amount) } +/// Get the intersection point (if any) of 2d lines a and b. +/// Lines are defined by 2 points on the line +pub fn vec2_intersection(a1: Vec2, a2: Vec2, b1: Vec2, b2: Vec2) -> Option { + let a_dir = a2 - a1; + let b_dir = b2 - b1; + let determinant = a_dir.perp_dot(b_dir); + if determinant.abs() <= f32::EPSILON { + return None; + } + Some( + Vec2 { + x: a_dir.x * (b1.x * b2.y - b1.y * b2.x) - (a1.x * a2.y - a1.y * a2.x) * b_dir.x, + y: (a1.x * a2.y - a1.y * a2.x) * -b_dir.y + a_dir.y * (b1.x * b2.y - b1.y * b2.x), + } / determinant, + ) +} + pub fn loop_value(from: f32, to: f32, value: f32) -> f32 { let range = to - from; if !range.is_normal() {