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

Feature support more mesh #82

Merged
merged 2 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading