From 9c7138c5ed85a681d256c6fe9b9409a7918600c0 Mon Sep 17 00:00:00 2001 From: zhouzihao <1042181618@qq.com> Date: Thu, 7 Sep 2023 16:49:56 +0800 Subject: [PATCH 1/4] =?UTF-8?q?dev-=E6=B7=BB=E5=8A=A0=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E5=9C=B0=E5=BD=A2=E7=9A=84=E6=A0=91=E6=9C=A8=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- ...1\346\236\234\345\217\266\345\255\220.png" | Bin 0 -> 259 bytes ...\346\236\234\346\240\221A\351\235\242.png" | Bin 0 -> 1113 bytes ...\346\236\234\346\240\221B\351\235\242.png" | Bin 0 -> 433 bytes src/lib.rs | 4 +- src/voxel_world/biomes/basic_land.rs | 39 +++++++- src/voxel_world/biomes/mod.rs | 93 +++++++++++++++++- src/voxel_world/biomes/sdf.rs | 51 ++++++++++ src/voxel_world/map_generator.rs | 26 ++--- src/voxel_world/voxel.rs | 2 + staff.ron | 2 + volex.ron | 11 ++- 12 files changed, 210 insertions(+), 21 deletions(-) create mode 100644 "assets/textures/\350\213\271\346\236\234\345\217\266\345\255\220.png" create mode 100644 "assets/textures/\350\213\271\346\236\234\346\240\221A\351\235\242.png" create mode 100644 "assets/textures/\350\213\271\346\236\234\346\240\221B\351\235\242.png" create mode 100644 src/voxel_world/biomes/sdf.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 70fce99..bf88c94 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "./Cargo.toml", "./Cargo.toml", ".\\Cargo.toml", - ".\\Cargo.toml" + ".\\Cargo.toml", + "./Cargo.toml" ] } \ No newline at end of file diff --git "a/assets/textures/\350\213\271\346\236\234\345\217\266\345\255\220.png" "b/assets/textures/\350\213\271\346\236\234\345\217\266\345\255\220.png" new file mode 100644 index 0000000000000000000000000000000000000000..f9d6eaa08a6320cce0edb7ec93d79b097ff10b0a GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=r#xL8Ln`LHoxPEl$&u#(-w`Dd zj<96zZ3(6`*jO$ZGi?*uz3ZKfc5d17+aI^GZJuxQr~UA^9Wm$EoSa{IXa0TuzVoBw$OrWnAJYD@<);T3K F0RRd|PqP33 literal 0 HcmV?d00001 diff --git "a/assets/textures/\350\213\271\346\236\234\346\240\221A\351\235\242.png" "b/assets/textures/\350\213\271\346\236\234\346\240\221A\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..75baa010b7af77bfea76f91476e5de596afa36d4 GIT binary patch literal 1113 zcmV-f1g86mP)hm_o8=X9rQkL53d*hN8tB^ z7sLlE!19&G%7*h#4(y2ho_Ws#^%G?r9RUFUSzJY>&K)?Sj&qgvppD3tz&>R(`c4C= zvz<}l8o~cRix}Bv*?H^x0fVrJUhN(WlQ^9NqJ4ur4^y(%ua8NuF)LCFR zDx|HbJC*hP#EpPeXVO81Y$T1>H?@d*%1E&5ORU_1=eRE?z|y?4mdPaoJTu{07{b*{ zWUqeut*rr-3{v*Jti!7iOMb@Es1gBM#gjn^N7X57X)`e7a353FfKG=k_M=XAO~}g` zQ2R+ULIS#R!K4%8qp8WY>dLe|Bw#Z8B4Ld%j?z=k0us}W?5I4IiOh+9mu-F^pgQ8R z(Yzs+3VME|<6|lglls?6idGx9(|kNc%V$0?hxcL?nQbl$S8b3yXaII%BBez#EO`-G zD{+7q1IXv6uLYt61^>OPkrmT3Q(_s9Y*j={*GdPfi=s$FvJUvRHyCyJtc8t6>dLNj zgl&;v7E?(MA}K2a-^0I<02F*inoPs)nE|!!>GuY?tyc)~d_=e}Fo9h`(5hTHMZTF3 z%5jFXtT;q@#z|_1s{vQ%{8s|9Xm{(D63g0EXJNxDw2;-l%yu0#k}PQ-U^TSrsl8)# zQ8{gq(}@qv#n5h83Chacy?P9fBfU4sBeAS1PDE~5yygXvr1UkXW6^E!Sjos=4 zv=Q-4XIi5&^0pAr$sSW^cp1o^l@55NfI00000NkvXXu0mjfmfj4P literal 0 HcmV?d00001 diff --git "a/assets/textures/\350\213\271\346\236\234\346\240\221B\351\235\242.png" "b/assets/textures/\350\213\271\346\236\234\346\240\221B\351\235\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..d1970aae1e1e2aaf55e7a4ed398b22cbb104c4cd GIT binary patch literal 433 zcmV;i0Z#sjP)KVSJe!olgdy)cUaVm6)w+)04906YO~3ye`JCgil8D?p-B zslX_qFjs(N<++a1k~>dP0w_c0rSBue2_VKGN}M@729#`U?TnVZhI0jIG&;AQYaFap z2%yAZwT{-R76^mZzEkiRpxL-LoMl8QL z5huX<0}D|CYItkpF+ieHE4#cka0TS7%+eNjE#MUZPXOBjH3hsBSOnDQ`5112Ern`- zKRgD!0-OK?eNY8F0gFMf)%2MG@Ctw@AZdY?*7+DAEpVJVHz5EmjTYVl@C5uV(0aP; bEQsg_M`|^s!#+$U00000NkvXXu0mjf>C>st literal 0 HcmV?d00001 diff --git a/src/lib.rs b/src/lib.rs index 1439e6f..a21f9f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,13 +27,13 @@ pub const CHUNK_SIZE: i32 = 16; pub const CHUNK_SIZE_U32: u32 = CHUNK_SIZE as u32; pub const CHUNK_SIZE_ADD_2_U32: u32 = CHUNK_SIZE_U32 + 2; // 贴图个数 -pub const MAX_TEXTURE_COUNT: usize = 13; +pub const MAX_TEXTURE_COUNT: usize = 16; // 物体选择半径 pub const TOUCH_RADIUS: f32 = 5.; pub const CLIENT_DEBUG: bool = false; pub const CLIENT_FPS: bool = false; // 是否每次都重新生成地形 -pub const CLIENT_MAP_GEN: bool = false; +pub const CLIENT_MAP_GEN: bool = true; // 最大物品堆放 pub const MAX_STAFF_FIXED: usize = 999; diff --git a/src/voxel_world/biomes/basic_land.rs b/src/voxel_world/biomes/basic_land.rs index dc7c745..86307dc 100644 --- a/src/voxel_world/biomes/basic_land.rs +++ b/src/voxel_world/biomes/basic_land.rs @@ -1,10 +1,20 @@ // 基础大陆 +use bevy::prelude::Vec3; use ndshape::ConstShape; -use crate::voxel_world::voxel::{Grass, Soli, Sown, Stone, Voxel, VoxelMaterial}; +use crate::{ + tools::chunk_key_any_xyz_to_vec3, + voxel_world::{ + chunk::ChunkKey, + voxel::{AppleLeaf, AppleWood, Grass, Soli, Sown, Stone, Voxel, VoxelMaterial}, + }, +}; -use super::{BiomesGenerator, SampleShape, MOUNTAIN_LEVEL, SEE_LEVEL, SNOW_LEVEL}; +use super::{ + sdf::{sd_cut_sphere, trunk}, + BiomesGenerator, SampleShape, TreeGentor, MOUNTAIN_LEVEL, SEE_LEVEL, SNOW_LEVEL, +}; // 基础大陆 // 1. 雪顶 @@ -46,4 +56,29 @@ impl BiomesGenerator for BasicLandBiomes { } } } + + fn make_tree_with_info( + &self, + chunk_key: crate::voxel_world::chunk::ChunkKey, + voxels: &mut Vec, + _chunk_index: u32, + _plane_index: u32, + _height: f32, + xyz: [u32; 3], + ) -> Option<(Vec, TreeGentor)> { + let root_pos = chunk_key_any_xyz_to_vec3(chunk_key, xyz); + let leaf_center = root_pos + Vec3::new(0.0, 4.0, 0.0); + let trunk_fn = trunk(root_pos, 5); + let leaf_fn = sd_cut_sphere(leaf_center, 3.6, 0.0); + // 判断 是否需要给其他的模块处理? + // 这里 可以判断的又5个方向 + let mut tree_gentor = TreeGentor { + tree: AppleWood::into_voxel(), + leaf: AppleLeaf::into_voxel(), + trunk_fn: Box::new(trunk_fn), + leafs_fn: Box::new(leaf_fn), + }; + tree_gentor.make_tree_for_chunk(voxels, chunk_key.clone()); + Some((Vec::new(), tree_gentor)) + } } diff --git a/src/voxel_world/biomes/mod.rs b/src/voxel_world/biomes/mod.rs index c87a256..de72011 100644 --- a/src/voxel_world/biomes/mod.rs +++ b/src/voxel_world/biomes/mod.rs @@ -1,3 +1,6 @@ +use std::marker::PhantomData; + +use bevy::prelude::Vec3; use ndshape::{ConstShape, ConstShape2u32, ConstShape3u32}; use noise::{ core::worley::{distance_functions::euclidean, ReturnType}, @@ -5,19 +8,23 @@ use noise::{ Worley, }; -use crate::{CHUNK_SIZE, CHUNK_SIZE_U32}; +use crate::{tools::chunk_key_any_xyz_to_vec3, CHUNK_SIZE, CHUNK_SIZE_U32}; use self::{ basic_land::BasicLandBiomes, bule_land::BuleLandBoimes, dry_land::DryLandBiomes, sand_land::SandLandBiomes, snow_land::SnowLandBiomes, }; -use super::{chunk::ChunkKey, voxel::Voxel}; +use super::{ + chunk::ChunkKey, + voxel::{Voxel, VoxelMaterial}, +}; pub mod basic_land; pub mod bule_land; pub mod dry_land; pub mod sand_land; +pub mod sdf; pub mod snow_land; pub type SampleShape = ConstShape3u32; @@ -35,6 +42,8 @@ pub fn biomes_generate( } // 生成噪声 let noise = biomes_noise(chunk_key, seed); + // 这里产生一个 种树的噪声 + let tree_noise = tree_noise(chunk_key, seed); for index in suface_index { // 由噪声生产的特征值 @@ -44,6 +53,11 @@ pub fn biomes_generate( let generator = get_generator_by_atrr(atrr); generator.gen_land(chunk_key.clone(), voxels, index, index_2d); // fixme: 这里要记录对于其他方块的影响 + if tree_noise[index_2d as usize] > 0.8 { + if let Some((key_list, tree_genter)) = + generator.make_tree(chunk_key.clone(), voxels, index, index_2d) + {} + } } } @@ -62,6 +76,25 @@ fn get_generator_by_atrr(data: f32) -> Box { } } +pub fn tree_noise(chunk_key: ChunkKey, seed: i32) -> Vec { + let noise = Worley::new(seed as u32) + .set_distance_function(euclidean) + .set_return_type(ReturnType::Value) + .set_frequency(1.0); + + let x_offset = (chunk_key.0.x * CHUNK_SIZE) as f64; + let z_offset = (chunk_key.0.z * CHUNK_SIZE) as f64; + + noise::utils::PlaneMapBuilder::<_, 2>::new(noise) + .set_size(CHUNK_SIZE as usize, CHUNK_SIZE as usize) + .set_x_bounds(x_offset, x_offset + CHUNK_SIZE as f64) + .set_y_bounds(z_offset, z_offset + CHUNK_SIZE as f64) + .build() + .into_iter() + .map(|x| x as f32) + .collect() +} + pub fn biomes_noise(chunk_key: ChunkKey, seed: i32) -> Vec { let noise = Worley::new(seed as u32) .set_distance_function(euclidean) @@ -111,6 +144,39 @@ pub trait BiomesGenerator: 'static + Sync + Send { [x, y, z], ); } + + fn make_tree( + &self, + chunk_key: ChunkKey, + voxels: &mut Vec, + chunk_index: u32, + plane_index: u32, + ) -> Option<(Vec, TreeGentor)> { + let base_y: f32 = (chunk_key.0.y * CHUNK_SIZE) as f32; + let [x, y, z] = SampleShape::delinearize(chunk_index); + let height = base_y + y as f32; + self.make_tree_with_info( + chunk_key, + voxels, + chunk_index, + plane_index, + height, + [x, y, z], + ) + } + + fn make_tree_with_info( + &self, + _chunk_key: ChunkKey, + _voxels: &mut Vec, + _chunk_index: u32, + _plane_index: u32, + _height: f32, + _xyz: [u32; 3], + ) -> Option<(Vec, TreeGentor)> { + // do nothing; + None + } } pub trait IntoBoxedTerrainGenerator: BiomesGenerator + Sized { @@ -128,3 +194,26 @@ pub const SEE_LEVEL: f32 = -60. + 76.; pub const MOUNTAIN_LEVEL: f32 = -60. + 100.; // 雪线 pub const SNOW_LEVEL: f32 = -60. + 100.; + +pub struct TreeGentor { + pub tree: Voxel, + pub leaf: Voxel, + pub trunk_fn: Box f32>, + pub leafs_fn: Box f32>, +} + +impl TreeGentor { + pub fn make_tree_for_chunk(&mut self, voxels: &mut Vec, chunk_key: ChunkKey) { + for index in 0..SampleShape::SIZE { + let inner_xyz = SampleShape::delinearize(index); + let check_pos = chunk_key_any_xyz_to_vec3(chunk_key, inner_xyz); + if self.trunk_fn.as_mut()(check_pos.clone()) <= 0.0 { + voxels[index as usize] = self.tree.clone(); + } else if self.leafs_fn.as_mut()(check_pos.clone()) <= 0.0 + && voxels[index as usize].id != self.leaf.id + { + voxels[index as usize] = self.leaf.clone(); + } + } + } +} diff --git a/src/voxel_world/biomes/sdf.rs b/src/voxel_world/biomes/sdf.rs new file mode 100644 index 0000000..9310637 --- /dev/null +++ b/src/voxel_world/biomes/sdf.rs @@ -0,0 +1,51 @@ +// 树干 + +use std::cmp::max; + +use bevy::{ + math::{vec2, Vec3Swizzles}, + prelude::{Vec2, Vec3}, +}; + +/** + * 树干函数 + * root :根部 + * pos :检查点 + * h : 树干占的 体素格子数 + * >0 是外部 <=0 是内部 + */ +pub fn trunk(root: Vec3, h: u32) -> impl FnMut(Vec3) -> f32 { + move |pos: Vec3| { + let a = pos - root; + if a.x != 0. || a.z != 0. || a.y < 0. || a.y > h as f32 { + return 1.0; + } + 0. + } +} + +/** + * 获取半圆 + */ +pub fn sd_cut_sphere(center: Vec3, r: f32, h: f32) -> impl FnMut(Vec3) -> f32 { + move |pos: Vec3| { + let p = pos - center; + + let w = (r * r - h * h).sqrt(); + + // sampling dependant computations + let q = vec2(p.xz().length(), p.y); + let a = (h - r) * q.x * q.x + w * w * (h + r - 2.0 * q.y); + let b = h * q.x - w * q.y; + let s = if a > b { a } else { b }; + return if s < 0.0 { + q.length() - r + } else { + if q.x < w { + h - q.y + } else { + (q - vec2(w, h)).length() + } + }; + } +} diff --git a/src/voxel_world/map_generator.rs b/src/voxel_world/map_generator.rs index 7e0e16b..63e3a61 100644 --- a/src/voxel_world/map_generator.rs +++ b/src/voxel_world/map_generator.rs @@ -102,19 +102,19 @@ pub fn gen_chunk_data_by_seed(seed: i32, chunk_key: ChunkKey) -> Vec { } //侵蚀 洞穴 - let noise_3d = noise3d_2(chunk_key, seed); - for i in 0..SampleShape::SIZE { - // let [x, y, z] = SampleShape::delinearize(i); - // let index = SampleShape::linearize([x, z, y]); - let flag: f32 = noise_3d[i as usize]; - if flag < 0.05 - && flag > -0.05 - && voxels[i as usize].id != Water::ID - && voxels[i as usize].id != BasicStone::ID - { - voxels[i as usize] = Voxel::EMPTY; - } - } + // let noise_3d = noise3d_2(chunk_key, seed); + // for i in 0..SampleShape::SIZE { + // // let [x, y, z] = SampleShape::delinearize(i); + // // let index = SampleShape::linearize([x, z, y]); + // let flag: f32 = noise_3d[i as usize]; + // if flag < 0.05 + // && flag > -0.05 + // && voxels[i as usize].id != Water::ID + // && voxels[i as usize].id != BasicStone::ID + // { + // voxels[i as usize] = Voxel::EMPTY; + // } + // } voxels } diff --git a/src/voxel_world/voxel.rs b/src/voxel_world/voxel.rs index 7195143..768f167 100644 --- a/src/voxel_world/voxel.rs +++ b/src/voxel_world/voxel.rs @@ -79,3 +79,5 @@ voxel_material!(Sand, 沙子, 6); voxel_material!(BasicStone, 基岩, 7); voxel_material!(DryGrass, 干草地, 8); voxel_material!(BuleGrass, 苍翠地, 9); +voxel_material!(AppleWood, 苹果树原木, 10); +voxel_material!(AppleLeaf, 苹果树叶子, 11); \ No newline at end of file diff --git a/staff.ron b/staff.ron index a7540e6..70c7384 100644 --- a/staff.ron +++ b/staff.ron @@ -8,5 +8,7 @@ (id:5,name:"FireWork",icon_string:"staff/烟花.png",staff_type:Consumable(0)), (id:6,name:"DryGrass",icon_string:"textures/干草地.png",staff_type:Voxel((id:8))), (id:7,name:"BlueGrass",icon_string:"textures/苍翠地.png",staff_type:Voxel((id:9))), + (id:8,name:"AppleWood",icon_string:"textures/苹果树A面.png",staff_type:Voxel((id:10))), + (id:9,name:"AppleLeaf",icon_string:"textures/苹果叶子.png",staff_type:Voxel((id:11))), ] ) \ No newline at end of file diff --git a/volex.ron b/volex.ron index 1384374..2e4b076 100644 --- a/volex.ron +++ b/volex.ron @@ -1,5 +1,10 @@ ( voxels:{ + 11:(type_name:"AppleLeaf",type_ch_name:"苹果树叶子",default:(index:15,path:"textures/苹果叶子.png"),normal:{}), + 10:(type_name:"AppleWood",type_ch_name:"苹果树原木",default:(index:13,path:"textures/苹果树A面.png"),normal:{ + 4:(index:14,path:"textures/苹果树B面.png"), + 1:(index:14,path:"textures/苹果树B面.png"), + }), 9:(type_name:"BuleGrass",type_ch_name:"苍翠地",default:(index:12,path:"textures/苍翠侧面.png"),normal:{ 4:(index:11,path:"textures/苍翠地.png"), 1:(index:1,path:"textures/003.png"), @@ -34,5 +39,9 @@ // 10 "textures/干草地.png", "textures/苍翠地.png", - "textures/苍翠侧面.png" + "textures/苍翠侧面.png", + "textures/苹果树A面.png", + "textures/苹果树B面.png", + //15 + "textures/苹果叶子.png", ]) \ No newline at end of file From 62c4cb9a4d4aadfc046a6d7f7f04c88781e7852d Mon Sep 17 00:00:00 2001 From: zhouzihao <1042181618@qq.com> Date: Thu, 7 Sep 2023 17:09:13 +0800 Subject: [PATCH 2/4] style --- src/voxel_world/biomes/sdf.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/voxel_world/biomes/sdf.rs b/src/voxel_world/biomes/sdf.rs index 9310637..3dfc439 100644 --- a/src/voxel_world/biomes/sdf.rs +++ b/src/voxel_world/biomes/sdf.rs @@ -1,10 +1,6 @@ -// 树干 - -use std::cmp::max; - use bevy::{ math::{vec2, Vec3Swizzles}, - prelude::{Vec2, Vec3}, + prelude::Vec3, }; /** From 1e28dcb34808e212f5232a4b9a12e8de06563886 Mon Sep 17 00:00:00 2001 From: zhouzihao <1042181618@qq.com> Date: Fri, 8 Sep 2023 03:05:43 +0800 Subject: [PATCH 3/4] =?UTF-8?q?dev-=E8=B7=A8=E5=8C=BA=E5=9D=97=E6=A0=91?= =?UTF-8?q?=E6=9C=A8=E7=94=9F=E6=88=90=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bin/client.rs | 9 -- src/bin/server.rs | 2 + src/client/state_manager/mod.rs | 4 +- src/client/ui/staff_rules.rs | 2 +- src/server/async_chunk.rs | 14 ++- src/server/chunk.rs | 8 +- src/server/message_def/chunk_result.rs | 2 +- src/sky/mod.rs | 1 - src/voxel_world/biomes/basic_land.rs | 30 +++-- src/voxel_world/biomes/mod.rs | 149 ++++++++++++++++++++++--- src/voxel_world/chunk.rs | 5 + src/voxel_world/map_database.rs | 6 +- src/voxel_world/map_generator.rs | 19 ++-- src/voxel_world/mod.rs | 4 +- src/voxel_world/voxel.rs | 2 +- 15 files changed, 199 insertions(+), 58 deletions(-) diff --git a/src/bin/client.rs b/src/bin/client.rs index abed270..629c238 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -71,12 +71,3 @@ fn main() { //app.add_systems(Startup, setting_language); app.run(); } - -//setting of switch the lanuguage -// fn setting_language(mut localize: ResMut) { -// localize.set_language(CHINESE); - -// println!("开始是:{}", localize.get("开始")); -// } - -// 快速注释 Ctrl + ? \ No newline at end of file diff --git a/src/bin/server.rs b/src/bin/server.rs index 7fb55ef..d766b3d 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -24,6 +24,7 @@ use just_join::{ }, sky::ServerSkyPlugins, staff::ServerStaffInfoPlugin, + voxel_world::biomes::OtherTreePlugin, PROTOCOL_ID, }; use renet_visualizer::RenetServerVisualizer; @@ -119,6 +120,7 @@ fn main() { ObjectFilingPlugin, ServerStaffRulePlugin, CossTroughCheckPlugin, + OtherTreePlugin, )); let (server, transport) = new_renet_server(); diff --git a/src/client/state_manager/mod.rs b/src/client/state_manager/mod.rs index eab9873..b68cabc 100644 --- a/src/client/state_manager/mod.rs +++ b/src/client/state_manager/mod.rs @@ -86,5 +86,5 @@ pub fn new_renet_client(connection_addr: ConnectionAddr) -> (RenetClient, Netcod (client, transport) } -pub const CHINESE:&str="Chinese"; -pub const ENGLISH:&str="English"; \ No newline at end of file +pub const CHINESE: &str = "Chinese"; +pub const ENGLISH: &str = "English"; diff --git a/src/client/ui/staff_rules.rs b/src/client/ui/staff_rules.rs index 7e716d1..c2c4f4c 100644 --- a/src/client/ui/staff_rules.rs +++ b/src/client/ui/staff_rules.rs @@ -1,9 +1,9 @@ // 合成相关UI -use bevy_easy_localize::Localize; use bevy::{ prelude::{Entity, Query, Res, ResMut, With}, window::{PrimaryWindow, Window}, }; +use bevy_easy_localize::Localize; use bevy_egui::{ egui::{self, Align2, Vec2}, EguiContext, EguiUserTextures, diff --git a/src/server/async_chunk.rs b/src/server/async_chunk.rs index 7c4575c..eac319a 100644 --- a/src/server/async_chunk.rs +++ b/src/server/async_chunk.rs @@ -10,6 +10,7 @@ use crate::{ server::{message_def::ServerChannel, object_filing::put_object::put_object}, staff::StaffInfoStroge, voxel_world::{ + biomes::OtherTreeTasksMap, chunk::ChunkKey, chunk_map::ChunkMap, compress::compress, @@ -47,6 +48,7 @@ pub fn deal_chunk_query_system( // 获取玩家当前状态 和处理 mut query_state: Query<&mut PlayerOntimeState>, server_lobby: Res, + mut other_tree_tasks_map: ResMut, ) { let pool = AsyncComputeTaskPool::get(); for client_id in server.clients_id() { @@ -63,7 +65,11 @@ pub fn deal_chunk_query_system( if let Some(data) = chunk_map.map_data.get(&new_key) { voxels = data.clone(); } else { - voxels = db.find_by_chunk_key(new_key, db_save_task.as_mut()); + voxels = db.find_by_chunk_key( + new_key, + db_save_task.as_mut(), + other_tree_tasks_map.as_mut(), + ); } let (buffer, tree) = compress(voxels.clone()); let message = if buffer.len() == 0 { @@ -264,7 +270,11 @@ pub fn send_message(mut tasks: ResMut, mut server: ResMut, mut db: ResMut, mut db_save_tasks: ResMut, + mut other_tree_tasks_map: ResMut, ) { for (_client_id, clip_spheres) in server_clip_spheres.clip_spheres.iter() { // 通过球体计算 chunkey @@ -32,7 +34,11 @@ pub fn server_chunk_generate_system( // chunk_map.gen_chunk_data(key); if !chunk_map.map_data.contains_key(&key) { // 这里可以判断一下是否是 已经加载的数据 - let data = db.find_by_chunk_key(key, db_save_tasks.as_mut()); + let data = db.find_by_chunk_key( + key, + db_save_tasks.as_mut(), + other_tree_tasks_map.as_mut(), + ); chunk_map.write_chunk(key, data); } }, diff --git a/src/server/message_def/chunk_result.rs b/src/server/message_def/chunk_result.rs index 85d7844..a07cdb7 100644 --- a/src/server/message_def/chunk_result.rs +++ b/src/server/message_def/chunk_result.rs @@ -11,7 +11,7 @@ pub enum ChunkResult { key: ChunkKey, data: (BitVec, Tree), }, - ChunkSame((ChunkKey,Voxel)), + ChunkSame((ChunkKey, Voxel)), ChunkUpdateOne { chunk_key: ChunkKey, pos: [u32; 3], diff --git a/src/sky/mod.rs b/src/sky/mod.rs index 7ec79d7..9227cf9 100644 --- a/src/sky/mod.rs +++ b/src/sky/mod.rs @@ -13,7 +13,6 @@ use bevy_renet::renet::{RenetClient, RenetServer}; use crate::server::message_def::{time_sync::TimeSync, ServerChannel}; - #[derive(Component)] pub struct Sun; diff --git a/src/voxel_world/biomes/basic_land.rs b/src/voxel_world/biomes/basic_land.rs index 86307dc..7ec502b 100644 --- a/src/voxel_world/biomes/basic_land.rs +++ b/src/voxel_world/biomes/basic_land.rs @@ -2,6 +2,7 @@ use bevy::prelude::Vec3; use ndshape::ConstShape; +use rand::Rng; use crate::{ tools::chunk_key_any_xyz_to_vec3, @@ -12,8 +13,8 @@ use crate::{ }; use super::{ - sdf::{sd_cut_sphere, trunk}, - BiomesGenerator, SampleShape, TreeGentor, MOUNTAIN_LEVEL, SEE_LEVEL, SNOW_LEVEL, + find_out_chunk_keys, BiomesGenerator, SampleShape, TreeGentor, MOUNTAIN_LEVEL, SEE_LEVEL, + SNOW_LEVEL, }; // 基础大陆 @@ -63,22 +64,33 @@ impl BiomesGenerator for BasicLandBiomes { voxels: &mut Vec, _chunk_index: u32, _plane_index: u32, - _height: f32, + height: f32, xyz: [u32; 3], ) -> Option<(Vec, TreeGentor)> { + let mut rng = rand::thread_rng(); + let root_pos = chunk_key_any_xyz_to_vec3(chunk_key, xyz); let leaf_center = root_pos + Vec3::new(0.0, 4.0, 0.0); - let trunk_fn = trunk(root_pos, 5); - let leaf_fn = sd_cut_sphere(leaf_center, 3.6, 0.0); // 判断 是否需要给其他的模块处理? + let h = rng.gen_range(3..5); + let r = rng.gen_range(2.9..4.6); // 这里 可以判断的又5个方向 let mut tree_gentor = TreeGentor { tree: AppleWood::into_voxel(), - leaf: AppleLeaf::into_voxel(), - trunk_fn: Box::new(trunk_fn), - leafs_fn: Box::new(leaf_fn), + leaf: if height >= -60. + 110. { + Voxel::EMPTY + } else { + AppleLeaf::into_voxel() + }, + trunk_params: (root_pos, h), + leafs_params: (leaf_center, r, 0.0), }; tree_gentor.make_tree_for_chunk(voxels, chunk_key.clone()); - Some((Vec::new(), tree_gentor)) + + let vec_list = find_out_chunk_keys(xyz, chunk_key.clone(), h, r.ceil() as u32); + if vec_list.len() > 0 { + return Some((vec_list, tree_gentor)); + } + None } } diff --git a/src/voxel_world/biomes/mod.rs b/src/voxel_world/biomes/mod.rs index de72011..3ec9bb6 100644 --- a/src/voxel_world/biomes/mod.rs +++ b/src/voxel_world/biomes/mod.rs @@ -1,6 +1,8 @@ -use std::marker::PhantomData; - -use bevy::prelude::Vec3; +use bevy::{ + prelude::{IVec3, Plugin, ResMut, Resource, Update, Vec3}, + tasks::AsyncComputeTaskPool, + utils::{HashMap, HashSet}, +}; use ndshape::{ConstShape, ConstShape2u32, ConstShape3u32}; use noise::{ core::worley::{distance_functions::euclidean, ReturnType}, @@ -8,16 +10,24 @@ use noise::{ Worley, }; -use crate::{tools::chunk_key_any_xyz_to_vec3, CHUNK_SIZE, CHUNK_SIZE_U32}; +use crate::{ + server::{async_chunk::ChunkResultTasks, message_def::chunk_result::ChunkResult}, + tools::chunk_key_any_xyz_to_vec3, + CHUNK_SIZE, CHUNK_SIZE_U32, +}; use self::{ - basic_land::BasicLandBiomes, bule_land::BuleLandBoimes, dry_land::DryLandBiomes, - sand_land::SandLandBiomes, snow_land::SnowLandBiomes, + basic_land::BasicLandBiomes, + bule_land::BuleLandBoimes, + dry_land::DryLandBiomes, + sand_land::SandLandBiomes, + sdf::{sd_cut_sphere, trunk}, + snow_land::SnowLandBiomes, }; use super::{ - chunk::ChunkKey, - voxel::{Voxel, VoxelMaterial}, + chunk::ChunkKey, chunk_map::ChunkMap, compress::compress, map_database::DbSaveTasks, + voxel::Voxel, }; pub mod basic_land; @@ -36,9 +46,10 @@ pub fn biomes_generate( seed: i32, suface_index: Vec, voxels: &mut Vec, -) { +) -> Vec<(Vec, TreeGentor)> { + let mut ret = Vec::new(); if suface_index.len() == 0 { - return; + return ret; } // 生成噪声 let noise = biomes_noise(chunk_key, seed); @@ -54,11 +65,12 @@ pub fn biomes_generate( generator.gen_land(chunk_key.clone(), voxels, index, index_2d); // fixme: 这里要记录对于其他方块的影响 if tree_noise[index_2d as usize] > 0.8 { - if let Some((key_list, tree_genter)) = - generator.make_tree(chunk_key.clone(), voxels, index, index_2d) - {} + if let Some(rs) = generator.make_tree(chunk_key.clone(), voxels, index, index_2d) { + ret.push(rs); + } } } + ret } // 获取不同的生成器 @@ -195,25 +207,126 @@ pub const MOUNTAIN_LEVEL: f32 = -60. + 100.; // 雪线 pub const SNOW_LEVEL: f32 = -60. + 100.; +#[derive(Debug, Clone)] pub struct TreeGentor { pub tree: Voxel, pub leaf: Voxel, - pub trunk_fn: Box f32>, - pub leafs_fn: Box f32>, + pub trunk_params: (Vec3, u32), + pub leafs_params: (Vec3, f32, f32), } impl TreeGentor { pub fn make_tree_for_chunk(&mut self, voxels: &mut Vec, chunk_key: ChunkKey) { + let mut trunk_fn = trunk(self.trunk_params.0, self.trunk_params.1); + let mut leaf_fn = sd_cut_sphere( + self.leafs_params.0, + self.leafs_params.1, + self.leafs_params.2, + ); + for index in 0..SampleShape::SIZE { let inner_xyz = SampleShape::delinearize(index); let check_pos = chunk_key_any_xyz_to_vec3(chunk_key, inner_xyz); - if self.trunk_fn.as_mut()(check_pos.clone()) <= 0.0 { + if trunk_fn(check_pos.clone()) <= 0.0 { voxels[index as usize] = self.tree.clone(); - } else if self.leafs_fn.as_mut()(check_pos.clone()) <= 0.0 - && voxels[index as usize].id != self.leaf.id + } else if leaf_fn(check_pos.clone()) <= 0.0 && voxels[index as usize].id != self.leaf.id { voxels[index as usize] = self.leaf.clone(); } } } } + +pub fn find_out_chunk_keys(xyz: [u32; 3], chunk_key: ChunkKey, h: u32, r: u32) -> Vec { + let mut ret = Vec::new(); + let [x, y, z] = xyz; + if x < r { + ret.push(chunk_key.add_ivec3(IVec3::new(-1, 0, 0))); + } + if x + r >= CHUNK_SIZE_U32 { + ret.push(chunk_key.add_ivec3(IVec3::new(1, 0, 0))); + } + if z < r { + ret.push(chunk_key.add_ivec3(IVec3::new(0, 0, -1))); + } + if z + r >= CHUNK_SIZE_U32 { + ret.push(chunk_key.add_ivec3(IVec3::new(-0, 0, 1))); + } + + if y + h - 1 + r >= CHUNK_SIZE_U32 { + ret.push(chunk_key.add_ivec3(IVec3::new(0, 1, 0))); + } + ret +} + +#[derive(Resource)] +pub struct OtherTreeTasksMap { + pub tree_map: HashMap>, +} + +impl OtherTreeTasksMap { + pub fn insert(&mut self, list: Vec<(Vec, TreeGentor)>) { + for (keys, tree_gentor) in list.into_iter() { + for key in keys.iter() { + self.tree_map + .entry(*key) + .or_insert(Vec::new()) + .push(tree_gentor.clone()); + } + } + } +} + +pub struct OtherTreePlugin; + +impl Plugin for OtherTreePlugin { + fn build(&self, app: &mut bevy::prelude::App) { + app.insert_resource(OtherTreeTasksMap { + tree_map: HashMap::new(), + }); + app.add_systems(Update, deal_other_tree); + } +} + +fn deal_other_tree( + mut db_save_task: ResMut, + mut chunk_map: ResMut, + mut other_tree_tasks_map: ResMut, + mut tasks: ResMut, +) { + let pool = AsyncComputeTaskPool::get(); + let mut exit_keys: HashSet = HashSet::new(); + + for (chunk_key, list) in other_tree_tasks_map.tree_map.iter_mut() { + if let Some(voxels) = chunk_map.map_data.get_mut(&chunk_key.clone()) { + for tree_gentor in list { + tree_gentor.make_tree_for_chunk(voxels, chunk_key.clone()); + exit_keys.insert(chunk_key.clone()); + } + } + } + + for key in exit_keys { + if let Some(_) = other_tree_tasks_map.tree_map.remove(&key) { + if let Some(data) = chunk_map.map_data.get(&key) { + let voxels = data.clone(); + let (buffer, tree) = compress(voxels.clone()); + let message = if buffer.len() == 0 { + bincode::serialize(&ChunkResult::ChunkSame((key, voxels[0]))).unwrap() + } else { + bincode::serialize(&ChunkResult::ChunkData { + key: key, + data: (buffer, tree), + }) + .unwrap() + }; + + let task = pool.spawn(async move { (0, message) }); + tasks.tasks.push(task); + + let task = pool.spawn(async move { (key.as_u8_array(), voxels.clone()) }); + db_save_task.tasks.push(task); + } + } + } +} diff --git a/src/voxel_world/chunk.rs b/src/voxel_world/chunk.rs index 92fb08f..4cb7011 100644 --- a/src/voxel_world/chunk.rs +++ b/src/voxel_world/chunk.rs @@ -15,6 +15,11 @@ use crate::{common::Sphere3, CHUNK_SIZE}; pub struct ChunkKey(pub IVec3); impl ChunkKey { + pub fn add_ivec3(&self, key: IVec3) -> ChunkKey { + let ivec3 = self.0.clone(); + ChunkKey(ivec3 + key) + } + pub fn as_u8_array(&self) -> [u8; 8] { let mut hasher = DefaultHasher::new(); self.0.hash(&mut hasher); diff --git a/src/voxel_world/map_database.rs b/src/voxel_world/map_database.rs index 879862f..9c24f38 100644 --- a/src/voxel_world/map_database.rs +++ b/src/voxel_world/map_database.rs @@ -9,7 +9,7 @@ use sled::Db; use crate::{voxel_world::map_generator::gen_chunk_data_by_seed, CHUNK_SIZE_U32, CLIENT_MAP_GEN}; -use super::{chunk::ChunkKey, voxel::Voxel}; +use super::{biomes::OtherTreeTasksMap, chunk::ChunkKey, voxel::Voxel}; #[derive(Resource)] pub struct MapDataBase { @@ -27,6 +27,7 @@ impl MapDataBase { &mut self, chunk_key: ChunkKey, db_tasks: &mut DbSaveTasks, + other_tree_tasks_map: &mut OtherTreeTasksMap, ) -> Vec { let pool = AsyncComputeTaskPool::get(); let mut voxels = Vec::new(); @@ -40,10 +41,11 @@ impl MapDataBase { Some(data) => bincode::deserialize(&data).unwrap(), // 这里在没有获取到的情况下使用算法的值 None => { - let new_voxels = gen_chunk_data_by_seed(1512354854, chunk_key); + let (new_voxels, other_trees) = gen_chunk_data_by_seed(1512354854, chunk_key); let new_voxels_clone = new_voxels.clone(); let task = pool.spawn(async move { (key, new_voxels_clone) }); db_tasks.tasks.push(task); + other_tree_tasks_map.insert(other_trees); new_voxels } }, diff --git a/src/voxel_world/map_generator.rs b/src/voxel_world/map_generator.rs index 63e3a61..27f6139 100644 --- a/src/voxel_world/map_generator.rs +++ b/src/voxel_world/map_generator.rs @@ -12,9 +12,12 @@ use crate::{ CHUNK_SIZE, CHUNK_SIZE_U32, }; -use super::{chunk::ChunkKey, voxel::Voxel}; +use super::{biomes::TreeGentor, chunk::ChunkKey, voxel::Voxel}; -pub fn gen_chunk_data_by_seed(seed: i32, chunk_key: ChunkKey) -> Vec { +pub fn gen_chunk_data_by_seed( + seed: i32, + chunk_key: ChunkKey, +) -> (Vec, Vec<(Vec, TreeGentor)>) { // let base_x = (chunk_key.0.x * CHUNK_SIZE) as f32; let base_y: f32 = (chunk_key.0.y * CHUNK_SIZE) as f32; // let base_z = (chunk_key.0.z * CHUNK_SIZE) as f32; @@ -35,11 +38,8 @@ pub fn gen_chunk_data_by_seed(seed: i32, chunk_key: ChunkKey) -> Vec { let index = PanleShap::linearize([x, z]); let top = h + fn_height(noise[index as usize]) + noise2[index as usize] * 5.0; if p_y <= top { - if p_y + 1.0 > top && p_y - 1.0 < top - // 必须大于海平面之上 - && p_y >= -60. + 76. - // 在山之下 - && p_y < -60. + 100. { + // 必须大于海平面 + if p_y + 1.0 > top && p_y - 1.0 < top && p_y >= -60. + 76. { suface_index.push(i); } if p_y >= -60. + 110. { @@ -81,7 +81,8 @@ pub fn gen_chunk_data_by_seed(seed: i32, chunk_key: ChunkKey) -> Vec { } // 处理不同群落 - biomes_generate(chunk_key, seed, suface_index, &mut voxels); + let others: Vec<(Vec, crate::voxel_world::biomes::TreeGentor)> = + biomes_generate(chunk_key, seed, suface_index, &mut voxels); //生成 沙子 if water_flag { @@ -116,7 +117,7 @@ pub fn gen_chunk_data_by_seed(seed: i32, chunk_key: ChunkKey) -> Vec { // } // } - voxels + (voxels, others) } pub fn check_water(voxels: Vec, point: [u32; 3]) -> bool { diff --git a/src/voxel_world/mod.rs b/src/voxel_world/mod.rs index f49e36a..75839db 100644 --- a/src/voxel_world/mod.rs +++ b/src/voxel_world/mod.rs @@ -1,8 +1,8 @@ +pub mod biomes; pub mod chunk; pub mod chunk_map; +pub mod compress; pub mod map_database; pub mod map_generator; pub mod player_state; pub mod voxel; -pub mod compress; -pub mod biomes; \ No newline at end of file diff --git a/src/voxel_world/voxel.rs b/src/voxel_world/voxel.rs index 768f167..b38da62 100644 --- a/src/voxel_world/voxel.rs +++ b/src/voxel_world/voxel.rs @@ -80,4 +80,4 @@ voxel_material!(BasicStone, 基岩, 7); voxel_material!(DryGrass, 干草地, 8); voxel_material!(BuleGrass, 苍翠地, 9); voxel_material!(AppleWood, 苹果树原木, 10); -voxel_material!(AppleLeaf, 苹果树叶子, 11); \ No newline at end of file +voxel_material!(AppleLeaf, 苹果树叶子, 11); From 42f14180adb0bfa21153bcf640578c1d9c2629be Mon Sep 17 00:00:00 2001 From: zhouzihao <1042181618@qq.com> Date: Fri, 8 Sep 2023 11:58:33 +0800 Subject: [PATCH 4/4] =?UTF-8?q?dev-=E8=B0=83=E6=95=B4=E6=A0=91=E6=9C=A8?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...1\346\236\234\345\217\266\345\255\220.png" | Bin 259 -> 807 bytes src/client/mesh_display.rs | 11 ++++- src/server/message_def/chunk_result.rs | 4 ++ src/server/player.rs | 3 ++ src/voxel_world/biomes/basic_land.rs | 18 ++++---- src/voxel_world/biomes/mod.rs | 42 +++++++++++++----- src/voxel_world/chunk.rs | 7 +++ 7 files changed, 65 insertions(+), 20 deletions(-) diff --git "a/assets/textures/\350\213\271\346\236\234\345\217\266\345\255\220.png" "b/assets/textures/\350\213\271\346\236\234\345\217\266\345\255\220.png" index f9d6eaa08a6320cce0edb7ec93d79b097ff10b0a..51d0c999102432c23cb9154dffd353aa22f58371 100644 GIT binary patch delta 785 zcmV+s1Md8T0;dL$BYy(!Nkl^o~yVsAGukwfE{x3iL5)bu1@1Ji!|2{oFuYUH%Qis%_`6CRb z*S2<}fR>1wgn%M7%o=S(dadz019~hn45Kw|;}J!mI5mHl0Dqf|K2#=gGn^VDJcs}b zd;}3_9f}1LU<;3sxJnhhJ~jlP3!Om(Q#-@k7@_R9q&T|R`X1J53q+eca_B|L*qs3p zGlbTiMa0kuwLqx3Sn8^hytV9FcFl@`;>e9qq+aa>JlJ(5kb=GHv9)I2vt06cWNYR1CVAvrSjTUbS`WQSz4MnJk@G+=T19NOD6(KnWk37Cq zYws$chL`E~O-3T32zKr1r6?jdwD~<8^r6_bUAMw03Eo@}7OMtt4Rj&GoZ(qUCR($Z z0U2*swI!Ifi&GKQg$VmL&Qyb~+bAG=pR3itO#WWqkbf0sa~XUu9!jdU!n@xLdBD86 zwgDvx5p{)cgd(>`sx46h#14JHQ6w;RGfae7i4{h3ZC$1sW|(p-?9Cn3D#Js>rL3@8 z2`%mj+x;6NN0N|9gpD*Sthn#b2zyej6mUfnvXwwvVegr%AVF!IY|vJ?#!+_!S!y`U z3M<}ZhJP9)Rv2kY^#CdoBv!b94|XLb$gFT7_Nn6XG&&cgRv5`wUZo@b*^padG+#{u z{c+gy#yoj!zUsRK6bo{KSKkh8c+~(q!CTl4t<{|oK{>&zZ-;ix*?b89njCW9@5OB! zjeaU@`|A-Pae`Sh!P|qkKf67akU2qw1az-Q&3}$vZ})ovTUZiiLa(V&PH$^6L0^fT zO+qmPEuw~Ak5VVd$Q#MG15I)JoZ~R{|7O74!O9}Sph#JzJ zAWOntO)rNffxZ*WCSiu%bBN(jgD4O~g3>kih($^G|LgG!^l)C3QoaGh>)_Uu*de9> P015yANkvXXu0mjf-xpr6 literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=r#xL8Ln`LHoxPEl$&u#(-w`Dd zj<96zZ3(6`*jO$ZGi?*uz3ZKfc5d17+aI^GZJuxQr~UA^9Wm$EoSa{IXa0TuzVoBw$OrWnAJYD@<);T3K F0RRd|PqP33 diff --git a/src/client/mesh_display.rs b/src/client/mesh_display.rs index e20b2ff..089b117 100644 --- a/src/client/mesh_display.rs +++ b/src/client/mesh_display.rs @@ -5,7 +5,7 @@ use std::{ use bevy::{ prelude::{ - AlphaMode, AssetServer, Assets, Color, Commands, Component, Entity, Handle, + AlphaMode, AssetServer, Assets, Color, Commands, Component, Entity, Handle, IVec3, IntoSystemConfigs, Last, MaterialMeshBundle, MaterialPlugin, Mesh, Plugin, PreUpdate, Res, ResMut, Resource, StandardMaterial, Startup, Transform, Update, }, @@ -165,6 +165,15 @@ pub fn async_chunk_result( while let Some(message) = client.receive_message(ServerChannel::ChunkResult) { let chunk_result: ChunkResult = bincode::deserialize(&message).unwrap(); match chunk_result { + ChunkResult::UpdateChunkData { key, data } => { + let voxel = uncompress(&data.0, data.1); + chunk_map.write_chunk(key.clone(), voxel); + key_set.insert((1, key.to_y_zore())); + key_set.insert((0, key.to_y_zore().add_ivec3(IVec3::new(1, 0, 0)))); + key_set.insert((0, key.to_y_zore().add_ivec3(IVec3::new(-1, 0, 0)))); + key_set.insert((0, key.to_y_zore().add_ivec3(IVec3::new(0, 0, 1)))); + key_set.insert((0, key.to_y_zore().add_ivec3(IVec3::new(0, 0, -1)))); + } ChunkResult::ChunkData { key, data } => { let task = pool.spawn(async move { (key, uncompress(&data.0, data.1)) }); chunk_sync_task.tasks.push(task); diff --git a/src/server/message_def/chunk_result.rs b/src/server/message_def/chunk_result.rs index a07cdb7..763f692 100644 --- a/src/server/message_def/chunk_result.rs +++ b/src/server/message_def/chunk_result.rs @@ -11,6 +11,10 @@ pub enum ChunkResult { key: ChunkKey, data: (BitVec, Tree), }, + UpdateChunkData { + key: ChunkKey, + data: (BitVec, Tree), + }, ChunkSame((ChunkKey, Voxel)), ChunkUpdateOne { chunk_key: ChunkKey, diff --git a/src/server/player.rs b/src/server/player.rs index 924d69e..2e926aa 100644 --- a/src/server/player.rs +++ b/src/server/player.rs @@ -10,6 +10,8 @@ use bevy_rapier3d::prelude::{ use crate::voxel_world::player_state::{PlayerOntimeState, PlayerState}; +use super::cross_through_check::CossTroughCheck; + #[derive(Debug, Component)] pub struct Player { pub id: u64, @@ -54,6 +56,7 @@ pub fn server_create_player( Group::GROUP_3, Group::GROUP_1 | Group::GROUP_3, )) + .insert(CossTroughCheck) .id() } diff --git a/src/voxel_world/biomes/basic_land.rs b/src/voxel_world/biomes/basic_land.rs index 7ec502b..1dce017 100644 --- a/src/voxel_world/biomes/basic_land.rs +++ b/src/voxel_world/biomes/basic_land.rs @@ -67,21 +67,21 @@ impl BiomesGenerator for BasicLandBiomes { height: f32, xyz: [u32; 3], ) -> Option<(Vec, TreeGentor)> { + if height >= MOUNTAIN_LEVEL { + return None; + } let mut rng = rand::thread_rng(); - let root_pos = chunk_key_any_xyz_to_vec3(chunk_key, xyz); - let leaf_center = root_pos + Vec3::new(0.0, 4.0, 0.0); + // 判断 是否需要给其他的模块处理? - let h = rng.gen_range(3..5); - let r = rng.gen_range(2.9..4.6); + let h = rng.gen_range(1..5); + let r = rng.gen_range(2.0..4.6); + + let leaf_center = root_pos + Vec3::new(0.0, h as f32 - 1.0, 0.0); // 这里 可以判断的又5个方向 let mut tree_gentor = TreeGentor { tree: AppleWood::into_voxel(), - leaf: if height >= -60. + 110. { - Voxel::EMPTY - } else { - AppleLeaf::into_voxel() - }, + leaf: AppleLeaf::into_voxel(), trunk_params: (root_pos, h), leafs_params: (leaf_center, r, 0.0), }; diff --git a/src/voxel_world/biomes/mod.rs b/src/voxel_world/biomes/mod.rs index 3ec9bb6..f416ddf 100644 --- a/src/voxel_world/biomes/mod.rs +++ b/src/voxel_world/biomes/mod.rs @@ -64,7 +64,7 @@ pub fn biomes_generate( let generator = get_generator_by_atrr(atrr); generator.gen_land(chunk_key.clone(), voxels, index, index_2d); // fixme: 这里要记录对于其他方块的影响 - if tree_noise[index_2d as usize] > 0.8 { + if tree_noise[index_2d as usize] > 0.99 { if let Some(rs) = generator.make_tree(chunk_key.clone(), voxels, index, index_2d) { ret.push(rs); } @@ -205,7 +205,7 @@ pub const SEE_LEVEL: f32 = -60. + 76.; // 山峰线 pub const MOUNTAIN_LEVEL: f32 = -60. + 100.; // 雪线 -pub const SNOW_LEVEL: f32 = -60. + 100.; +pub const SNOW_LEVEL: f32 = -60. + 110.; #[derive(Debug, Clone)] pub struct TreeGentor { @@ -229,7 +229,8 @@ impl TreeGentor { let check_pos = chunk_key_any_xyz_to_vec3(chunk_key, inner_xyz); if trunk_fn(check_pos.clone()) <= 0.0 { voxels[index as usize] = self.tree.clone(); - } else if leaf_fn(check_pos.clone()) <= 0.0 && voxels[index as usize].id != self.leaf.id + } else if leaf_fn(check_pos.clone()) <= 0.0 + && voxels[index as usize].id == Voxel::EMPTY.id { voxels[index as usize] = self.leaf.clone(); } @@ -240,22 +241,43 @@ impl TreeGentor { pub fn find_out_chunk_keys(xyz: [u32; 3], chunk_key: ChunkKey, h: u32, r: u32) -> Vec { let mut ret = Vec::new(); let [x, y, z] = xyz; + let mut x_offset = 0; + let mut z_offset = 0; if x < r { ret.push(chunk_key.add_ivec3(IVec3::new(-1, 0, 0))); - } - if x + r >= CHUNK_SIZE_U32 { + x_offset = -1; + } else if x + r >= CHUNK_SIZE_U32 { ret.push(chunk_key.add_ivec3(IVec3::new(1, 0, 0))); + x_offset = -1; } if z < r { ret.push(chunk_key.add_ivec3(IVec3::new(0, 0, -1))); + z_offset = -1; + } else if z + r >= CHUNK_SIZE_U32 { + ret.push(chunk_key.add_ivec3(IVec3::new(0, 0, 1))); + z_offset = 1; } - if z + r >= CHUNK_SIZE_U32 { - ret.push(chunk_key.add_ivec3(IVec3::new(-0, 0, 1))); - } - + let mut y_offset = 0; if y + h - 1 + r >= CHUNK_SIZE_U32 { ret.push(chunk_key.add_ivec3(IVec3::new(0, 1, 0))); + y_offset = 1; + } + + if x_offset != 0 && z_offset != 0 { + ret.push(chunk_key.add_ivec3(IVec3::new(x_offset, 0, z_offset))); } + if y_offset != 0 { + if x_offset != 0 { + ret.push(chunk_key.add_ivec3(IVec3::new(x_offset, y_offset, 0))); + } + if z_offset != 0 { + ret.push(chunk_key.add_ivec3(IVec3::new(0, y_offset, z_offset))); + } + if x_offset != 0 && z_offset != 0 { + ret.push(chunk_key.add_ivec3(IVec3::new(x_offset, y_offset, z_offset))); + } + } + ret } @@ -314,7 +336,7 @@ fn deal_other_tree( let message = if buffer.len() == 0 { bincode::serialize(&ChunkResult::ChunkSame((key, voxels[0]))).unwrap() } else { - bincode::serialize(&ChunkResult::ChunkData { + bincode::serialize(&ChunkResult::UpdateChunkData { key: key, data: (buffer, tree), }) diff --git a/src/voxel_world/chunk.rs b/src/voxel_world/chunk.rs index 4cb7011..5a9f611 100644 --- a/src/voxel_world/chunk.rs +++ b/src/voxel_world/chunk.rs @@ -15,6 +15,13 @@ use crate::{common::Sphere3, CHUNK_SIZE}; pub struct ChunkKey(pub IVec3); impl ChunkKey { + + pub fn to_y_zore(&self)->ChunkKey { + let mut ivec3 = self.0.clone(); + ivec3.y = 0; + ChunkKey(ivec3) + } + pub fn add_ivec3(&self, key: IVec3) -> ChunkKey { let ivec3 = self.0.clone(); ChunkKey(ivec3 + key)