mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-12-22 20:08:20 -06:00
raycasts, refactor
This commit is contained in:
parent
a9666062ec
commit
3b36990d32
|
@ -16,6 +16,7 @@ pub struct Inputs {
|
||||||
#[derive(Unique, Clone, Default, Debug)]
|
#[derive(Unique, Clone, Default, Debug)]
|
||||||
pub struct RawInputState {
|
pub struct RawInputState {
|
||||||
pub keyboard_state: HashSet<VirtualKeyCode, BuildNoHashHasher<u32>>,
|
pub keyboard_state: HashSet<VirtualKeyCode, BuildNoHashHasher<u32>>,
|
||||||
|
pub button_state: [bool; 32],
|
||||||
pub mouse_delta: DVec2
|
pub mouse_delta: DVec2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +38,10 @@ pub fn process_events(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DeviceEvent::Button { button: _, state: _ } => {
|
DeviceEvent::Button { button, state } => {
|
||||||
//log::debug!("Button {button} {state:?}");
|
if button < 32 {
|
||||||
|
input_state.button_state[button as usize] = matches!(state, ElementState::Pressed);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
@ -56,6 +59,8 @@ pub fn update_input_states (
|
||||||
raw_inputs.keyboard_state.contains(&VirtualKeyCode::S) as u32 as f32
|
raw_inputs.keyboard_state.contains(&VirtualKeyCode::S) as u32 as f32
|
||||||
).normalize_or_zero();
|
).normalize_or_zero();
|
||||||
inputs.look = raw_inputs.mouse_delta.as_vec2();
|
inputs.look = raw_inputs.mouse_delta.as_vec2();
|
||||||
|
inputs.action_a = raw_inputs.button_state[1];
|
||||||
|
inputs.action_b = raw_inputs.button_state[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_input (
|
pub fn init_input (
|
||||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -13,6 +13,7 @@ use glam::vec3;
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
|
|
||||||
mod logging;
|
mod logging;
|
||||||
|
|
||||||
pub(crate) mod rendering;
|
pub(crate) mod rendering;
|
||||||
pub(crate) mod world;
|
pub(crate) mod world;
|
||||||
pub(crate) mod player;
|
pub(crate) mod player;
|
||||||
|
@ -24,8 +25,17 @@ pub(crate) mod events;
|
||||||
pub(crate) mod input;
|
pub(crate) mod input;
|
||||||
pub(crate) mod fly_controller;
|
pub(crate) mod fly_controller;
|
||||||
|
|
||||||
use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background};
|
use rendering::{
|
||||||
use world::{loading::update_loaded_world_around_player, render::draw_world, init_game_world};
|
Renderer,
|
||||||
|
RenderTarget,
|
||||||
|
BackgroundColor,
|
||||||
|
clear_background
|
||||||
|
};
|
||||||
|
use world::{
|
||||||
|
init_game_world,
|
||||||
|
loading::update_loaded_world_around_player,
|
||||||
|
raycast::update_player_raycast
|
||||||
|
};
|
||||||
use player::spawn_player;
|
use player::spawn_player;
|
||||||
use prefabs::load_prefabs;
|
use prefabs::load_prefabs;
|
||||||
use settings::GameSettings;
|
use settings::GameSettings;
|
||||||
|
@ -33,6 +43,10 @@ use camera::compute_cameras;
|
||||||
use events::{clear_events, process_glutin_events};
|
use events::{clear_events, process_glutin_events};
|
||||||
use input::{init_input, process_inputs};
|
use input::{init_input, process_inputs};
|
||||||
use fly_controller::update_controllers;
|
use fly_controller::update_controllers;
|
||||||
|
use rendering::{
|
||||||
|
selection_box::render_selection_box,
|
||||||
|
world::draw_world,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
pub(crate) struct DeltaTime(Duration);
|
pub(crate) struct DeltaTime(Duration);
|
||||||
|
@ -50,6 +64,7 @@ fn update() -> Workload {
|
||||||
process_inputs,
|
process_inputs,
|
||||||
update_controllers,
|
update_controllers,
|
||||||
update_loaded_world_around_player,
|
update_loaded_world_around_player,
|
||||||
|
update_player_raycast,
|
||||||
compute_cameras
|
compute_cameras
|
||||||
).into_workload()
|
).into_workload()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
use glam::Mat4;
|
use glam::Mat4;
|
||||||
use shipyard::{Component, EntitiesViewMut, ViewMut};
|
use shipyard::{Component, AllStoragesViewMut};
|
||||||
use crate::{
|
use crate::{
|
||||||
transform::Transform,
|
transform::Transform,
|
||||||
camera::Camera,
|
camera::Camera,
|
||||||
fly_controller::FlyController,
|
fly_controller::FlyController,
|
||||||
|
world::raycast::LookingAtBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct LocalPlayer;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Player;
|
pub struct Player;
|
||||||
|
|
||||||
|
@ -16,31 +14,15 @@ pub struct Player;
|
||||||
pub struct MainPlayer;
|
pub struct MainPlayer;
|
||||||
|
|
||||||
pub fn spawn_player (
|
pub fn spawn_player (
|
||||||
mut entities: EntitiesViewMut,
|
mut storages: AllStoragesViewMut
|
||||||
mut vm_player: ViewMut<Player>,
|
|
||||||
mut vm_main_player: ViewMut<MainPlayer>,
|
|
||||||
mut vm_local_player: ViewMut<LocalPlayer>,
|
|
||||||
mut vm_transform: ViewMut<Transform>,
|
|
||||||
mut vm_camera: ViewMut<Camera>,
|
|
||||||
mut vm_controls: ViewMut<FlyController>,
|
|
||||||
) {
|
) {
|
||||||
log::info!("spawning player");
|
log::info!("spawning player");
|
||||||
entities.add_entity(
|
storages.add_entity((
|
||||||
(
|
|
||||||
&mut vm_player,
|
|
||||||
&mut vm_main_player,
|
|
||||||
&mut vm_local_player,
|
|
||||||
&mut vm_transform,
|
|
||||||
&mut vm_camera,
|
|
||||||
&mut vm_controls
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Player,
|
Player,
|
||||||
MainPlayer,
|
MainPlayer,
|
||||||
LocalPlayer,
|
Transform::default(),
|
||||||
Transform(Mat4::default()),
|
|
||||||
Camera::default(),
|
Camera::default(),
|
||||||
FlyController
|
FlyController,
|
||||||
)
|
LookingAtBlock::default(),
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@ use glium::{
|
||||||
};
|
};
|
||||||
use glam::Vec3;
|
use glam::Vec3;
|
||||||
|
|
||||||
|
pub mod world;
|
||||||
|
pub mod selection_box;
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
pub struct RenderTarget(pub glium::Frame);
|
pub struct RenderTarget(pub glium::Frame);
|
||||||
|
|
||||||
|
|
18
src/rendering/selection_box.rs
Normal file
18
src/rendering/selection_box.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
use shipyard::{View, IntoIter, NonSendSync, UniqueViewMut};
|
||||||
|
use crate::{
|
||||||
|
player::MainPlayer,
|
||||||
|
world::raycast::LookingAtBlock,
|
||||||
|
camera::Camera
|
||||||
|
};
|
||||||
|
use super::RenderTarget;
|
||||||
|
|
||||||
|
//wip
|
||||||
|
pub fn render_selection_box(
|
||||||
|
lookat: View<LookingAtBlock>,
|
||||||
|
camera: View<Camera>,
|
||||||
|
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||||
|
) {
|
||||||
|
for lookat in lookat.iter() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,6 @@ use glium::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
camera::Camera,
|
camera::Camera,
|
||||||
rendering::RenderTarget,
|
|
||||||
prefabs::{
|
prefabs::{
|
||||||
ChunkShaderPrefab,
|
ChunkShaderPrefab,
|
||||||
BlockTexturesPrefab,
|
BlockTexturesPrefab,
|
||||||
|
@ -30,6 +29,7 @@ use crate::{
|
||||||
chunk::CHUNK_SIZE,
|
chunk::CHUNK_SIZE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use super::RenderTarget;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct ChunkVertex {
|
pub struct ChunkVertex {
|
28
src/world.rs
28
src/world.rs
|
@ -6,16 +6,18 @@ use anyhow::{Result, Context};
|
||||||
|
|
||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod render;
|
|
||||||
pub mod tasks;
|
pub mod tasks;
|
||||||
pub mod loading;
|
pub mod loading;
|
||||||
pub mod mesh;
|
pub mod mesh;
|
||||||
pub mod neighbors;
|
pub mod neighbors;
|
||||||
pub mod worldgen;
|
pub mod worldgen;
|
||||||
|
pub mod raycast;
|
||||||
|
|
||||||
use chunk::{Chunk, ChunkMesh};
|
use chunk::{Chunk, ChunkMesh};
|
||||||
use tasks::ChunkTaskManager;
|
use tasks::ChunkTaskManager;
|
||||||
|
|
||||||
|
use self::{chunk::CHUNK_SIZE, block::Block};
|
||||||
|
|
||||||
//TODO separate world struct for render data
|
//TODO separate world struct for render data
|
||||||
// because this is not send-sync
|
// because this is not send-sync
|
||||||
|
|
||||||
|
@ -25,6 +27,30 @@ pub struct ChunkStorage {
|
||||||
pub chunks: HashMap<IVec3, Chunk>
|
pub chunks: HashMap<IVec3, Chunk>
|
||||||
}
|
}
|
||||||
impl ChunkStorage {
|
impl ChunkStorage {
|
||||||
|
pub const fn to_chunk_coords(position: IVec3) -> (IVec3, IVec3) {
|
||||||
|
(
|
||||||
|
IVec3::new(
|
||||||
|
position.x.div_euclid(CHUNK_SIZE as i32),
|
||||||
|
position.y.div_euclid(CHUNK_SIZE as i32),
|
||||||
|
position.z.div_euclid(CHUNK_SIZE as i32),
|
||||||
|
),
|
||||||
|
IVec3::new(
|
||||||
|
position.x.rem_euclid(CHUNK_SIZE as i32),
|
||||||
|
position.y.rem_euclid(CHUNK_SIZE as i32),
|
||||||
|
position.z.rem_euclid(CHUNK_SIZE as i32),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn get_block(&self, position: IVec3) -> Option<Block> {
|
||||||
|
let (chunk, block) = Self::to_chunk_coords(position);
|
||||||
|
let block = self.chunks
|
||||||
|
.get(&chunk)?
|
||||||
|
.block_data.as_ref()?
|
||||||
|
.blocks.get(block.x as usize)?
|
||||||
|
.get(block.y as usize)?
|
||||||
|
.get(block.z as usize)?;
|
||||||
|
Some(*block)
|
||||||
|
}
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use glam::IVec3;
|
use glam::IVec3;
|
||||||
use glium::{VertexBuffer, IndexBuffer};
|
use glium::{VertexBuffer, IndexBuffer};
|
||||||
use super::{block::Block, render::ChunkVertex};
|
use super::block::Block;
|
||||||
|
use crate::rendering::world::ChunkVertex;
|
||||||
|
|
||||||
pub const CHUNK_SIZE: usize = 32;
|
pub const CHUNK_SIZE: usize = 32;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use glam::{IVec3, ivec3};
|
||||||
use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType};
|
use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType};
|
||||||
use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload, NonSendSync};
|
use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload, NonSendSync};
|
||||||
use crate::{
|
use crate::{
|
||||||
player::LocalPlayer,
|
player::MainPlayer,
|
||||||
transform::Transform,
|
transform::Transform,
|
||||||
settings::GameSettings,
|
settings::GameSettings,
|
||||||
rendering::Renderer
|
rendering::Renderer
|
||||||
|
@ -27,7 +27,7 @@ pub fn update_loaded_world_around_player() -> Workload {
|
||||||
|
|
||||||
pub fn update_chunks_if_player_moved(
|
pub fn update_chunks_if_player_moved(
|
||||||
v_settings: UniqueView<GameSettings>,
|
v_settings: UniqueView<GameSettings>,
|
||||||
v_local_player: View<LocalPlayer>,
|
v_local_player: View<MainPlayer>,
|
||||||
v_transform: View<Transform>,
|
v_transform: View<Transform>,
|
||||||
mut vm_world: UniqueViewMut<ChunkStorage>,
|
mut vm_world: UniqueViewMut<ChunkStorage>,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use strum::{EnumIter, IntoEnumIterator};
|
use strum::{EnumIter, IntoEnumIterator};
|
||||||
use glam::{Vec3A, vec3a, IVec3, ivec3};
|
use glam::{Vec3A, vec3a, IVec3, ivec3};
|
||||||
use super::{render::ChunkVertex, chunk::CHUNK_SIZE, block::{Block, RenderType}};
|
use super::{chunk::CHUNK_SIZE, block::{Block, RenderType}};
|
||||||
|
use crate::rendering::world::ChunkVertex;
|
||||||
|
|
||||||
pub mod data;
|
pub mod data;
|
||||||
use data::MeshGenData;
|
use data::MeshGenData;
|
||||||
|
|
55
src/world/raycast.rs
Normal file
55
src/world/raycast.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
use glam::{Vec3, IVec3};
|
||||||
|
use shipyard::{View, Component, ViewMut, IntoIter, UniqueView};
|
||||||
|
use crate::{player::MainPlayer, transform::Transform};
|
||||||
|
|
||||||
|
use super::{ChunkStorage, block::Block};
|
||||||
|
|
||||||
|
const RAYCAST_STEP: f32 = 0.25;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct RaycastReport {
|
||||||
|
pub length: f32,
|
||||||
|
pub position: Vec3,
|
||||||
|
pub block_position: IVec3,
|
||||||
|
pub block: Block,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChunkStorage {
|
||||||
|
//this is probably pretty slow...
|
||||||
|
pub fn raycast(&self, origin: Vec3, direction: Vec3, limit: Option<f32>) -> Option<RaycastReport> {
|
||||||
|
debug_assert!(direction.is_normalized(), "Ray direction not normalized");
|
||||||
|
let mut position = origin;
|
||||||
|
let mut length = 0.;
|
||||||
|
loop {
|
||||||
|
let block_position = position.floor().as_ivec3();
|
||||||
|
if let Some(block) = self.get_block(block_position) {
|
||||||
|
if block.descriptor().raycast_collision {
|
||||||
|
return Some(RaycastReport { length, position, block_position, block });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
length += RAYCAST_STEP;
|
||||||
|
position += direction * RAYCAST_STEP;
|
||||||
|
if let Some(limit) = limit {
|
||||||
|
if length > limit {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Clone, Copy, Debug, Default)]
|
||||||
|
pub struct LookingAtBlock(pub Option<RaycastReport>);
|
||||||
|
|
||||||
|
pub fn update_player_raycast(
|
||||||
|
main_player: View<MainPlayer>,
|
||||||
|
transform: View<Transform>,
|
||||||
|
mut raycast: ViewMut<LookingAtBlock>,
|
||||||
|
world: UniqueView<ChunkStorage>,
|
||||||
|
) {
|
||||||
|
for (_, transform, report) in (&main_player, transform.inserted_or_modified(), &mut raycast).iter() {
|
||||||
|
let (_, rotation, position) = transform.0.to_scale_rotation_translation();
|
||||||
|
let direction = rotation * Vec3::NEG_Z;
|
||||||
|
*report = LookingAtBlock(world.raycast(position, direction, Some(10.)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,10 +4,10 @@ use shipyard::Unique;
|
||||||
use rayon::{ThreadPool, ThreadPoolBuilder};
|
use rayon::{ThreadPool, ThreadPoolBuilder};
|
||||||
use super::{
|
use super::{
|
||||||
chunk::BlockData,
|
chunk::BlockData,
|
||||||
render::ChunkVertex,
|
|
||||||
mesh::{generate_mesh, data::MeshGenData},
|
mesh::{generate_mesh, data::MeshGenData},
|
||||||
worldgen::generate_world,
|
worldgen::generate_world,
|
||||||
};
|
};
|
||||||
|
use crate::rendering::world::ChunkVertex;
|
||||||
|
|
||||||
pub enum ChunkTask {
|
pub enum ChunkTask {
|
||||||
LoadChunk {
|
LoadChunk {
|
||||||
|
|
Loading…
Reference in a new issue