Make light effect entities
This commit is contained in:
parent
027134f4c6
commit
3e8de93759
|
@ -22,6 +22,8 @@ pub fn add_systems(m: &mut ecs::Manager) {
|
|||
m.add_render_system(sys);
|
||||
let sys = systems::LerpRotation::new(m);
|
||||
m.add_render_system(sys);
|
||||
let sys = systems::LightEntity::new(m);
|
||||
m.add_render_system(sys);
|
||||
|
||||
block_entity::add_systems(m);
|
||||
}
|
||||
|
@ -156,3 +158,17 @@ impl GameInfo {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Light {
|
||||
pub block_light: f32,
|
||||
pub sky_light: f32,
|
||||
}
|
||||
|
||||
impl Light {
|
||||
pub fn new() -> Light {
|
||||
Light {
|
||||
block_light: 0.0,
|
||||
sky_light: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use super::{
|
|||
Gravity,
|
||||
Bounds,
|
||||
GameInfo,
|
||||
Light
|
||||
};
|
||||
use world;
|
||||
use render;
|
||||
|
@ -45,6 +46,7 @@ pub fn create_local(m: &mut ecs::Manager) -> ecs::Entity {
|
|||
Point3::new(0.3, 1.8, 0.3)
|
||||
)));
|
||||
m.add_component_direct(entity, PlayerModel::new("", false, false, true));
|
||||
m.add_component_direct(entity, Light::new());
|
||||
entity
|
||||
}
|
||||
|
||||
|
@ -60,6 +62,7 @@ pub fn create_remote(m: &mut ecs::Manager, name: &str) -> ecs::Entity {
|
|||
Point3::new(0.3, 1.8, 0.3)
|
||||
)));
|
||||
m.add_component_direct(entity, PlayerModel::new(name, true, true, false));
|
||||
m.add_component_direct(entity, Light::new());
|
||||
entity
|
||||
}
|
||||
|
||||
|
@ -113,6 +116,7 @@ struct PlayerRenderer {
|
|||
position: ecs::Key<Position>,
|
||||
rotation: ecs::Key<Rotation>,
|
||||
game_info: ecs::Key<GameInfo>,
|
||||
light: ecs::Key<Light>,
|
||||
}
|
||||
|
||||
impl PlayerRenderer {
|
||||
|
@ -120,15 +124,18 @@ impl PlayerRenderer {
|
|||
let player_model = m.get_key();
|
||||
let position = m.get_key();
|
||||
let rotation = m.get_key();
|
||||
let light = m.get_key();
|
||||
PlayerRenderer {
|
||||
filter: ecs::Filter::new()
|
||||
.with(player_model)
|
||||
.with(position)
|
||||
.with(rotation),
|
||||
.with(rotation)
|
||||
.with(light),
|
||||
player_model: player_model,
|
||||
position: position,
|
||||
rotation: rotation,
|
||||
game_info: m.get_key(),
|
||||
light: light,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,6 +167,7 @@ impl ecs::System for PlayerRenderer {
|
|||
let player_model = m.get_component_mut(e, self.player_model).unwrap();
|
||||
let position = m.get_component_mut(e, self.position).unwrap();
|
||||
let rotation = m.get_component_mut(e, self.rotation).unwrap();
|
||||
let light = m.get_component(e, self.light).unwrap();
|
||||
|
||||
if player_model.dirty {
|
||||
self.entity_removed(m, e, world, renderer);
|
||||
|
@ -168,6 +176,10 @@ impl ecs::System for PlayerRenderer {
|
|||
|
||||
if let Some(pmodel) = player_model.model {
|
||||
let mdl = renderer.model.get_model(pmodel).unwrap();
|
||||
|
||||
mdl.block_light = light.block_light;
|
||||
mdl.sky_light = light.sky_light;
|
||||
|
||||
let offset = if player_model.first_person {
|
||||
let ox = (rotation.yaw - PI64/2.0).cos() * 0.25;
|
||||
let oz = -(rotation.yaw - PI64/2.0).sin() * 0.25;
|
||||
|
|
|
@ -3,6 +3,7 @@ use super::*;
|
|||
use ecs;
|
||||
use world;
|
||||
use render;
|
||||
use shared::Position as BPos;
|
||||
|
||||
pub struct ApplyVelocity {
|
||||
filter: ecs::Filter,
|
||||
|
@ -214,3 +215,80 @@ impl ecs::System for LerpRotation {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LightEntity {
|
||||
filter: ecs::Filter,
|
||||
position: ecs::Key<Position>,
|
||||
bounds: ecs::Key<Bounds>,
|
||||
light: ecs::Key<Light>
|
||||
}
|
||||
|
||||
impl LightEntity {
|
||||
pub fn new(m: &mut ecs::Manager) -> LightEntity {
|
||||
let position = m.get_key();
|
||||
let bounds = m.get_key();
|
||||
let light = m.get_key();
|
||||
LightEntity {
|
||||
filter: ecs::Filter::new()
|
||||
.with(position)
|
||||
.with(bounds)
|
||||
.with(light),
|
||||
position: position,
|
||||
bounds: bounds,
|
||||
light: light,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ecs::System for LightEntity {
|
||||
|
||||
fn filter(&self) -> &ecs::Filter {
|
||||
&self.filter
|
||||
}
|
||||
|
||||
fn update(&mut self, m: &mut ecs::Manager, world: &mut world::World, _: &mut render::Renderer) {
|
||||
use cgmath::EuclideanVector;
|
||||
for e in m.find(&self.filter) {
|
||||
let pos = m.get_component(e, self.position).unwrap();
|
||||
let bounds = m.get_component(e, self.bounds).unwrap();
|
||||
let light = m.get_component_mut(e, self.light).unwrap();
|
||||
let mut count = 0.0;
|
||||
let mut block_light = 0.0;
|
||||
let mut sky_light = 0.0;
|
||||
|
||||
let min_x = (pos.position.x + bounds.bounds.min.x).floor() as i32;
|
||||
let min_y = (pos.position.y + bounds.bounds.min.y).floor() as i32;
|
||||
let min_z = (pos.position.z + bounds.bounds.min.z).floor() as i32;
|
||||
let max_x = (pos.position.x + bounds.bounds.max.x).ceil() as i32 + 1;
|
||||
let max_y = (pos.position.y + bounds.bounds.max.y).ceil() as i32 + 1;
|
||||
let max_z = (pos.position.z + bounds.bounds.max.z).ceil() as i32 + 1;
|
||||
|
||||
let length = (bounds.bounds.max - bounds.bounds.min).length() as f32;
|
||||
|
||||
for y in min_y .. max_y {
|
||||
for z in min_z .. max_z {
|
||||
for x in min_x .. max_x {
|
||||
let dist = length - (
|
||||
((x as f32 + 0.5) - pos.position.x as f32).powi(2)
|
||||
+ ((y as f32 + 0.5) - pos.position.y as f32).powi(2)
|
||||
+ ((z as f32 + 0.5) - pos.position.z as f32).powi(2)
|
||||
)
|
||||
.sqrt()
|
||||
.min(length);
|
||||
let dist = dist / length;
|
||||
count += dist;
|
||||
block_light += world.get_block_light(BPos::new(x, y, z)) as f32 * dist;
|
||||
sky_light += world.get_sky_light(BPos::new(x, y, z)) as f32 * dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
if count <= 0.01 {
|
||||
light.block_light = 0.0;
|
||||
light.sky_light = 0.0;
|
||||
} else {
|
||||
light.block_light = block_light / count;
|
||||
light.sky_light = sky_light / count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue