Skip to content

Commit

Permalink
Merge pull request #82 from zzhgithub/feature-support-more-mesh
Browse files Browse the repository at this point in the history
Feature support more mesh
  • Loading branch information
zzhgithub authored Sep 14, 2023
2 parents b032fcf + 6ba29d8 commit f8956cd
Show file tree
Hide file tree
Showing 17 changed files with 253 additions and 28 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub const CLIENT_MAP_GEN: bool = true;
- T - toggle One/Thrid Person
- E - Open composite rules list
- Q - throw active toolbar object
- (Hold Left-Shift Left-Click)-rotation Cube Direction

# Feature List
- [x] Load unlimited maps
Expand Down
2 changes: 2 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ cargo run --release --bin client
- T 切换视角
- E 打开合成表
- Q 丢弃toolbar上激活中的物品
- 按住左Shirt+左键单机。旋转方块方向


# LIB 中的配置常量
```rust
Expand Down
Binary file added assets/textures/测试1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/textures/测试2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/textures/测试3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/textures/测试4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/textures/测试5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/textures/测试6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 28 additions & 2 deletions src/client/player/mouse_control.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bevy::{
prelude::{
in_state, warn, Event, EventReader, EventWriter, IVec3, Input, IntoSystemConfigs,
in_state, warn, Event, EventReader, EventWriter, IVec3, Input, IntoSystemConfigs, KeyCode,
MouseButton, Plugin, Query, Res, ResMut, Resource, Transform, Update, Vec3,
},
time::{Time, Timer, TimerMode},
Expand All @@ -16,7 +16,7 @@ use crate::{
},
server::player::Player,
tools::{vec3_to_chunk_key_any_xyz, zone::check_player_put_object_available},
voxel_world::{chunk::ChunkKey, voxel::Voxel},
voxel_world::{chunk::ChunkKey, chunk_map::ChunkMap, voxel::Voxel},
};

use super::controller::ControllerFlag;
Expand Down Expand Up @@ -79,17 +79,43 @@ pub fn deal_broken_cube_event(
//鼠标操作
pub fn mouse_button_system(
mouse_button_input: Res<Input<MouseButton>>,
keyboard_input: Res<Input<KeyCode>>,
choose_cube: Res<ChooseCube>,
controller_flag: Res<ControllerFlag>,
mut client: ResMut<RenetClient>,
tool_bar_data: Res<ToolBar>,
mut attack_timer: ResMut<AttackTimer>,
player_query: Query<(&Player, &Transform)>,
chunk_map: Res<ChunkMap>,
) {
if !controller_flag.flag {
// println!("3:{}", controller_flag.flag);
return;
}

// 移动数据的方向
if mouse_button_input.just_released(MouseButton::Left)
&& keyboard_input.pressed(KeyCode::ShiftLeft)
{
if let Some(pos) = choose_cube.center {
let (chunk_key, xyz) = vec3_to_chunk_key_any_xyz(pos);
if let Some(voxel_type) = chunk_map.get_block(chunk_key, xyz) {
// FIXME: 这里要判断是否每种情况都可以去旋转!
let new_voxel = voxel_type.next_direction();
println!("这里发送了旋转方块的指令{:?}", new_voxel);
let message = bincode::serialize(&ChunkQuery::Change {
chunk_key,
pos: xyz,
voxel_type: new_voxel,
center: pos,
active_index: None,
})
.unwrap();
client.send_message(ClientChannel::ChunkQuery, message);
}
}
}

if mouse_button_input.just_pressed(MouseButton::Left) || attack_timer.pressed {
attack_timer.pressed = true;
// println!("4:{}", controller_flag.flag);
Expand Down
58 changes: 50 additions & 8 deletions src/client/voxels/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use ndshape::{ConstShape, ConstShape3u32, Shape};

use crate::{
client::voxels::mesh_material::ATTRIBUTE_DATA,
voxel_world::voxel::{Voxel, VoxelMaterial, Water},
voxel_world::voxel::{Voxel, VoxelDirection, VoxelMaterial, Water},
CHUNK_SIZE, CHUNK_SIZE_ADD_2_U32,
};

Expand Down Expand Up @@ -52,23 +52,64 @@ where
indices.extend_from_slice(&face.quad_mesh_indices(positions.len() as u32));
positions.extend_from_slice(&face.quad_mesh_positions(quad, 1.0));
normals.extend_from_slice(&face.quad_mesh_normals());
tex_coords.extend_from_slice(&face.tex_coords(
RIGHT_HANDED_Y_UP_CONFIG.u_flip_face,
true,
quad,
));
// 这里可以生成Data???? 但是怎么知道 是那个面的?
// 这里可以生成Data 但是怎么知道 是那个面的?
let index = <S as ConstShape<3>>::linearize(quad.minimum);

// 这里处理一下问题
if block_face_normal_index == 1 || block_face_normal_index == 4 {
match voxels[index as usize].direction.clone() {
VoxelDirection::Z => {
tex_coords.extend_from_slice(&[
[0.0, quad.height as f32],
[quad.width as f32, quad.height as f32],
[0.0, 0.0],
[quad.width as f32, 0.0],
]);
}
VoxelDirection::X => {
tex_coords.extend_from_slice(&[
[quad.width as f32, quad.height as f32],
[quad.width as f32, 0.0],
[0.0, quad.height as f32],
[0.0, 0.0],
]);
}
VoxelDirection::NZ => {
tex_coords.extend_from_slice(&[
[quad.width as f32, 0.0],
[0.0, 0.0],
[quad.width as f32, quad.height as f32],
[0.0, quad.height as f32],
]);
}
VoxelDirection::NX => {
tex_coords.extend_from_slice(&[
[0.0, 0.0],
[0.0, quad.height as f32],
[quad.width as f32, 0.0],
[quad.width as f32, quad.height as f32],
]);
}
}
} else {
tex_coords.extend_from_slice(&face.tex_coords(
RIGHT_HANDED_Y_UP_CONFIG.u_flip_face,
true,
quad,
));
}

// 法向量值
let normol_num = (block_face_normal_index as u32) << 8u32;
// 计算贴图索引
let txt_index = MaterailConfiguration::find_volex_index(
material_config.clone(),
block_face_normal_index as u8,
&voxels[index as usize].id,
voxels[index as usize].direction.clone(),
);
// todo 这里后面要知道是那个面的方便渲染

// 这里后面要知道是那个面的方便渲染
data.extend_from_slice(&[normol_num | (txt_index); 4]);
}
}
Expand Down Expand Up @@ -165,6 +206,7 @@ pub fn gen_mesh_water(voxels: Vec<Voxel>, material_config: MaterailConfiguration
material_config.clone(),
block_face_normal_index as u8,
&Water::ID,
VoxelDirection::Z,
);
data.extend_from_slice(&[normol_num | (txt_index); 4]);
}
Expand Down
33 changes: 30 additions & 3 deletions src/client/voxels/voxel_materail_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bevy_inspector_egui::prelude::*;
use serde::{Deserialize, Serialize};
use walkdir::WalkDir;

use crate::voxel_world::voxel::{Grass, Soli, Stone, VoxelMaterial};
use crate::voxel_world::voxel::{Grass, Soli, Stone, VoxelDirection, VoxelMaterial};

#[derive(Debug, Clone, Serialize, Deserialize, Default, Reflect, InspectorOptions)]
#[reflect(InspectorOptions)]
Expand Down Expand Up @@ -124,10 +124,17 @@ impl MaterailConfiguration {
}

// 通过面 和 体素类型获取 图片的索引
pub fn find_volex_index(self, normal: u8, volex_type: &u8) -> u32 {
pub fn find_volex_index(self, normal: u8, volex_type: &u8, direction: VoxelDirection) -> u32 {
let change_normal = match direction {
VoxelDirection::Z => rotate_times(normal, 0),
VoxelDirection::X => rotate_times(normal, 1),
VoxelDirection::NZ => rotate_times(normal, 2),
VoxelDirection::NX => rotate_times(normal, 3),
};

return match self.voxels.get(volex_type) {
Some(config) => {
return match config.normal.get(&normal) {
return match config.normal.get(&change_normal) {
Some(vconfig) => vconfig.index,
None => config.default.index,
};
Expand All @@ -136,3 +143,23 @@ impl MaterailConfiguration {
};
}
}

fn rotate_times(normal: u8, times: usize) -> u8 {
let mut ret = normal;
if times > 0 {
for _ in 0..times {
ret = rotate_half_pi(ret);
}
}
ret
}

fn rotate_half_pi(normal: u8) -> u8 {
return match normal {
0 => 5,
2 => 0,
3 => 2,
5 => 3,
_ => normal,
};
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ 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 = 16;
pub const MAX_TEXTURE_COUNT: usize = 22;
// 物体选择半径
pub const TOUCH_RADIUS: f32 = 5.;
pub const CLIENT_DEBUG: bool = false;
Expand Down
11 changes: 9 additions & 2 deletions src/server/async_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ pub fn deal_chunk_query_system(
warn!("基岩无法破坏");
continue;
}
if old_voxel.id != Voxel::EMPTY.id && voxel_type.id != Voxel::EMPTY.id {
if old_voxel.id != Voxel::EMPTY.id
&& voxel_type.id != Voxel::EMPTY.id
&& active_index != None
{
warn!("放置错误");
continue;
}
Expand All @@ -130,7 +133,11 @@ pub fn deal_chunk_query_system(
}
} else {
warn!("{}|角色没有当前生成的index", client_id);
continue;
if old_voxel.direction == voxel_type.direction {
continue;
} else {
println!("转动方向");
}
}
} else {
warn!("{}|{}没有找到资源对应关系", client_id, voxel_type.id);
Expand Down
98 changes: 95 additions & 3 deletions src/voxel_world/voxel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,47 @@ use serde::{Deserialize, Serialize};

/**
* 体素类型
*
* 这里要设计使用 u32的数据
* voxel_data >> 8u & 0b111 8位后的数据 9 10 11位置的数据
* voxel_data & 255u 表示取最后的8位
* 方块是否透明是否要记录呢?不用在数据库中,但是转回来的时候我要知道。并且可以生成对应的mesh在地图中
*
* 存储类型:
* 体素类型 方块方向
* [0-8] [9 10]
* todo 在某种情况下计算不同位置的 图片索引和贴图?
*
* 展示时的数据
* 贴图索引 法向量 方块方向
* [0-8] [9-11] [12 13]
*
* 是否可视等 是在其他地方定义的
*
*/
#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, Reflect, PartialEq, Eq, Hash)]
pub struct Voxel {
pub id: u8,
pub direction: VoxelDirection,
}

// 体素方向
#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize, Default, PartialEq, Eq, Hash)]
pub enum VoxelDirection {
#[default]
Z,
NZ, // 指向Z的负数半轴
X,
NX, // 指向X的负数半轴
}

pub const VOXEL_DIRECTION_VEC: [VoxelDirection; 4] = [
VoxelDirection::Z,
VoxelDirection::NZ,
VoxelDirection::X,
VoxelDirection::NX,
];

impl PartialOrd for Voxel {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.id.partial_cmp(&other.id)
Expand All @@ -23,8 +58,53 @@ impl Ord for Voxel {
}

impl Voxel {
pub const EMPTY: Self = Self { id: 0 };
pub const FILLED: Self = Self { id: 1 };
pub const EMPTY: Self = Self {
id: 0,
direction: VoxelDirection::Z,
};
pub const FILLED: Self = Self {
id: 1,
direction: VoxelDirection::Z,
};

// 转换成32位的存在类型
pub fn into_save_u32(&self) -> u32 {
let direction_base = match self.direction {
VoxelDirection::Z => 0u32 << 8u32,
VoxelDirection::NZ => 1u32 << 8u32,
VoxelDirection::X => 2u32 << 8u32,
VoxelDirection::NX => 3u32 << 8u32,
};
(self.id as u32) | direction_base
}

// u32 位置类型转换成 体素类型
pub fn u32_into_voxel(data: u32) -> Self {
Self {
id: Self::pick_id(data),
direction: Self::pick_direction(data),
}
}

pub fn pick_id(data: u32) -> u8 {
(data & 255u32) as u8
}

pub fn pick_direction(data: u32) -> VoxelDirection {
VOXEL_DIRECTION_VEC[(data >> 8u32 & 0b11) as usize]
}

pub fn next_direction(&self) -> Self {
Self {
id: self.id,
direction: match self.direction {
VoxelDirection::Z => VoxelDirection::X,
VoxelDirection::X => VoxelDirection::NZ,
VoxelDirection::NZ => VoxelDirection::NX,
VoxelDirection::NX => VoxelDirection::Z,
},
}
}
}

impl MeshVoxel for Voxel {
Expand All @@ -49,7 +129,18 @@ pub trait VoxelMaterial {
const ID: u8;

fn into_voxel() -> Voxel {
Voxel { id: Self::ID }
Voxel {
id: Self::ID,
..Default::default()
}
}

// 转化成 有方向的体素数据
fn into_voxel_with_dir(direction: VoxelDirection) -> Voxel {
Voxel {
id: Self::ID,
direction,
}
}
}

Expand Down Expand Up @@ -81,3 +172,4 @@ voxel_material!(DryGrass, 干草地, 8);
voxel_material!(BuleGrass, 苍翠地, 9);
voxel_material!(AppleWood, 苹果树原木, 10);
voxel_material!(AppleLeaf, 苹果树叶子, 11);
voxel_material!(TestCube, 测试方块, 12);
Loading

0 comments on commit f8956cd

Please sign in to comment.