rts camera
center camera spawn basic water fix generator config set camera bounds
This commit is contained in:
@@ -19,6 +19,7 @@ pub fn generate_heightmap(cfg: &GenerationConfig, seed: u32) -> Map {
|
|||||||
chunks,
|
chunks,
|
||||||
height: cfg.size.y as usize,
|
height: cfg.size.y as usize,
|
||||||
width: cfg.size.x as usize,
|
width: cfg.size.x as usize,
|
||||||
|
sea_level: cfg.sea_level as f32,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,12 +41,8 @@ pub fn generate_chunk(chunk_x: f64, chunk_z: f64, cfg: &GenerationConfig, seed:
|
|||||||
(x as f64 + chunk_x * Chunk::SIZE as f64) / &cfg.noise_scale,
|
(x as f64 + chunk_x * Chunk::SIZE as f64) / &cfg.noise_scale,
|
||||||
(z as f64 + chunk_z * Chunk::SIZE as f64) / &cfg.noise_scale,
|
(z as f64 + chunk_z * Chunk::SIZE as f64) / &cfg.noise_scale,
|
||||||
]) as f32;
|
]) as f32;
|
||||||
temp[x + z * Chunk::SIZE] = sample_tempurature(
|
temp[x + z * Chunk::SIZE] =
|
||||||
z as f32 + chunk_z as f32 * Chunk::SIZE as f32,
|
sample_tempurature(z as f32 + chunk_z as f32 * Chunk::SIZE as f32, sample, &cfg, 100.);
|
||||||
sample,
|
|
||||||
&cfg,
|
|
||||||
100.,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Chunk {
|
return Chunk {
|
||||||
@@ -95,10 +92,7 @@ fn sample_point(x: f64, z: f64, cfg: &GenerationConfig, noise: &impl NoiseFn<f64
|
|||||||
let d1 = p.x.min(p.y);
|
let d1 = p.x.min(p.y);
|
||||||
let od = outer - p;
|
let od = outer - p;
|
||||||
let d2 = od.x.min(od.y);
|
let d2 = od.x.min(od.y);
|
||||||
let d = d1
|
let d = d1.min(d2).min(cfg.border_size).remap(0., cfg.border_size, 0., 1.);
|
||||||
.min(d2)
|
|
||||||
.min(cfg.border_size)
|
|
||||||
.remap(0., cfg.border_size, 0., 1.);
|
|
||||||
|
|
||||||
return (elevation as f32) * d;
|
return (elevation as f32) * d;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pub mod tile_manager;
|
|||||||
pub mod tile_mapper;
|
pub mod tile_mapper;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
use crate::hex_utils::{HexCoord, INNER_RADIUS, OUTER_RADIUS};
|
use crate::hex_utils::{tile_to_world_distance, HexCoord, INNER_RADIUS, OUTER_RADIUS};
|
||||||
use bevy::math::{IVec2, UVec2, Vec2, Vec3};
|
use bevy::math::{IVec2, UVec2, Vec2, Vec3};
|
||||||
use bevy::prelude::Resource;
|
use bevy::prelude::Resource;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
@@ -84,6 +84,7 @@ pub mod prelude {
|
|||||||
pub chunks: Vec<Chunk>,
|
pub chunks: Vec<Chunk>,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
|
pub sea_level: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Map {
|
impl Map {
|
||||||
@@ -105,7 +106,7 @@ pub mod prelude {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_height(&self, pos: &HexCoord) -> f32 {
|
pub fn sample_height(&self, pos: &HexCoord) -> f32 {
|
||||||
let chunk = &self.chunks[pos.to_chunk_index(self.width)];
|
let chunk = &self.chunks[pos.to_chunk_index(self.width)];
|
||||||
return chunk.heights[pos.to_chunk_local_index()];
|
return chunk.heights[pos.to_chunk_local_index()];
|
||||||
}
|
}
|
||||||
@@ -119,6 +120,23 @@ pub mod prelude {
|
|||||||
let chunk = &self.chunks[pos.to_chunk_index(self.width)];
|
let chunk = &self.chunks[pos.to_chunk_index(self.width)];
|
||||||
return chunk.temperature[pos.to_chunk_local_index()];
|
return chunk.temperature[pos.to_chunk_local_index()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_center(&self) -> Vec3 {
|
||||||
|
let w = self.width * Chunk::SIZE;
|
||||||
|
let h = self.height * Chunk::SIZE;
|
||||||
|
return Vec3::new(
|
||||||
|
tile_to_world_distance(w as i32 / 2),
|
||||||
|
self.sea_level,
|
||||||
|
tile_to_world_distance(h as i32 / 2),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_world_width(&self) -> f32 {
|
||||||
|
return tile_to_world_distance((self.width * Chunk::SIZE) as i32);
|
||||||
|
}
|
||||||
|
pub fn get_world_height(&self) -> f32 {
|
||||||
|
return tile_to_world_distance((self.height * Chunk::SIZE) as i32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub const ATTRIBUTE_PACKED_VERTEX_DATA: MeshVertexAttribute =
|
pub const ATTRIBUTE_PACKED_VERTEX_DATA: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("PackedVertexData", 988540817, VertexFormat::Uint32);
|
MeshVertexAttribute::new("PackedVertexData", 988540817, VertexFormat::Uint32);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use crate::prelude::PhosCamera;
|
use crate::prelude::PhosCamera;
|
||||||
use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin};
|
use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin};
|
||||||
use bevy::input::mouse::MouseMotion;
|
use bevy::input::mouse::{MouseMotion, MouseScrollUnit, MouseWheel};
|
||||||
use bevy::pbr::ScreenSpaceAmbientOcclusionBundle;
|
use bevy::pbr::ScreenSpaceAmbientOcclusionBundle;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::window::CursorGrabMode;
|
use bevy::window::CursorGrabMode;
|
||||||
|
use prelude::{CameraBounds, PhosCameraTargets};
|
||||||
|
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
||||||
@@ -11,8 +12,12 @@ pub struct PhosCameraPlugin;
|
|||||||
|
|
||||||
impl Plugin for PhosCameraPlugin {
|
impl Plugin for PhosCameraPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(Startup, setup)
|
app.add_systems(PreStartup, setup);
|
||||||
.add_systems(Update, (grab_mouse, (update_camera, update_camera_mouse).chain()));
|
|
||||||
|
app.add_systems(Update, (rts_camera_system, apply_camera_height).chain());
|
||||||
|
app.add_systems(PostUpdate, limit_camera_bounds);
|
||||||
|
//Free Cam
|
||||||
|
//app.add_systems(Update, (grab_mouse, (update_camera, update_camera_mouse).chain()));
|
||||||
|
|
||||||
app.add_plugins(TemporalAntiAliasPlugin);
|
app.add_plugins(TemporalAntiAliasPlugin);
|
||||||
}
|
}
|
||||||
@@ -22,13 +27,16 @@ fn setup(mut commands: Commands, mut msaa: ResMut<Msaa>) {
|
|||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Camera3dBundle {
|
Camera3dBundle {
|
||||||
transform: Transform::from_xyz(0., 30., 0.).looking_at(Vec3::new(1000., 0., 1000.), Vec3::Y),
|
transform: Transform::from_xyz(0., 30., 0.)
|
||||||
|
.with_rotation(Quat::from_axis_angle(Vec3::Y, (-90 as f32).to_radians())),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
PhosCamera {
|
PhosCamera {
|
||||||
speed: 100.,
|
speed: 100.,
|
||||||
|
zoom_speed: 20.,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
PhosCameraTargets::default(),
|
||||||
))
|
))
|
||||||
.insert(ScreenSpaceAmbientOcclusionBundle::default())
|
.insert(ScreenSpaceAmbientOcclusionBundle::default())
|
||||||
.insert(TemporalAntiAliasBundle::default());
|
.insert(TemporalAntiAliasBundle::default());
|
||||||
@@ -119,17 +127,18 @@ fn grab_mouse(mut windows: Query<&mut Window>, mouse: Res<ButtonInput<MouseButto
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rts_camera_system(
|
fn rts_camera_system(
|
||||||
mut cam_query: Query<(&mut Transform, &PhosCamera)>,
|
mut cam_query: Query<(&mut Transform, &PhosCamera, &mut PhosCameraTargets)>,
|
||||||
key: Res<ButtonInput<KeyCode>>,
|
key: Res<ButtonInput<KeyCode>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
|
mut wheel: EventReader<MouseWheel>,
|
||||||
) {
|
) {
|
||||||
let (mut cam, cam_cfg) = cam_query.single_mut();
|
let (mut cam, cam_cfg, mut cam_targets) = cam_query.single_mut();
|
||||||
let mut cam_move = Vec3::ZERO;
|
let mut cam_move = Vec3::ZERO;
|
||||||
|
|
||||||
if key.pressed(KeyCode::KeyA) {
|
if key.pressed(KeyCode::KeyA) {
|
||||||
cam_move.x = -1.;
|
|
||||||
} else if key.pressed(KeyCode::KeyD) {
|
|
||||||
cam_move.x = 1.;
|
cam_move.x = 1.;
|
||||||
|
} else if key.pressed(KeyCode::KeyD) {
|
||||||
|
cam_move.x = -1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
if key.pressed(KeyCode::KeyW) {
|
if key.pressed(KeyCode::KeyW) {
|
||||||
@@ -138,5 +147,30 @@ fn rts_camera_system(
|
|||||||
cam_move.z = -1.;
|
cam_move.z = -1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
cam.translation += cam_move.normalize() * cam_cfg.speed * time.delta_seconds();
|
let fwd = cam.forward();
|
||||||
|
let fwd_quat = Quat::from_rotation_arc(Vec3::Z, fwd.into());
|
||||||
|
cam_move = fwd_quat.mul_vec3(cam_move.normalize_or_zero()) * cam_cfg.speed * time.delta_seconds();
|
||||||
|
|
||||||
|
for e in wheel.read() {
|
||||||
|
match e.unit {
|
||||||
|
MouseScrollUnit::Line => cam_targets.height -= e.y * 20.,
|
||||||
|
MouseScrollUnit::Pixel => cam_targets.height -= e.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cam_targets.height = cam_targets.height.clamp(cam_cfg.min_height, cam_cfg.max_height);
|
||||||
|
|
||||||
|
cam.translation += cam_move;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_camera_height(mut cam_query: Query<(&mut Transform, &PhosCamera, &mut PhosCameraTargets)>, time: Res<Time>) {
|
||||||
|
let (mut cam_t, cam_cfg, targets) = cam_query.single_mut();
|
||||||
|
|
||||||
|
let movement = (cam_t.translation.y - targets.height) * time.delta_seconds();
|
||||||
|
|
||||||
|
cam_t.translation.y -= movement;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn limit_camera_bounds(mut cam_query: Query<(&mut Transform, &CameraBounds)>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,44 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
#[derive(Component, Default)]
|
#[derive(Component)]
|
||||||
pub struct PhosCamera {
|
pub struct PhosCamera {
|
||||||
pub min_height: f32,
|
pub min_height: f32,
|
||||||
pub max_height: f32,
|
pub max_height: f32,
|
||||||
pub speed: f32,
|
pub speed: f32,
|
||||||
pub zoom_speed: f32,
|
pub zoom_speed: f32,
|
||||||
|
pub min_angle: f32,
|
||||||
|
pub max_angle: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for PhosCamera {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
min_height: 10.,
|
||||||
|
max_height: 100.,
|
||||||
|
speed: 20.,
|
||||||
|
zoom_speed: 20.,
|
||||||
|
min_angle: 10.,
|
||||||
|
max_angle: 80.,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
pub struct PhosCameraTargets {
|
||||||
|
pub height: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
pub struct CameraBounds {
|
pub struct CameraBounds {
|
||||||
pub min: Vec2,
|
pub min: Vec2,
|
||||||
pub max: Vec2,
|
pub max: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CameraBounds {
|
||||||
|
pub fn from_size(size: UVec2) -> Self {
|
||||||
|
return Self {
|
||||||
|
min: Vec2::ZERO,
|
||||||
|
max: size.as_vec2(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use bevy::{asset::LoadState, pbr::ExtendedMaterial, prelude::*};
|
use bevy::{asset::LoadState, pbr::ExtendedMaterial, prelude::*};
|
||||||
use bevy_inspector_egui::quick::ResourceInspectorPlugin;
|
use bevy_inspector_egui::quick::ResourceInspectorPlugin;
|
||||||
use bevy_rapier3d::geometry::{Collider, TriMeshFlags};
|
use bevy_rapier3d::geometry::{Collider, TriMeshFlags};
|
||||||
use camera_system::prelude::PhosCamera;
|
use camera_system::prelude::{CameraBounds, PhosCamera};
|
||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
use world_generation::{
|
use world_generation::{
|
||||||
biome_painter::*,
|
biome_painter::*,
|
||||||
@@ -29,7 +29,8 @@ impl Plugin for MapInitPlugin {
|
|||||||
ResourceInspectorPlugin::<GenerationConfig>::default(),
|
ResourceInspectorPlugin::<GenerationConfig>::default(),
|
||||||
));
|
));
|
||||||
|
|
||||||
app.add_systems(Startup, (load_textures, load_tiles, create_map));
|
app.add_systems(Startup, (load_textures, load_tiles));
|
||||||
|
app.add_systems(PostStartup, create_map);
|
||||||
|
|
||||||
app.add_systems(Update, finalize_texture);
|
app.add_systems(Update, finalize_texture);
|
||||||
app.add_systems(PostUpdate, (despawn_map, spawn_map).chain());
|
app.add_systems(PostUpdate, (despawn_map, spawn_map).chain());
|
||||||
@@ -87,13 +88,13 @@ fn finalize_texture(
|
|||||||
map.regenerate = true;
|
map.regenerate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_map(mut commands: Commands, mut cam: Query<&mut Transform, With<PhosCamera>>) {
|
fn create_map(mut commands: Commands, mut cam: Query<(&mut Transform, Entity), With<PhosCamera>>) {
|
||||||
let config = GenerationConfig {
|
let config = GenerationConfig {
|
||||||
layers: vec![
|
layers: vec![
|
||||||
GeneratorLayer {
|
GeneratorLayer {
|
||||||
base_roughness: 2.14,
|
base_roughness: 2.14,
|
||||||
roughness: 0.87,
|
roughness: 0.87,
|
||||||
strength: 2.93,
|
strength: 8.3,
|
||||||
min_value: -0.2,
|
min_value: -0.2,
|
||||||
persistence: 0.77,
|
persistence: 0.77,
|
||||||
is_rigid: false,
|
is_rigid: false,
|
||||||
@@ -117,7 +118,7 @@ fn create_map(mut commands: Commands, mut cam: Query<&mut Transform, With<PhosCa
|
|||||||
GeneratorLayer {
|
GeneratorLayer {
|
||||||
base_roughness: 2.6,
|
base_roughness: 2.6,
|
||||||
roughness: 4.,
|
roughness: 4.,
|
||||||
strength: 4.3,
|
strength: 3.1,
|
||||||
min_value: 0.,
|
min_value: 0.,
|
||||||
persistence: 1.57,
|
persistence: 1.57,
|
||||||
is_rigid: true,
|
is_rigid: true,
|
||||||
@@ -148,7 +149,7 @@ fn create_map(mut commands: Commands, mut cam: Query<&mut Transform, With<PhosCa
|
|||||||
weight: 1.,
|
weight: 1.,
|
||||||
weight_multi: 4.57,
|
weight_multi: 4.57,
|
||||||
layers: 3,
|
layers: 3,
|
||||||
first_layer_mask: true,
|
first_layer_mask: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
noise_scale: 450.,
|
noise_scale: 450.,
|
||||||
@@ -161,12 +162,14 @@ fn create_map(mut commands: Commands, mut cam: Query<&mut Transform, With<PhosCa
|
|||||||
|
|
||||||
commands.insert_resource(heightmap);
|
commands.insert_resource(heightmap);
|
||||||
|
|
||||||
// let mut cam_t = cam.single_mut();
|
let (mut cam_t, cam_entity) = cam.single_mut();
|
||||||
// cam_t.translation = Vec3::new(
|
cam_t.translation = Vec3::new(
|
||||||
// tile_to_world_distance(config.size.x as i32 / 2),
|
tile_to_world_distance((config.size.x as i32 * Chunk::SIZE as i32) / 2),
|
||||||
// cam_t.translation.y,
|
cam_t.translation.y,
|
||||||
// tile_to_world_distance(config.size.y as i32 / 2),
|
tile_to_world_distance((config.size.y as i32 * Chunk::SIZE as i32) / 2),
|
||||||
// );
|
);
|
||||||
|
|
||||||
|
commands.entity(cam_entity).insert(CameraBounds::from_size(config.size));
|
||||||
|
|
||||||
commands.insert_resource(config);
|
commands.insert_resource(config);
|
||||||
}
|
}
|
||||||
@@ -174,7 +177,8 @@ fn create_map(mut commands: Commands, mut cam: Query<&mut Transform, With<PhosCa
|
|||||||
fn spawn_map(
|
fn spawn_map(
|
||||||
heightmap: Res<Map>,
|
heightmap: Res<Map>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, ChunkMaterial>>>,
|
mut chunk_materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, ChunkMaterial>>>,
|
||||||
|
mut standard_materials: ResMut<Assets<StandardMaterial>>,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
atlas: Res<ChunkAtlas>,
|
atlas: Res<ChunkAtlas>,
|
||||||
mut map: ResMut<PhosMap>,
|
mut map: ResMut<PhosMap>,
|
||||||
@@ -188,7 +192,7 @@ fn spawn_map(
|
|||||||
}
|
}
|
||||||
let b_painter = biome_painters.get(painter.0.clone());
|
let b_painter = biome_painters.get(painter.0.clone());
|
||||||
map.regenerate = false;
|
map.regenerate = false;
|
||||||
let chunk_material = materials.add(ExtendedMaterial {
|
let chunk_material = chunk_materials.add(ExtendedMaterial {
|
||||||
base: StandardMaterial::default(),
|
base: StandardMaterial::default(),
|
||||||
extension: ChunkMaterial {
|
extension: ChunkMaterial {
|
||||||
array_texture: atlas.handle.clone(),
|
array_texture: atlas.handle.clone(),
|
||||||
@@ -228,6 +232,17 @@ fn spawn_map(
|
|||||||
Collider::trimesh_with_flags(col_verts, col_indicies, TriMeshFlags::MERGE_DUPLICATE_VERTICES),
|
Collider::trimesh_with_flags(col_verts, col_indicies, TriMeshFlags::MERGE_DUPLICATE_VERTICES),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commands.spawn((PbrBundle {
|
||||||
|
transform: Transform::from_translation(heightmap.get_center()),
|
||||||
|
mesh: meshes.add(Plane3d::default().mesh().size(heightmap.get_world_width(), heightmap.get_world_height())),
|
||||||
|
material: standard_materials.add(StandardMaterial {
|
||||||
|
base_color: Color::AQUAMARINE.with_a(0.5),
|
||||||
|
alpha_mode: AlphaMode::Blend,
|
||||||
|
..default()
|
||||||
|
}),
|
||||||
|
..default()
|
||||||
|
},));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn despawn_map(
|
fn despawn_map(
|
||||||
|
|||||||
Reference in New Issue
Block a user