Added AABB for lights

master
hheik 2023-08-30 04:23:28 +03:00
parent 2bc44d694d
commit 4cec5f45fe
5 changed files with 107 additions and 17 deletions

View File

@ -52,7 +52,7 @@ fn fragment(
if (point_lights[i].radius <= 0.0) {
continue;
}
let radius = point_lights[i].radius + sin(t * 5.0) * 0.2;
let radius = point_lights[i].radius - (sin(t * 5.0) * 0.5 + 0.5) * 0.2;
let dist = distance(pos, point_lights[i].position);
let edge_treshold = radius * light_edge_mult - light_edge;
@ -68,7 +68,7 @@ fn fragment(
continue;
}
let spot = spot_lights[i];
let radius = spot.radius + sin(t * 5.0) * 0.2;
let radius = spot.radius - (sin(t * 5.0) * 0.5 + 0.5) * 0.2;
let diff = pos - spot.position;
let dist = length(diff);
let spot_dir = vec2<f32>(cos(spot.rotation), sin(spot.rotation));

View File

@ -1,5 +1,6 @@
use bevy::prelude::*;
use bevy_prototype_debug_lines::DebugLinesPlugin;
use crate::game::darkness::LightAabb;
pub struct DebugPlugin;
@ -11,12 +12,13 @@ impl Plugin for DebugPlugin {
app.configure_set(Last, DebugSet.run_if(is_debug_enabled));
app.insert_resource(DebugMode::off())
.add_plugins(bevy_prototype_debug_lines::DebugLinesPlugin::default())
.add_plugins((
bevy_inspector_egui::quick::WorldInspectorPlugin::new().run_if(is_debug_enabled),
bevy_rapier2d::prelude::RapierDebugRenderPlugin::default(),
))
.add_plugins(DebugLinesPlugin::default())
.add_systems(Update, debug_toggle);
.add_systems(Update, debug_toggle)
.add_systems(Last, (light_boundaries).in_set(DebugSet));
}
}
@ -45,3 +47,66 @@ fn debug_toggle(input: Res<Input<KeyCode>>, mut debug_mode: ResMut<DebugMode>) {
debug_mode.enabled = !debug_mode.enabled
}
}
fn light_boundaries(
mut debug_draw: ResMut<bevy_prototype_debug_lines::DebugLines>,
point_query: Query<(&GlobalTransform, &crate::game::darkness::PointLight2D)>,
spot_query: Query<(&GlobalTransform, &crate::game::darkness::SpotLight2D)>,
) {
for (tranform, light) in &point_query {
let rect = light.aabb();
draw_rect(
Rect::from_center_size(
rect.center() + tranform.translation().truncate(),
rect.size(),
),
0.0,
Color::RED,
&mut debug_draw,
)
}
for (tranform, light) in &spot_query {
let rect = light.aabb();
draw_rect(
Rect::from_center_size(
rect.center() + tranform.translation().truncate(),
rect.size(),
),
0.0,
Color::RED,
&mut debug_draw,
)
}
}
fn draw_rect(
rect: Rect,
duration: f32,
color: Color,
debug_draw: &mut ResMut<bevy_prototype_debug_lines::DebugLines>,
) {
debug_draw.line_colored(
Vec3::new(rect.min.x, rect.min.y, 0.0),
Vec3::new(rect.max.x, rect.min.y, 0.0),
duration,
color,
);
debug_draw.line_colored(
Vec3::new(rect.max.x, rect.min.y, 0.0),
Vec3::new(rect.max.x, rect.max.y, 0.0),
duration,
color,
);
debug_draw.line_colored(
Vec3::new(rect.max.x, rect.max.y, 0.0),
Vec3::new(rect.min.x, rect.max.y, 0.0),
duration,
color,
);
debug_draw.line_colored(
Vec3::new(rect.min.x, rect.max.y, 0.0),
Vec3::new(rect.min.x, rect.min.y, 0.0),
duration,
color,
);
}

View File

@ -2,7 +2,7 @@ use crate::{debug, game_setup};
use bevy::prelude::*;
use bevy_ecs_ldtk::{LdtkWorldBundle, LevelSelection};
use self::darkness::SpotLight2D;
use self::darkness::{PointLight2D, SpotLight2D};
pub mod camera;
pub mod darkness;
@ -36,5 +36,6 @@ fn setup(mut commands: Commands, assets: Res<AssetServer>) {
radius: 100.0,
angle: 1.0,
},
PointLight2D { radius: 20.0 },
));
}

