Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Ecs rewrite #1

Merged
merged 82 commits into from
Jan 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
097bd50
start rewrite
griffi-gh Jan 19, 2023
470d1a7
switch to `shipyard`
griffi-gh Jan 19, 2023
b1b78cc
x
griffi-gh Jan 19, 2023
fcb123b
x
griffi-gh Jan 19, 2023
d77779d
got a window
griffi-gh Jan 19, 2023
e89dd07
some progress
griffi-gh Jan 19, 2023
000e1c3
prefab loader
griffi-gh Jan 20, 2023
d96e99f
world structure
griffi-gh Jan 20, 2023
706f482
Add readme
griffi-gh Jan 20, 2023
2c01480
chunk structure
griffi-gh Jan 20, 2023
a39ad3b
loader
griffi-gh Jan 20, 2023
cc08456
meow
griffi-gh Jan 20, 2023
10faee2
owo
griffi-gh Jan 20, 2023
3d7083d
some things
griffi-gh Jan 20, 2023
e3ef07d
sync
griffi-gh Jan 21, 2023
5b0817b
WIP Chunk loading
griffi-gh Jan 21, 2023
dc0c314
ї
griffi-gh Jan 21, 2023
0a528d8
"unroll" loop
griffi-gh Jan 21, 2023
c761688
chunk marking/loading!!
griffi-gh Jan 22, 2023
26b43ed
wip camera
griffi-gh Jan 22, 2023
7b5120b
chunk rendering
griffi-gh Jan 22, 2023
f9a7953
Separate chunk neighbor code, WIP tasks
griffi-gh Jan 22, 2023
5f06c85
change neighbors to a right handed system
griffi-gh Jan 22, 2023
8f1821a
add mipmaps and spcify wrap function on sampler
griffi-gh Jan 22, 2023
ee55ef2
some refactoring, worldgen tasks and more (i forgor :skull:)
griffi-gh Jan 22, 2023
38c0bfa
hacky shit but it works
griffi-gh Jan 23, 2023
d290dd8
add logging
griffi-gh Jan 23, 2023
6f866d2
got something to render...
griffi-gh Jan 23, 2023
59cdd84
Use correct culling?
griffi-gh Jan 23, 2023
cb428f4
Ooops cleared the frame twice
griffi-gh Jan 23, 2023
ff38faa
Remove useless `mut`
griffi-gh Jan 23, 2023
ecedfc9
spawn L shapes
griffi-gh Jan 23, 2023
710bede
swap face normals
griffi-gh Jan 23, 2023
92b0d89
fix warnings
griffi-gh Jan 23, 2023
68fcb71
create files
griffi-gh Jan 23, 2023
567e6d8
wip input system
griffi-gh Jan 24, 2023
9c802a6
input system updates
griffi-gh Jan 24, 2023
8615853
undo input code
griffi-gh Jan 24, 2023
83f0695
events and input
griffi-gh Jan 25, 2023
e68e0b3
testing
griffi-gh Jan 25, 2023
3d6988f
wip camera
griffi-gh Jan 25, 2023
29166c3
upd camera
griffi-gh Jan 25, 2023
56c2f0d
fuck
griffi-gh Jan 26, 2023
f3f0227
yay it works!
griffi-gh Jan 26, 2023
fc6da88
remove useless argument
griffi-gh Jan 26, 2023
dfdcc3e
change world generations, enable mi[mapping in sampler, unlink moveme…
griffi-gh Jan 26, 2023
941f563
block textures
griffi-gh Jan 26, 2023
9ed19bf
skip drawing empty chunks
griffi-gh Jan 26, 2023
5c3ee1c
testing
griffi-gh Jan 26, 2023
a512fff
Chunk state downgrades
griffi-gh Jan 26, 2023
294648b
u
griffi-gh Jan 26, 2023
a7a1b44
testing noise
griffi-gh Jan 27, 2023
90c5b2a
fix
griffi-gh Jan 27, 2023
6b8deab
control
griffi-gh Jan 27, 2023
783b6a1
wip
griffi-gh Jan 27, 2023
19fa7e6
Wip frustum code port
griffi-gh Jan 27, 2023
a29f6c6
frustum
griffi-gh Jan 27, 2023
1f1b337
frustum culling impl
griffi-gh Jan 27, 2023
5b4f54a
wip culling
griffi-gh Jan 27, 2023
fe5bafd
fix
griffi-gh Jan 27, 2023
4c2a29e
enable frustum culling!
griffi-gh Jan 27, 2023
d9ab57b
Mouse sensitivity is now affected by delta time
griffi-gh Jan 27, 2023
16bc214
reenable worldgen
griffi-gh Jan 27, 2023
158639d
update frustum only if the camera moves
griffi-gh Jan 27, 2023
a966606
refactor part of the cube frustum culling code
griffi-gh Jan 27, 2023
3b36990
raycasts, refactor
griffi-gh Jan 28, 2023
b4462a0
wip
griffi-gh Jan 28, 2023
2bb22dd
wip selection box
griffi-gh Jan 28, 2023
a4f4a76
having issues with blending...
griffi-gh Jan 28, 2023
0c25bfa
selection kinda works
griffi-gh Jan 28, 2023
407f87a
increase player range
griffi-gh Jan 28, 2023
b8bbda4
better check
griffi-gh Jan 28, 2023
f3e8459
generalize lookingat
griffi-gh Jan 28, 2023
c1cd481
block breaking!
griffi-gh Jan 28, 2023
5f9f0ad
update
griffi-gh Jan 28, 2023
1fef7e0
skip placement if both buttons are down
griffi-gh Jan 28, 2023
665b3b8
prev inputs
griffi-gh Jan 28, 2023
827ed16
fix typo
griffi-gh Jan 28, 2023
5a0e73e
block selector effect
griffi-gh Jan 28, 2023
427feec
wtf
griffi-gh Jan 28, 2023
1a948b4
fix world gen
griffi-gh Jan 28, 2023
42a8224
Merge branch 'master' into ecs-rewrite
griffi-gh Jan 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ Cargo.lock

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

#old source
_src
14 changes: 6 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ name = "kubi"
version = "0.1.0"
edition = "2021"

[profile.dev.package.noise]
opt-level = 3

[dependencies]
glium = "0.32"
image = { version = "0.24", default_features = false, features = ["png"] }
Expand All @@ -14,9 +11,10 @@ env_logger = "0.10"
strum = { version = "0.24", features = ["derive"] }
glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] }
hashbrown = "0.13"
noise = "0.8"
rayon = "1.6"
#ordered-float = "3.4"

