Added sprite selection

This commit is contained in:
Joshua Barretto 2019-09-26 11:43:03 +01:00
parent a6d5b82ef5
commit bef4f11536
6 changed files with 55 additions and 39 deletions

View File

@ -10,4 +10,5 @@ uniform u_globals {
vec4 screen_res; vec4 screen_res;
uvec4 light_shadow_count; uvec4 light_shadow_count;
uvec4 medium; uvec4 medium;
ivec4 select_pos;
}; };

View File

@ -27,6 +27,8 @@ void main() {
inst_mat[2] = inst_mat2; inst_mat[2] = inst_mat2;
inst_mat[3] = inst_mat3; inst_mat[3] = inst_mat3;
vec3 sprite_pos = (inst_mat * vec4(0, 0, 0, 1)).xyz;
f_pos = (inst_mat * vec4(v_pos * SCALE, 1)).xyz; f_pos = (inst_mat * vec4(v_pos * SCALE, 1)).xyz;
// Wind waving // Wind waving
@ -40,6 +42,11 @@ void main() {
f_col = srgb_to_linear(v_col) * srgb_to_linear(inst_col); f_col = srgb_to_linear(v_col) * srgb_to_linear(inst_col);
// Select glowing
if (select_pos.w > 0 && select_pos.xyz == floor(sprite_pos)) {
f_col *= 4.0;
}
f_light = 1.0; f_light = 1.0;
gl_Position = gl_Position =

View File

@ -138,6 +138,7 @@ impl Scene {
0, 0,
0, 0,
BlockKind::Air, BlockKind::Air,
None,
)], )],
) { ) {
error!("Renderer failed to update: {:?}", err); error!("Renderer failed to update: {:?}", err);

View File

@ -30,6 +30,7 @@ gfx_defines! {
screen_res: [f32; 4] = "screen_res", screen_res: [f32; 4] = "screen_res",
light_shadow_count: [u32; 4] = "light_shadow_count", light_shadow_count: [u32; 4] = "light_shadow_count",
medium: [u32; 4] = "medium", medium: [u32; 4] = "medium",
select_pos: [i32; 4] = "select_pos",
} }
constant Light { constant Light {
@ -56,6 +57,7 @@ impl Globals {
light_count: usize, light_count: usize,
shadow_count: usize, shadow_count: usize,
medium: BlockKind, medium: BlockKind,
select_pos: Option<Vec3<i32>>,
) -> Self { ) -> Self {
Self { Self {
view_mat: arr_to_mat(view_mat.into_col_array()), view_mat: arr_to_mat(view_mat.into_col_array()),
@ -68,6 +70,10 @@ impl Globals {
screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(), screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(),
light_shadow_count: [light_count as u32, shadow_count as u32, 0, 0], light_shadow_count: [light_count as u32, shadow_count as u32, 0, 0],
medium: [if medium.is_fluid() { 1 } else { 0 }; 4], medium: [if medium.is_fluid() { 1 } else { 0 }; 4],
select_pos: select_pos
.map(|sp| Vec4::from(sp) + Vec4::unit_w())
.unwrap_or(Vec4::zero())
.into_array(),
} }
} }
} }
@ -86,6 +92,7 @@ impl Default for Globals {
0, 0,
0, 0,
BlockKind::Air, BlockKind::Air,
None,
) )
} }
} }

View File

@ -55,6 +55,7 @@ pub struct Scene {
postprocess: PostProcess, postprocess: PostProcess,
terrain: Terrain<TerrainChunk>, terrain: Terrain<TerrainChunk>,
loaded_distance: f32, loaded_distance: f32,
select_pos: Option<Vec3<i32>>,
figure_mgr: FigureMgr, figure_mgr: FigureMgr,
sound_mgr: SoundMgr, sound_mgr: SoundMgr,
@ -87,6 +88,8 @@ impl Scene {
}, },
terrain: Terrain::new(renderer), terrain: Terrain::new(renderer),
loaded_distance: 0.0, loaded_distance: 0.0,
select_pos: None,
figure_mgr: FigureMgr::new(), figure_mgr: FigureMgr::new(),
sound_mgr: SoundMgr::new(), sound_mgr: SoundMgr::new(),
} }
@ -107,6 +110,11 @@ impl Scene {
&mut self.camera &mut self.camera
} }
/// Set the block position that the player is interacting with
pub fn set_select_pos(&mut self, pos: Option<Vec3<i32>>) {
self.select_pos = pos;
}
/// Handle an incoming user input event (e.g.: cursor moved, key pressed, window closed). /// Handle an incoming user input event (e.g.: cursor moved, key pressed, window closed).
/// ///
/// If the event is handled, return true. /// If the event is handled, return true.
@ -257,6 +265,7 @@ impl Scene {
.get(cam_pos.map(|e| e.floor() as i32)) .get(cam_pos.map(|e| e.floor() as i32))
.map(|b| b.kind()) .map(|b| b.kind())
.unwrap_or(BlockKind::Air), .unwrap_or(BlockKind::Air),
self.select_pos,
)], )],
) )
.expect("Failed to update global constants"); .expect("Failed to update global constants");