View File

@ -19,6 +19,7 @@ impl Plugin for DarknessPlugin {
fn build(&self, app: &mut App) {
app.register_type::<PointLight2D>()
.register_type::<SpotLight2D>()
.register_type::<VisibilityBlocker>()
.register_asset_reflect::<DarknessMaterial>()
.add_plugins(Material2dPlugin::<DarknessMaterial>::default())
.add_systems(Update, add_to_level)
@ -26,12 +27,22 @@ impl Plugin for DarknessPlugin {
}
}
pub trait LightAabb {
fn aabb(&self) -> Rect;
}
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct PointLight2D {
pub radius: f32,
}
impl LightAabb for PointLight2D {
fn aabb(&self) -> Rect {
Rect::from_center_half_size(Vec2::ZERO, Vec2::splat(self.radius + 2.0))
}
}
#[derive(Copy, Clone, Debug, Default, Reflect, ShaderType)]
pub(crate) struct GpuPointLight2D {
pub(crate) position: Vec2,
@ -45,6 +56,12 @@ pub struct SpotLight2D {
pub angle: f32,
}
impl LightAabb for SpotLight2D {
fn aabb(&self) -> Rect {
Rect::from_center_half_size(Vec2::ZERO, Vec2::splat(self.radius + 2.0))
}
}
#[derive(Copy, Clone, Debug, Default, Reflect, ShaderType)]
pub(crate) struct GpuSpotLight2D {
pub(crate) position: Vec2,
@ -56,6 +73,10 @@ pub(crate) struct GpuSpotLight2D {
padding3: u32,
}
#[derive(Component, Reflect, Default, Debug, Clone, Copy)]
#[reflect(Component)]
pub struct VisibilityBlocker;
fn add_to_level(
mut commands: Commands,
mut level_events: EventReader<LevelEvent>,

View File

@ -5,6 +5,7 @@ use bevy_ecs_ldtk::prelude::*;
use bevy_rapier2d::prelude::*;
use std::collections::HashSet;
use crate::game::darkness::VisibilityBlocker;
use crate::util::Vector2I;
pub struct LdtkHelperPlugin;
@ -31,7 +32,7 @@ impl Plugin for LdtkHelperPlugin {
.add_event::<EntityInstanceAdded>()
.register_ldtk_int_cell::<WallBundle>(1)
.insert_resource(WordlyInstances::default())
.add_systems(Update, entity_instance_events)
.add_systems(Update, (wall_setup, entity_instance_events))
.add_systems(PostUpdate, (entity_namer, unique_handler));
}
}
@ -153,7 +154,7 @@ impl FieldValueGetter for EntityInstance {
/// 2. combine wall tiles into flat "plates" in each individual row
/// 3. combine the plates into rectangles across multiple rows wherever possible
/// 4. spawn colliders for each rectangle
pub fn wall_setup(
fn wall_setup(
mut commands: Commands,
wall_query: Query<(&GridCoords, &Parent), Added<Wall>>,
parent_query: Query<&Parent, Without<Wall>>,
@ -277,26 +278,28 @@ pub fn wall_setup(
// 1. Adjusts the transforms to be relative to the level for free
// 2. the colliders will be despawned automatically when levels unload
for wall_rect in wall_rects {
level
.spawn_empty()
.insert(Collider::cuboid(
level.spawn((
Collider::cuboid(
(wall_rect.right as f32 - wall_rect.left as f32 + 1.)
* grid_size as f32
/ 2.,
(wall_rect.top as f32 - wall_rect.bottom as f32 + 1.)
* grid_size as f32
/ 2.,
))
.insert(RigidBody::Fixed)
.insert(Friction::new(1.0))
.insert(Transform::from_xyz(
),
VisibilityBlocker,
RigidBody::Fixed,
Name::new("Collider"),
Friction::new(1.0),
Transform::from_xyz(
(wall_rect.left + wall_rect.right + 1) as f32 * grid_size as f32
/ 2.,
(wall_rect.bottom + wall_rect.top + 1) as f32 * grid_size as f32
/ 2.,
0.,
))
.insert(GlobalTransform::default());
),
GlobalTransform::default(),
));
}
});
}