[features]
default = []
shipyard = { version = "0.6", features = ["thread_local"] }
nohash-hasher = "0.2.0"
anyhow = "1.0"
flume = "0.10"
#once_cell = "1.17"
bracket-noise = "0.8"
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# development moved to
# https://github.com/griffi-gh/kubi/tree/ecs-rewrite
this branch contains the latest version before the rewrite
<h1 align="center">Kubi</h1>
work in progress
<h6 align="right"><i>~ uwu</i></h6>
1 change: 1 addition & 0 deletions crabs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sorry no crabs here
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ uniform vec4 u_color;

void main() {
color = u_color;
color -= vec4(0, 0, 0, 0.1 * sin(gl_FragCoord.x) * cos(gl_FragCoord.y));
}
10 changes: 10 additions & 0 deletions shaders/selection_box.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#version 150 core

in vec3 position;
uniform vec3 u_position;
uniform mat4 perspective;
uniform mat4 view;

void main() {
gl_Position = perspective * view * vec4(position + u_position, 1.);
}
File renamed without changes.
10 changes: 8 additions & 2 deletions src/game/shaders/glsl/chunk.vert → shaders/world.vert
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
#version 150 core

//TODO pack this data:
// uint position_normal_uv
// XXYYZZNU
// wehere Normal and Uv are enums
// maybe somehow pack in tex index too

in vec3 position;
in vec3 normal;
in vec2 uv;
in uint tex_index;
out vec2 v_uv;
out vec3 v_normal;
flat out uint v_tex_index;
uniform vec2 position_offset;
uniform vec3 position_offset;
uniform mat4 perspective;
uniform mat4 view;

void main() {
v_normal = normal;
v_tex_index = tex_index;
v_uv = uv;
gl_Position = perspective * view * (vec4(position, 1.0) + vec4(position_offset.x, 0., position_offset.y, 0.));
gl_Position = perspective * view * vec4(position + position_offset, 1.);
}
37 changes: 37 additions & 0 deletions src/block_placement.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use glam::Vec3;
use shipyard::{UniqueViewMut, UniqueView, View, IntoIter};
use crate::{
player::MainPlayer,
world::{raycast::LookingAtBlock, ChunkStorage, block::Block},
input::{Inputs, PrevInputs}
};

