Skip to content

Commit

Permalink
refactor player component and entity hierarchy, and add some document…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
meyerzinn committed May 17, 2023
1 parent 546c69d commit f1b4854
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 43 deletions.
109 changes: 71 additions & 38 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,57 +26,90 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
cmds.spawn((
/*
Lowercase denotes an entity, and uppercase denotes a component:
player
├── Player
├── TransformBundle
├── VisibilityBundle
├── body
│   └── BodyBundle
└── head
├── Head (marker)
├── TransformBundle (offsets the head from the player)
├── VisibilityBundle (camera needs to be child of a visible entity)
└── camera
├── AtmosphereCamera (cancels atmosphere translation)
├── Camera3dBundle
├── CameraMode (first or third person)
├── Fxaa
└── TransformBundle (moves camera w.r.t. head orientation)
*/

let visibility_bundle = || VisibilityBundle {
visibility: Visibility::Visible,
..default()
};

let player_bundle = (
player::Player,
VisibilityBundle {
visibility: Visibility::Visible,
..default()
},
visibility_bundle(),
TransformBundle {
local: Transform::from_xyz(2.0, 170.0, 2.0).looking_to(Vec3::Z, Vec3::Y),
..default()
},
))
.with_children(|player| {
player.spawn(player::Body).insert(MaterialMeshBundle {
);

let body_bundle = player::BodyBundle {
material_mesh_bundle: MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Box::new(0.5, 1.8, 0.5))),
material: materials.add(StandardMaterial {
base_color: Color::WHITE,
..default()
}),
transform: Transform::IDENTITY.looking_to(Vec3::Z, Vec3::Y),
..default()
});
},
..default()
};

player
.spawn((
player::Head,
TransformBundle {
// head is 1.8m above feet
local: Transform::from_translation(Vec3::new(0.0, 0.9, 0.0))
.looking_to(Vec3::Z, Vec3::Y),
..default()
},
))
.with_children(|head| {
// spawn camera as a child of head
head.spawn(Camera3dBundle {
projection: bevy::render::camera::Projection::Perspective(
PerspectiveProjection {
fov: PI / 2.,
far: 2048.0,
..Default::default()
},
),
transform: Transform::from_translation(Vec3::new(0.0, 0.0, -5.0))
.looking_to(Vec3::Z, Vec3::Y),
..Default::default()
})
.insert(CameraMode::ThirdPersonForward);
});
})
.insert(Fxaa::default())
.insert(bevy_atmosphere::plugin::AtmosphereCamera::default());
let head_bundle = (
player::Head,
visibility_bundle(),
TransformBundle {
// head is 1.8m above feet or 0.9m above the center
local: Transform::from_translation(Vec3::new(0.0, 0.9, 0.0))
.looking_to(Vec3::Z, Vec3::Y),
..default()
},
);

let camera_bundle = (
CameraMode::ThirdPersonForward,
visibility_bundle(),
Camera3dBundle {
projection: bevy::render::camera::Projection::Perspective(PerspectiveProjection {
fov: PI / 2.,
far: 2048.0,
..Default::default()
}),
transform: Transform::from_translation(Vec3::new(0.0, 0.0, -5.0))
.looking_to(Vec3::Z, Vec3::Y),
..default()
},
Fxaa::default(),
bevy_atmosphere::plugin::AtmosphereCamera::default(),
);

cmds.spawn(player_bundle).with_children(|player| {
player.spawn(body_bundle);

player.spawn(head_bundle).with_children(|head| {
// spawn camera as a child of head
head.spawn(camera_bundle);
});
});

cmds.insert_resource(AmbientLight {
color: Color::WHITE,
Expand Down
14 changes: 10 additions & 4 deletions src/voxel/world/chunks.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
use bevy::{
math::IVec3,
prelude::{
Changed, Commands, CoreSet, Entity, GlobalTransform, IntoSystemConfig, IntoSystemConfigs,
IntoSystemSetConfig, Plugin, Query, Res, ResMut, Resource, SystemSet, With,
Changed, Commands, Component, CoreSet, Entity, GlobalTransform, IntoSystemConfig,
IntoSystemConfigs, IntoSystemSetConfig, Plugin, Query, Res, ResMut, Resource, SystemSet,
With,
},
utils::{HashMap, HashSet},
};
use float_ord::FloatOrd;

use super::{player, Chunk, ChunkShape, CHUNK_LENGTH};
use super::{Chunk, ChunkShape, CHUNK_LENGTH};
use crate::voxel::storage::ChunkMap;
use crate::voxel::Voxel;

// @todo: should this contain a radius so that different entities could cause chunk loading in different ranges?
#[derive(Component, Default)]
/// Marker component for entities with a [GlobalTransform] which are tracked for the purpose of loading terrain.
pub struct LoadChunksAround;

/// Updates the current chunk position for the current player.
fn update_player_pos(
player: Query<&GlobalTransform, (With<player::Body>, Changed<GlobalTransform>)>,
player: Query<&GlobalTransform, (With<LoadChunksAround>, Changed<GlobalTransform>)>,
mut chunk_pos: ResMut<CurrentLocalPlayerChunk>,
) {
if let Ok(ply) = player.get_single() {
Expand Down
13 changes: 12 additions & 1 deletion src/voxel/world/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ use std::f32::consts::FRAC_PI_2;

use crate::debug::DebugUISet;

use super::chunks::LoadChunksAround;

const BODY_ROTATION_SLERP: f32 = 0.5;

#[derive(Component)]
pub struct Player;

#[derive(Bundle, Default)]
pub struct BodyBundle<M: Material> {
pub material_mesh_bundle: MaterialMeshBundle<M>,

// defaults are fine for these:
pub body: Body,
pub load_chunks_around: LoadChunksAround,
}

/// Marker component for player body.
#[derive(Component)]
#[derive(Component, Default)]
pub struct Body;

#[derive(Component)]
Expand Down

0 comments on commit f1b4854

Please sign in to comment.