View File

@ -117,6 +117,27 @@ impl PlayState for SessionState {
.compute_dependents(&self.client.borrow()); .compute_dependents(&self.client.borrow());
let cam_dir: Vec3<f32> = Vec3::from(view_mat.inverted() * -Vec4::unit_z()); let cam_dir: Vec3<f32> = Vec3::from(view_mat.inverted() * -Vec4::unit_z());
// Check to see whether we're aiming at anything
let (build_pos, select_pos) = {
let client = self.client.borrow();
let terrain = client.state().terrain();
let ray = terrain
.ray(cam_pos, cam_pos + cam_dir * 100.0)
.until(|block| block.is_tangeable())
.cast();
let dist = ray.0;
if let Ok(Some(_)) = ray.1 {
// Hit something!
(
Some((cam_pos + cam_dir * (dist - 0.001)).map(|e| e.floor() as i32)),
Some((cam_pos + cam_dir * dist).map(|e| e.floor() as i32)),
)
} else {
(None, None)
}
};
self.scene.set_select_pos(select_pos);
// Reset controller events // Reset controller events
self.controller.clear_events(); self.controller.clear_events();
@ -142,19 +163,8 @@ impl PlayState for SessionState {
.get(client.entity()) .get(client.entity())
.is_some() .is_some()
{ {
let (d, b) = { if let Some(build_pos) = build_pos {
let terrain = client.state().terrain(); client.place_block(build_pos, self.selected_block);
let ray = terrain
.ray(cam_pos, cam_pos + cam_dir * 100.0)
.until(|block| !block.is_air())
.cast();
(ray.0, if let Ok(Some(_)) = ray.1 { true } else { false })
};
if b {
let pos =
(cam_pos + cam_dir * (d - 0.01)).map(|e| e.floor() as i32);
client.place_block(pos, self.selected_block);
} }
} else { } else {
self.controller.primary = state self.controller.primary = state
@ -166,21 +176,6 @@ impl PlayState for SessionState {
let mut client = self.client.borrow_mut(); let mut client = self.client.borrow_mut();
let hit_pos = {
let terrain = client.state().terrain();
let ray = terrain
.ray(cam_pos, cam_pos + cam_dir * 100.0)
.until(|block| block.is_tangeable())
.cast();
let dist = ray.0;
if let Ok(Some(_)) = ray.1 {
// Hit something!
Some((cam_pos + cam_dir * dist).map(|e| e.floor() as i32))
} else {
None
}
};
if state if state
&& client && client
.state() .state()
@ -188,8 +183,8 @@ impl PlayState for SessionState {
.get(client.entity()) .get(client.entity())
.is_some() .is_some()
{ {
if let Some(hit_pos) = hit_pos { if let Some(select_pos) = select_pos {
client.remove_block(hit_pos); client.remove_block(select_pos);
} }
} else if client } else if client
.state() .state()
@ -200,8 +195,8 @@ impl PlayState for SessionState {
{ {
self.controller.secondary = state; self.controller.secondary = state;
} else { } else {
if let Some(hit_pos) = hit_pos { if let Some(select_pos) = select_pos {
client.collect_block(hit_pos); client.collect_block(select_pos);
} }
} }
} }
@ -214,14 +209,10 @@ impl PlayState for SessionState {
.is_some() .is_some()
{ {
if state { if state {
if let Ok(Some(block)) = client if let Some(block) = select_pos
.state() .and_then(|sp| client.state().terrain().get(sp).ok().copied())
.terrain()
.ray(cam_pos, cam_pos + cam_dir * 100.0)
.cast()
.1
{ {
self.selected_block = *block; self.selected_block = block;
} }
} }
} else { } else {