pub fn block_placement_system(
main_player: View<MainPlayer>,
raycast: View<LookingAtBlock>,
input: UniqueView<Inputs>,
prev_input: UniqueView<PrevInputs>,
mut world: UniqueViewMut<ChunkStorage>
) {
let action_place = input.action_b && !prev_input.0.action_b;
let action_break = input.action_a && !prev_input.0.action_a;
if action_place ^ action_break {
//get raycast info
let Some(ray) = (&main_player, &raycast).iter().next().unwrap().1/**/.0 else { return };
//update block
let place_position = if action_place {
let position = (ray.position - ray.direction * 0.5).floor().as_ivec3();
let Some(block) = world.get_block_mut(position) else { return };
*block = Block::Dirt;
position
} else {
let Some(block) = world.get_block_mut(ray.block_position) else { return };
*block = Block::Air;
ray.block_position
};
//mark chunk as dirty
let (chunk_pos, _) = ChunkStorage::to_chunk_coords(place_position);
let chunk = world.chunks.get_mut(&chunk_pos).unwrap();
chunk.dirty = true;
}
}
43 changes: 43 additions & 0 deletions src/camera.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use glam::{Mat4, Vec3};
use shipyard::{Component, Workload, IntoWorkload};
use std::f32::consts::PI;

mod matrices;
mod frustum;

use matrices::update_matrices;
use frustum::{Frustum, update_frustum};

#[derive(Component)]
pub struct Camera {
pub view_matrix: Mat4,
pub perspective_matrix: Mat4,
pub frustum: Frustum,
pub up: Vec3,
pub fov: f32,
pub z_near: f32,
pub z_far: f32,
}
impl Camera {
pub fn new(fov: f32, z_near: f32, z_far: f32, up: Vec3) -> Self {
Self {
fov, z_near, z_far, up,
//TODO maybe separate this?
perspective_matrix: Mat4::default(),
view_matrix: Mat4::default(),
frustum: Frustum::default(),
}
}
}
impl Default for Camera {
fn default() -> Self {
Self::new(PI / 3., 0.1, 1024., Vec3::Y)
}
}

pub fn compute_cameras() -> Workload {
(
update_matrices,
update_frustum,
).into_workload()
}
130 changes: 130 additions & 0 deletions src/camera/frustum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// basically ported from c++
// - used as a reference:
// [ https://github.com/Beastwick18/gltest/blob/main/src/renderer/Frustum.cpp ]
// - original code:
// [ https://gist.github.com/podgorskiy/e698d18879588ada9014768e3e82a644 ]
// - which uses cube vs frustum intersection code from:
// [ http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm ]
// three layers of stolen code, yay!

use glam::{Vec3A, Vec4, Mat3A, vec3a, Vec3, vec4};
use shipyard::{ViewMut, IntoIter, View};
use crate::transform::Transform;
use super::Camera;

#[repr(usize)]
enum FrustumPlane {
Left,
Right,
Bottom,
Top,
Near,
Far,
}

const PLANE_COUNT: usize = 6;
const PLANE_COMBINATIONS: usize = PLANE_COUNT * (PLANE_COUNT - 1) / 2;
const POINT_COUNT: usize = 8;

#[derive(Default)]
pub struct Frustum {
planes: [Vec4; PLANE_COUNT],
points: [Vec3A; POINT_COUNT]
}
impl Frustum {
pub fn compute(camera: &Camera) -> Self {
//compute transposed view-projection matrix
let mat = (camera.perspective_matrix * camera.view_matrix).transpose();

// compute planes
let mut planes = [Vec4::default(); PLANE_COUNT];
planes[FrustumPlane::Left as usize] = mat.w_axis + mat.x_axis;
planes[FrustumPlane::Right as usize] = mat.w_axis - mat.x_axis;
planes[FrustumPlane::Bottom as usize] = mat.w_axis + mat.y_axis;
planes[FrustumPlane::Top as usize] = mat.w_axis - mat.y_axis;
planes[FrustumPlane::Near as usize] = mat.w_axis + mat.z_axis;
planes[FrustumPlane::Far as usize] = mat.w_axis - mat.z_axis;

//compute crosses
let crosses = [
Vec3A::from(planes[FrustumPlane::Left as usize]).cross(planes[FrustumPlane::Right as usize].into()),
Vec3A::from(planes[FrustumPlane::Left as usize]).cross(planes[FrustumPlane::Bottom as usize].into()),
Vec3A::from(planes[FrustumPlane::Left as usize]).cross(planes[FrustumPlane::Top as usize].into()),
Vec3A::from(planes[FrustumPlane::Left as usize]).cross(planes[FrustumPlane::Near as usize].into()),
Vec3A::from(planes[FrustumPlane::Left as usize]).cross(planes[FrustumPlane::Far as usize].into()),
Vec3A::from(planes[FrustumPlane::Right as usize]).cross(planes[FrustumPlane::Bottom as usize].into()),
Vec3A::from(planes[FrustumPlane::Right as usize]).cross(planes[FrustumPlane::Top as usize].into()),
Vec3A::from(planes[FrustumPlane::Right as usize]).cross(planes[FrustumPlane::Near as usize].into()),
Vec3A::from(planes[FrustumPlane::Right as usize]).cross(planes[FrustumPlane::Far as usize].into()),
Vec3A::from(planes[FrustumPlane::Bottom as usize]).cross(planes[FrustumPlane::Top as usize].into()),
Vec3A::from(planes[FrustumPlane::Bottom as usize]).cross(planes[FrustumPlane::Near as usize].into()),
Vec3A::from(planes[FrustumPlane::Bottom as usize]).cross(planes[FrustumPlane::Far as usize].into()),
Vec3A::from(planes[FrustumPlane::Top as usize]).cross(planes[FrustumPlane::Near as usize].into()),
Vec3A::from(planes[FrustumPlane::Top as usize]).cross(planes[FrustumPlane::Far as usize].into()),
Vec3A::from(planes[FrustumPlane::Near as usize]).cross(planes[FrustumPlane::Far as usize].into()),
];

//compute points
let points = [
intersection::<{FrustumPlane::Left as usize}, {FrustumPlane::Bottom as usize}, {FrustumPlane::Near as usize}>(&planes, &crosses),
intersection::<{FrustumPlane::Left as usize}, {FrustumPlane::Top as usize}, {FrustumPlane::Near as usize}>(&planes, &crosses),
intersection::<{FrustumPlane::Right as usize}, {FrustumPlane::Bottom as usize}, {FrustumPlane::Near as usize}>(&planes, &crosses),
intersection::<{FrustumPlane::Right as usize}, {FrustumPlane::Top as usize}, {FrustumPlane::Near as usize}>(&planes, &crosses),
intersection::<{FrustumPlane::Left as usize}, {FrustumPlane::Bottom as usize}, {FrustumPlane::Far as usize}>(&planes, &crosses),
intersection::<{FrustumPlane::Left as usize}, {FrustumPlane::Top as usize}, {FrustumPlane::Far as usize}>(&planes, &crosses),
intersection::<{FrustumPlane::Right as usize}, {FrustumPlane::Bottom as usize}, {FrustumPlane::Far as usize}>(&planes, &crosses),
intersection::<{FrustumPlane::Right as usize}, {FrustumPlane::Top as usize}, {FrustumPlane::Far as usize}>(&planes, &crosses),
];

Self { planes, points }
}

pub fn is_box_visible(&self, minp: Vec3, maxp: Vec3) -> bool {
// check box outside/inside of frustum
for plane in self.planes {
if (plane.dot(vec4(minp.x, minp.y, minp.z, 1.)) < 0.) &&
(plane.dot(vec4(maxp.x, minp.y, minp.z, 1.)) < 0.) &&
(plane.dot(vec4(minp.x, maxp.y, minp.z, 1.)) < 0.) &&
(plane.dot(vec4(maxp.x, maxp.y, minp.z, 1.)) < 0.) &&
(plane.dot(vec4(minp.x, minp.y, maxp.z, 1.)) < 0.) &&
(plane.dot(vec4(maxp.x, minp.y, maxp.z, 1.)) < 0.) &&
(plane.dot(vec4(minp.x, maxp.y, maxp.z, 1.)) < 0.) &&
(plane.dot(vec4(maxp.x, maxp.y, maxp.z, 1.)) < 0.)
{
return false
}
}

// check frustum outside/inside box
if self.points.iter().all(|point| point.x > maxp.x) { return false }
if self.points.iter().all(|point| point.x < minp.x) { return false }
if self.points.iter().all(|point| point.y > maxp.y) { return false }
if self.points.iter().all(|point| point.y < minp.y) { return false }
if self.points.iter().all(|point| point.z > maxp.z) { return false }
if self.points.iter().all(|point| point.z < minp.z) { return false }

true
}
}

