height map generator
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
19
.vscode/launch.json
vendored
Normal file
19
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "cppvsdbg",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
// "console": "externalTerminal",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug",
|
||||||
|
"program": "${workspaceRoot}/target/debug/phos.exe",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"cmake.configureOnOpen": false
|
||||||
|
}
|
||||||
15
.vscode/tasks.json
vendored
Normal file
15
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks":[
|
||||||
|
{
|
||||||
|
"type":"cargo",
|
||||||
|
"command":"build",
|
||||||
|
"args":[],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"label":"build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
4361
Cargo.lock
generated
Normal file
4361
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[workspace]
|
||||||
|
|
||||||
|
members = [
|
||||||
|
"game/main",
|
||||||
|
"engine/world_generation"
|
||||||
|
]
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
|
# Enable a small amount of optimization in debug mode
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 1
|
||||||
|
|
||||||
|
# Enable high optimizations for dependencies (incl. Bevy), but not for our code:
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 3
|
||||||
9
engine/world_generation/Cargo.toml
Normal file
9
engine/world_generation/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "world_generation"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
noise = "0.9.0"
|
||||||
149
engine/world_generation/src/lib.rs
Normal file
149
engine/world_generation/src/lib.rs
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
|
||||||
|
use noise::{NoiseFn, SuperSimplex};
|
||||||
|
|
||||||
|
pub struct GenerationConfig {
|
||||||
|
pub noise_scale: f64,
|
||||||
|
pub sea_level: f64,
|
||||||
|
pub layers: Vec<GeneratorLayer>,
|
||||||
|
}
|
||||||
|
pub struct GeneratorLayer {
|
||||||
|
pub strength: f64,
|
||||||
|
pub min_value: f64,
|
||||||
|
pub base_roughness: f64,
|
||||||
|
pub roughness: f64,
|
||||||
|
pub persistence: f64,
|
||||||
|
pub is_rigid: bool,
|
||||||
|
pub weight: f64,
|
||||||
|
pub weight_multi: f64,
|
||||||
|
pub layers: usize,
|
||||||
|
pub first_layer_mask: bool,
|
||||||
|
}
|
||||||
|
pub struct Chunk {
|
||||||
|
pub points: Vec<f32>,
|
||||||
|
pub size: usize,
|
||||||
|
}
|
||||||
|
pub struct Map {
|
||||||
|
pub chunks: Vec<Chunk>,
|
||||||
|
pub height: usize,
|
||||||
|
pub width: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_heightmap(
|
||||||
|
height: usize,
|
||||||
|
width: usize,
|
||||||
|
cfg: &GenerationConfig,
|
||||||
|
seed: u32,
|
||||||
|
) -> Map {
|
||||||
|
let mut chunks: Vec<Chunk> = Vec::with_capacity(height * width);
|
||||||
|
for z in 0..height {
|
||||||
|
for x in 0..width {
|
||||||
|
chunks.push(generate_chunk(x as f64, z as f64, 32, cfg, seed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Map {
|
||||||
|
chunks: chunks,
|
||||||
|
height: height,
|
||||||
|
width: width,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_chunk(
|
||||||
|
chunk_x: f64,
|
||||||
|
chunk_z: f64,
|
||||||
|
size: usize,
|
||||||
|
cfg: &GenerationConfig,
|
||||||
|
seed: u32,
|
||||||
|
) -> Chunk {
|
||||||
|
let mut result: Vec<f32> = Vec::with_capacity(size * size);
|
||||||
|
let noise = SuperSimplex::new(seed);
|
||||||
|
for z in 0..size {
|
||||||
|
for x in 0..size {
|
||||||
|
result.push(sample_point(
|
||||||
|
x as f64 + chunk_x * size as f64,
|
||||||
|
z as f64 + chunk_z * size as f64,
|
||||||
|
&cfg,
|
||||||
|
&noise,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Chunk {
|
||||||
|
points: result,
|
||||||
|
size: size,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sample_point(x: f64, z: f64, cfg: &GenerationConfig, noise: &SuperSimplex) -> f32 {
|
||||||
|
let x_s = x / cfg.noise_scale;
|
||||||
|
let z_s = z / cfg.noise_scale;
|
||||||
|
|
||||||
|
let mut elevation: f64 = 0.;
|
||||||
|
let mut first_layer: f64 = 0.;
|
||||||
|
for i in 0..cfg.layers.len() {
|
||||||
|
let value: f64;
|
||||||
|
let layer = &cfg.layers[i];
|
||||||
|
if layer.is_rigid {
|
||||||
|
value = sample_rigid(x_s, z_s, layer, noise);
|
||||||
|
} else {
|
||||||
|
value = sample_simple(x_s, z_s, layer, noise);
|
||||||
|
}
|
||||||
|
if i == 0 {
|
||||||
|
first_layer = value;
|
||||||
|
}
|
||||||
|
if layer.first_layer_mask {
|
||||||
|
elevation += mask(first_layer, value, cfg.sea_level);
|
||||||
|
} else {
|
||||||
|
elevation += value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return elevation as f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mask(mask: f64, value: f64, sea_level: f64) -> f64 {
|
||||||
|
let m = (mask - sea_level).max(0.);
|
||||||
|
return value * m;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sample_simple(x: f64, z: f64, cfg: &GeneratorLayer, noise: &SuperSimplex) -> f64 {
|
||||||
|
let mut freq: f64 = cfg.base_roughness;
|
||||||
|
let mut amp: f64 = 1.;
|
||||||
|
let mut value = 0.;
|
||||||
|
|
||||||
|
for _ in 0..cfg.layers {
|
||||||
|
let v = noise.get([x * freq, z * freq]);
|
||||||
|
value += (v + 1.) * 0.5 * amp;
|
||||||
|
freq *= cfg.roughness;
|
||||||
|
amp *= cfg.persistence;
|
||||||
|
}
|
||||||
|
value -= cfg.min_value;
|
||||||
|
return value * cfg.strength;
|
||||||
|
}
|
||||||
|
fn sample_rigid(x: f64, z: f64, cfg: &GeneratorLayer, noise: &SuperSimplex) -> f64 {
|
||||||
|
let mut freq: f64 = cfg.base_roughness;
|
||||||
|
let mut amp: f64 = 1.;
|
||||||
|
let mut value = 0.;
|
||||||
|
let mut weight = 1.;
|
||||||
|
for _ in 0..cfg.layers {
|
||||||
|
let mut v = 1. - noise.get([x * freq, z * freq]).abs();
|
||||||
|
v *= v;
|
||||||
|
v *= weight;
|
||||||
|
weight = v * cfg.weight_multi;
|
||||||
|
weight = weight.clamp(0., 1.);
|
||||||
|
value += v * amp;
|
||||||
|
freq *= cfg.roughness;
|
||||||
|
amp *= cfg.persistence;
|
||||||
|
}
|
||||||
|
value -= cfg.min_value;
|
||||||
|
return value * cfg.strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn it_works() {
|
||||||
|
// let result = add(2, 2);
|
||||||
|
// assert_eq!(result, 4);
|
||||||
|
// }
|
||||||
|
}
|
||||||
6
engine/world_generation/src/mesh_generator.rs
Normal file
6
engine/world_generation/src/mesh_generator.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
mod lib;
|
||||||
|
use lib::Chunk;
|
||||||
|
|
||||||
|
pub fn generate_chunk_mesh(chunk: &Chunk){
|
||||||
|
|
||||||
|
}
|
||||||
11
game/main/Cargo.toml
Normal file
11
game/main/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "phos"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bevy = "0.13.0"
|
||||||
|
bevy-inspector-egui = "0.23.4"
|
||||||
|
noise = "0.8.2"
|
||||||
28
game/main/src/main.rs
Normal file
28
game/main/src/main.rs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
use bevy::{pbr::wireframe::WireframePlugin, prelude::*};
|
||||||
|
use bevy_inspector_egui::quick::WorldInspectorPlugin;
|
||||||
|
mod phos;
|
||||||
|
use phos::PhosGamePlugin;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
App::new()
|
||||||
|
.add_plugins((
|
||||||
|
DefaultPlugins.set(WindowPlugin {
|
||||||
|
primary_window: Some(Window {
|
||||||
|
title: "Phos".into(),
|
||||||
|
name: Some("phos".into()),
|
||||||
|
resolution: (1920.0, 1080.0).into(),
|
||||||
|
resizable: false,
|
||||||
|
enabled_buttons: bevy::window::EnabledButtons {
|
||||||
|
maximize: false,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
}),
|
||||||
|
..default()
|
||||||
|
}),
|
||||||
|
WireframePlugin,
|
||||||
|
WorldInspectorPlugin::new(),
|
||||||
|
PhosGamePlugin,
|
||||||
|
))
|
||||||
|
.run();
|
||||||
|
}
|
||||||
32
game/main/src/phos.rs
Normal file
32
game/main/src/phos.rs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
use bevy::{pbr::CascadeShadowConfig, prelude::*};
|
||||||
|
|
||||||
|
pub struct PhosGamePlugin;
|
||||||
|
|
||||||
|
impl Plugin for PhosGamePlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(Startup, init_game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_game(mut commands: Commands) {
|
||||||
|
commands.spawn((
|
||||||
|
Camera3dBundle {
|
||||||
|
transform: Transform::from_xyz(0., 50., 0.)
|
||||||
|
.looking_at(Vec3::new(50., 0., 50.), Vec3::Y),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
commands.spawn(DirectionalLightBundle {
|
||||||
|
directional_light: DirectionalLight {
|
||||||
|
shadows_enabled: false,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
cascade_shadow_config: CascadeShadowConfig {
|
||||||
|
bounds: vec![20., 40., 80., 1000., 5000., 19000., 20000.],
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
transform: Transform::from_xyz(0.0, 16.0, 5.).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
..default()
|
||||||
|
});
|
||||||
|
}
|
||||||
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
hard_tabs=true
|
||||||
Reference in New Issue
Block a user