mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-12-22 11:58:21 -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)]
|
||||
pub struct RawInputState {
|
||||
pub keyboard_state: HashSet<VirtualKeyCode, BuildNoHashHasher<u32>>,
|
||||
pub button_state: [bool; 32],
|
||||
pub mouse_delta: DVec2
|
||||
}
|
||||
|
||||
|
@ -37,8 +38,10 @@ pub fn process_events(
|
|||
};
|
||||
}
|
||||
},
|
||||
DeviceEvent::Button { button: _, state: _ } => {
|
||||
//log::debug!("Button {button} {state:?}");
|
||||
DeviceEvent::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
|
||||
).normalize_or_zero();
|
||||
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 (
|
||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -13,6 +13,7 @@ use glam::vec3;
|
|||
use std::time::{Instant, Duration};
|
||||
|
||||
mod logging;
|
||||
|
||||
pub(crate) mod rendering;
|
||||
pub(crate) mod world;
|
||||
pub(crate) mod player;
|
||||
|
@ -24,8 +25,17 @@ pub(crate) mod events;
|
|||
pub(crate) mod input;
|
||||
pub(crate) mod fly_controller;
|
||||
|
||||
use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background};
|
||||
use world::{loading::update_loaded_world_around_player, render::draw_world, init_game_world};
|
||||
use rendering::{
|
||||
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 prefabs::load_prefabs;
|
||||
use settings::GameSettings;
|
||||
|
@ -33,6 +43,10 @@ use camera::compute_cameras;
|
|||
use events::{clear_events, process_glutin_events};
|
||||
use input::{init_input, process_inputs};
|
||||
use fly_controller::update_controllers;
|
||||
use rendering::{
|
||||
selection_box::render_selection_box,
|
||||
world::draw_world,
|
||||
};
|
||||
|
||||
#[derive(Unique)]
|
||||
pub(crate) struct DeltaTime(Duration);
|
||||
|
@ -50,6 +64,7 @@ fn update() -> Workload {
|
|||
process_inputs,
|
||||
update_controllers,
|
||||
update_loaded_world_around_player,
|
||||
update_player_raycast,
|
||||
compute_cameras
|
||||
).into_workload()
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
use glam::Mat4;
|
||||
use shipyard::{Component, EntitiesViewMut, ViewMut};
|
||||
use shipyard::{Component, AllStoragesViewMut};
|
||||
use crate::{
|
||||
transform::Transform,
|
||||
camera::Camera,
|
||||
fly_controller::FlyController,
|
||||
fly_controller::FlyController,
|
||||
world::raycast::LookingAtBlock,
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct LocalPlayer;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Player;
|
||||
|
||||
|
@ -16,31 +14,15 @@ pub struct Player;
|
|||
pub struct MainPlayer;
|
||||
|
||||
pub fn spawn_player (
|
||||
mut entities: EntitiesViewMut,
|
||||
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>,
|
||||
mut storages: AllStoragesViewMut
|
||||
) {
|
||||
log::info!("spawning player");
|
||||
entities.add_entity(
|
||||
(
|
||||
&mut vm_player,
|
||||
&mut vm_main_player,
|
||||
&mut vm_local_player,
|
||||
&mut vm_transform,
|
||||
&mut vm_camera,
|
||||
&mut vm_controls
|
||||
),
|
||||
(
|
||||
Player,
|
||||
MainPlayer,
|
||||
LocalPlayer,
|
||||
Transform(Mat4::default()),
|
||||
Camera::default(),
|
||||
FlyController
|
||||
)
|
||||
);
|
||||
storages.add_entity((
|
||||
Player,
|
||||
MainPlayer,
|
||||
Transform::default(),
|
||||
Camera::default(),
|
||||
FlyController,
|
||||
LookingAtBlock::default(),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ use glium::{
|
|||
};
|
||||
use glam::Vec3;
|
||||
|
||||
pub mod world;
|
||||
pub mod selection_box;
|
||||
|
||||
#[derive(Unique)]
|
||||
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::{
|
||||
camera::Camera,
|
||||
rendering::RenderTarget,
|
||||
prefabs::{
|
||||
ChunkShaderPrefab,
|
||||
BlockTexturesPrefab,
|
||||
|
@ -30,6 +29,7 @@ use crate::{
|
|||
chunk::CHUNK_SIZE,
|
||||
},
|
||||
};
|
||||
use super::RenderTarget;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ChunkVertex {
|
28
src/world.rs
28
src/world.rs
|
@ -6,16 +6,18 @@ use anyhow::{Result, Context};
|
|||
|
||||
pub mod chunk;
|
||||
pub mod block;
|
||||
pub mod render;
|
||||
pub mod tasks;
|
||||
pub mod loading;
|
||||
pub mod mesh;
|
||||
pub mod neighbors;
|
||||
pub mod worldgen;
|
||||
pub mod raycast;
|
||||
|
||||
use chunk::{Chunk, ChunkMesh};
|
||||
use tasks::ChunkTaskManager;
|
||||
|
||||
use self::{chunk::CHUNK_SIZE, block::Block};
|
||||
|
||||
//TODO separate world struct for render data
|
||||
// because this is not send-sync
|
||||
|
||||
|
@ -25,6 +27,30 @@ pub struct ChunkStorage {
|
|||
pub chunks: HashMap<IVec3, Chunk>
|
||||
}
|
||||
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 {
|
||||
Self::default()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use glam::IVec3;
|
||||
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;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use glam::{IVec3, ivec3};
|
|||
use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType};
|
||||
use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload, NonSendSync};
|
||||
use crate::{
|
||||
player::LocalPlayer,
|
||||
player::MainPlayer,
|
||||
transform::Transform,
|
||||
settings::GameSettings,
|
||||
rendering::Renderer
|
||||
|
@ -27,7 +27,7 @@ pub fn update_loaded_world_around_player() -> Workload {
|
|||
|
||||
pub fn update_chunks_if_player_moved(
|
||||
v_settings: UniqueView<GameSettings>,
|
||||
v_local_player: View<LocalPlayer>,
|
||||
v_local_player: View<MainPlayer>,
|
||||
v_transform: View<Transform>,
|
||||
mut vm_world: UniqueViewMut<ChunkStorage>,
|
||||
) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use strum::{EnumIter, IntoEnumIterator};
|
||||
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;
|
||||
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 super::{
|
||||
chunk::BlockData,
|
||||
render::ChunkVertex,
|
||||
mesh::{generate_mesh, data::MeshGenData},
|
||||
worldgen::generate_world,
|
||||
};
|
||||
use crate::rendering::world::ChunkVertex;
|
||||
|
||||
pub enum ChunkTask {
|
||||
LoadChunk {
|
||||
|
|
Loading…
Reference in a new issue