const fn ij2k<const I: usize, const J: usize>() -> usize {
I * (9 - I) / 2 + J - 1
}
fn intersection<const A: usize, const B: usize, const C: usize>(planes: &[Vec4; PLANE_COUNT], crosses: &[Vec3A; PLANE_COMBINATIONS]) -> Vec3A {
let d = Vec3A::from(planes[A]).dot(crosses[ij2k::<B, C>()]);
let res = Mat3A::from_cols(
crosses[ij2k::<B, C>()],
-crosses[ij2k::<A, C>()],
crosses[ij2k::<A, B>()],
) * vec3a(planes[A].w, planes[B].w, planes[C].w);
res * (-1. / d)
}

pub fn update_frustum(
mut cameras: ViewMut<Camera>,
transforms: View<Transform>
) {
for (camera, _) in (&mut cameras, transforms.inserted_or_modified()).iter() {
camera.frustum = Frustum::compute(camera);
}
}
42 changes: 42 additions & 0 deletions src/camera/matrices.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use glam::{Vec3, Mat4};
use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload};
use crate::{transform::Transform, events::WindowResizedEvent};
use super::Camera;

//maybe parallelize these two?

fn update_view_matrix(
mut vm_camera: ViewMut<Camera>,
v_transform: View<Transform>
) {
for (camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() {
let (_, rotation, translation) = transform.0.to_scale_rotation_translation();
let direction = rotation * Vec3::NEG_Z;
camera.view_matrix = Mat4::look_to_rh(translation, direction, camera.up);
}
}

fn update_perspective_matrix(
mut vm_camera: ViewMut<Camera>,
resize: View<WindowResizedEvent>,
) {
//TODO update on launch
let Some(&size) = resize.iter().next() else {
return
};
for camera in (&mut vm_camera).iter() {
camera.perspective_matrix = Mat4::perspective_rh_gl(
camera.fov,
size.0.x as f32 / size.0.y as f32,
camera.z_near,
camera.z_far,
)
}
}

pub fn update_matrices() -> Workload {
(
update_view_matrix,
update_perspective_matrix,
).into_workload()
}
55 changes: 55 additions & 0 deletions src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use glam::UVec2;
use shipyard::{World, Component, AllStoragesViewMut, SparseSet};
use glium::glutin::event::{Event, DeviceEvent, DeviceId, WindowEvent};

#[derive(Component, Clone, Copy, Debug, Default)]
pub struct EventComponent;

#[derive(Component, Clone, Copy, Debug, Default)]
pub struct OnBeforeExitEvent;

#[derive(Component, Clone, Debug)]
pub struct InputDeviceEvent{
pub device_id: DeviceId,
pub event: DeviceEvent
}

#[derive(Component, Clone, Copy, Debug, Default)]
pub struct WindowResizedEvent(pub UVec2);

pub fn process_glutin_events(world: &mut World, event: &Event<'_, ()>) {
#[allow(clippy::collapsible_match, clippy::single_match)]
match event {
Event::WindowEvent { window_id: _, event } => match event {
WindowEvent::Resized(size) => {
world.add_entity((
EventComponent,
WindowResizedEvent(UVec2::new(size.width as _, size.height as _))
));
},
_ => ()
},
Event::DeviceEvent { device_id, event } => {
world.add_entity((
EventComponent,
InputDeviceEvent {
device_id: *device_id,
event: event.clone()
}
));
},
Event::LoopDestroyed => {
world.add_entity((
EventComponent,
OnBeforeExitEvent
));
},
_ => (),
}
}

pub fn clear_events(
mut all_storages: AllStoragesViewMut,
) {
all_storages.delete_any::<SparseSet<EventComponent>>();
}
Loading