Skip to content

Commit

Permalink
fix-处理问题可以掉入地形内部的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
zzhgithub committed Sep 5, 2023
1 parent 165c0c9 commit 4eed844
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 23 deletions.
4 changes: 3 additions & 1 deletion src/bin/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ use just_join::{
common::ServerClipSpheresPlugin,
connection_config,
server::{
async_chunk::ChunkDataPlugin, chunk::ServerChunkPlugin, deal_message_system,
async_chunk::ChunkDataPlugin, chunk::ServerChunkPlugin,
cross_through_check::CossTroughCheckPlugin, deal_message_system,
object_filing::ObjectFilingPlugin, player::ServerLobby, server_connect_system,
staff_rule_sync::ServerStaffRulePlugin, sync_body_and_head,
terrain_physics::TerrainPhysicsPlugin,
Expand Down Expand Up @@ -117,6 +118,7 @@ fn main() {
ServerSkyPlugins,
ObjectFilingPlugin,
ServerStaffRulePlugin,
CossTroughCheckPlugin,
));

let (server, transport) = new_renet_server();
Expand Down
6 changes: 4 additions & 2 deletions src/client/player/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use bevy::{
use bevy_egui::EguiSet;
use bevy_renet::renet::RenetClient;

use crate::client::{ state_manager::GameState, message_def::{player_input::PlayerInput, ClientChannel},
use crate::client::{
message_def::{player_input::PlayerInput, ClientChannel},
state_manager::GameState,
};

use super::{
Expand Down Expand Up @@ -138,7 +140,7 @@ fn initial_grab_cursor(mut primary_window: Query<&mut Window, With<PrimaryWindow
}
}

fn back_grab_cursor(mut primary_window: Query<&mut Window, With<PrimaryWindow>>) {
pub fn back_grab_cursor(mut primary_window: Query<&mut Window, With<PrimaryWindow>>) {
if let Ok(mut window) = primary_window.get_single_mut() {
{
window.cursor.grab_mode = CursorGrabMode::None;
Expand Down
15 changes: 9 additions & 6 deletions src/client/state_manager/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ use bevy::{
use bevy_egui::{egui, EguiContext, EguiContexts, EguiUserTextures};

use crate::{
client::ui::{
test::toggle_ui,
tool_bar::{tool_bar, ToolBar},
tool_box::tool_box,
UiPicResourceManager,
client::{
player::controller::back_grab_cursor,
ui::{
test::toggle_ui,
tool_bar::{tool_bar, ToolBar},
tool_box::tool_box,
UiPicResourceManager,
},
},
staff::StaffInfoStroge,
tools::string::{is_port, is_valid_server_address},
Expand All @@ -40,7 +43,7 @@ impl Plugin for MenuPlugin {
app.add_state::<MenuState>();
app.insert_resource(TestResource::default());
app.insert_resource(ToolBar::default());
app.add_systems(OnEnter(GameState::Menu), setup);
app.add_systems(OnEnter(GameState::Menu), (setup, back_grab_cursor));
app.add_systems(Update, menu_main.run_if(in_state(MenuState::Main)));
app.add_systems(Update, test.run_if(in_state(MenuState::Test)));
app.add_systems(
Expand Down
79 changes: 79 additions & 0 deletions src/server/cross_through_check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// 穿透检查

use bevy::prelude::{
Commands, Component, Entity, Plugin, PreUpdate, Query, Res, ResMut, Transform, Update, Vec3,
Without,
};
use bevy_rapier3d::{
prelude::{RapierContext, RapierRigidBodyHandle},
rapier::prelude::RigidBodyType,
};

use crate::{
tools::{chunk_key_any_xyz_to_vec3, pos_to_center, vec3_to_chunk_key_any_xyz},
voxel_world::{chunk_map::ChunkMap, voxel::Voxel},
};

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

#[derive(Debug, Clone, Copy, Component)]
pub struct CossTroughFixed(Vec3);

pub struct CossTroughCheckPlugin;

impl Plugin for CossTroughCheckPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_systems(PreUpdate, cross_through_check);
app.add_systems(Update, cross_through_fixed);
}
}

fn cross_through_check(
mut commands: Commands,
mut context: ResMut<RapierContext>,
query: Query<
(Entity, &RapierRigidBodyHandle, &Transform, &CossTroughCheck),
Without<CossTroughFixed>,
>,
chunk_map: Res<ChunkMap>,
) {
for (entity, body_handle, trf, _) in query.iter() {
let (chunk_key, xyz) = vec3_to_chunk_key_any_xyz(pos_to_center(trf.translation));
if let Some(test_voxel) = chunk_map.get_block(chunk_key, xyz) {
if test_voxel.id != Voxel::EMPTY.id {
if let Some((new_chunk_key, new_xyz)) =
chunk_map.find_closest_block_y(chunk_key, xyz, Voxel::EMPTY.id)
{
if let Some(body) = context.bodies.get_mut(body_handle.0) {
body.set_body_type(RigidBodyType::KinematicPositionBased, true);
let mut pos = chunk_key_any_xyz_to_vec3(new_chunk_key, new_xyz);
pos.x = trf.translation.x;
pos.z = trf.translation.z;
commands.entity(entity).insert(CossTroughFixed(pos));
}
}
}
}
}
}

fn cross_through_fixed(
mut commands: Commands,
mut context: ResMut<RapierContext>,
mut query: Query<(
Entity,
&RapierRigidBodyHandle,
&mut Transform,
&CossTroughFixed,
)>,
) {
for (entity, body_handle, mut trf, fixed) in query.iter_mut() {
if let Some(body) = context.bodies.get_mut(body_handle.0) {
// println!("修复了物体 to {}", fixed.0);
trf.translation = fixed.0;
body.set_body_type(RigidBodyType::Dynamic, true);
commands.entity(entity).remove::<CossTroughFixed>();
}
}
}
1 change: 1 addition & 0 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use self::{

pub mod async_chunk;
pub mod chunk;
pub mod cross_through_check;
pub mod message_def;
pub mod object_filing;
pub mod player;
Expand Down
33 changes: 19 additions & 14 deletions src/server/object_filing/follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use seldom_state::{

use crate::{
server::{
cross_through_check::CossTroughCheck,
message_def::{tool_bar_message::ToolBarMessage, ServerChannel},
player::Player,
},
Expand Down Expand Up @@ -135,21 +136,25 @@ fn load_up_state_machine(
query: Query<(Entity, &FilledObject), (Without<StateMachine>, Without<ThrowObject>)>,
) {
for (entity, _) in query.iter() {
commands.entity(entity).insert(Idle).insert(
StateMachine::default()
.trans_builder(Near { range: NEAR_RANGE }, |_: &Idle, entity: Entity| {
Some(Follow {
target: entity,
speed: PICK_SPEED,
commands
.entity(entity)
.insert(CossTroughCheck)
.insert(Idle)
.insert(
StateMachine::default()
.trans_builder(Near { range: NEAR_RANGE }, |_: &Idle, entity: Entity| {
Some(Follow {
target: entity,
speed: PICK_SPEED,
})
})
})
.trans::<Follow>(Near { range: NEAR_RANGE }.not(), Idle)
.trans_builder(CloseTo { range: CLOSE_RANGE }, |follow: &Follow, _| {
Some(Picked {
target: follow.target,
})
}),
);
.trans::<Follow>(Near { range: NEAR_RANGE }.not(), Idle)
.trans_builder(CloseTo { range: CLOSE_RANGE }, |follow: &Follow, _| {
Some(Picked {
target: follow.target,
})
}),
);
}
}

Expand Down
21 changes: 21 additions & 0 deletions src/tools/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,24 @@ pub fn vec3_to_chunk_key_any_xyz(pos: Vec3) -> (ChunkKey, [u32; 3]) {

(chunk_key, [x, y, z])
}

// chunkKey和x y z坐标 还原到 Cube的中心位置
pub fn chunk_key_any_xyz_to_vec3(chunk_key: ChunkKey, xyz: [u32; 3]) -> Vec3 {
let x =
(chunk_key.0.x as f32) * (CHUNK_SIZE as f32) - CHUNK_SIZE as f32 / 2. + xyz[0] as f32 + 0.5;
let y =
(chunk_key.0.y as f32) * (CHUNK_SIZE as f32) - CHUNK_SIZE as f32 / 2. + xyz[1] as f32 + 0.5;
let z =
(chunk_key.0.z as f32) * (CHUNK_SIZE as f32) - CHUNK_SIZE as f32 / 2. + xyz[2] as f32 + 0.5;
Vec3::new(x, y, z)
}

// 计算点所在的 方块终点是什么
pub fn pos_to_center(pos: Vec3) -> Vec3 {
let res = Vec3 {
x: pos.x.floor(),
y: pos.y.floor(),
z: pos.z.floor(),
};
res + Vec3::splat(0.5)
}
39 changes: 39 additions & 0 deletions src/voxel_world/chunk_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,45 @@ impl ChunkMap {
Self { map_data: data_map }
}

// 获取某个位置的方块
pub fn get_block(&self, chunk_key: ChunkKey, xyz: [u32; 3]) -> Option<Voxel> {
type DataShape = ConstShape3u32<CHUNK_SIZE_U32, CHUNK_SIZE_U32, CHUNK_SIZE_U32>;
let index = DataShape::linearize(xyz) as usize;
if let Some(voxels) = self.get(chunk_key) {
return Some(voxels[index]);
}
None
}

// 寻找y轴上最进的数据
pub fn find_closest_block_y(
&self,
chunk_key: ChunkKey,
xyz: [u32; 3],
id: u8,
) -> Option<(ChunkKey, [u32; 3])> {
type DataShape = ConstShape3u32<CHUNK_SIZE_U32, CHUNK_SIZE_U32, CHUNK_SIZE_U32>;
for chunk_y in chunk_key.0.y..=128 / CHUNK_SIZE {
let start = if chunk_y == chunk_key.0.y { xyz[1] } else { 0 };
let new_chunk_key = ChunkKey(IVec3 {
x: chunk_key.0.x,
y: chunk_y,
z: chunk_key.0.z,
});
if let Some(chunk_data) = self.get(new_chunk_key) {
for y in start..CHUNK_SIZE_U32 {
let pos = [xyz[0], y, xyz[2]];
let index = DataShape::linearize(pos);
let data = chunk_data[index as usize];
if data.id == id {
return Some((new_chunk_key, pos));
}
}
}
}
None
}

pub fn chunk_for_mesh_ready(&self, chunk_key: ChunkKey) -> bool {
let px = &IVec3::new(1, 0, 0);
let nx = &IVec3::new(-1, 0, 0);
Expand Down

0 comments on commit 4eed844

Please sign in to comment.