mesh generation
This commit is contained in:
@@ -6,4 +6,5 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bevy = "0.13.1"
|
||||
noise = "0.9.0"
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
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,
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
mod data;
|
||||
use data::*;
|
||||
use crate::prelude::*;
|
||||
use bevy::math::IVec2;
|
||||
use noise::{NoiseFn, SuperSimplex};
|
||||
|
||||
pub fn generate_heightmap(
|
||||
height: usize,
|
||||
width: usize,
|
||||
cfg: &GenerationConfig,
|
||||
seed: u32,
|
||||
) -> Map {
|
||||
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 {
|
||||
@@ -42,6 +38,7 @@ pub fn generate_chunk(
|
||||
return Chunk {
|
||||
points: result,
|
||||
size: size,
|
||||
chunk_offset: IVec2::new(chunk_x as i32, chunk_z as i32),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -108,4 +105,4 @@ fn sample_rigid(x: f64, z: f64, cfg: &GeneratorLayer, noise: &SuperSimplex) -> f
|
||||
}
|
||||
value -= cfg.min_value;
|
||||
return value * cfg.strength;
|
||||
}
|
||||
}
|
||||
|
||||
10
engine/world_generation/src/hex_utils.rs
Normal file
10
engine/world_generation/src/hex_utils.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub const OUTER_RADIUS: f32 = 1.;
|
||||
pub const INNER_RADIUS: f32 = OUTER_RADIUS * 0.866025404;
|
||||
|
||||
|
||||
pub fn to_hex_pos(pos: Vec3) -> Vec3 {
|
||||
let x = (pos.x + pos.z * 0.5 - (pos.z / 2.).floor()) * (INNER_RADIUS * 2.);
|
||||
return Vec3::new(x, pos.y, pos.z * OUTER_RADIUS * 1.5);
|
||||
}
|
||||
@@ -1,9 +1,38 @@
|
||||
pub mod prelude {
|
||||
use bevy::math::IVec2;
|
||||
|
||||
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 chunk_offset: IVec2,
|
||||
}
|
||||
pub struct Map {
|
||||
pub chunks: Vec<Chunk>,
|
||||
pub height: usize,
|
||||
pub width: usize,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pub mod heightmap;
|
||||
pub mod hex_utils;
|
||||
pub mod mesh_generator;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -1,6 +1,73 @@
|
||||
mod data;
|
||||
use data::Chunk;
|
||||
use crate::{
|
||||
hex_utils::{to_hex_pos, INNER_RADIUS, OUTER_RADIUS},
|
||||
prelude::*,
|
||||
};
|
||||
use bevy::{
|
||||
prelude::*,
|
||||
render::{
|
||||
mesh::{Indices, PrimitiveTopology},
|
||||
render_asset::RenderAssetUsages,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn generate_chunk_mesh(chunk: &Chunk){
|
||||
const HEX_CORNERS: [Vec3; 6] = [
|
||||
Vec3::new(0., 0., OUTER_RADIUS),
|
||||
Vec3::new(INNER_RADIUS, 0., 0.5 * OUTER_RADIUS),
|
||||
Vec3::new(INNER_RADIUS, 0., -0.5 * OUTER_RADIUS),
|
||||
Vec3::new(0., 0., -OUTER_RADIUS),
|
||||
Vec3::new(-INNER_RADIUS, 0., -0.5 * OUTER_RADIUS),
|
||||
Vec3::new(-INNER_RADIUS, 0., 0.5 * OUTER_RADIUS),
|
||||
];
|
||||
|
||||
}
|
||||
pub fn generate_chunk_mesh(chunk: &Chunk) -> Mesh {
|
||||
let vertex_count: usize = chunk.size * chunk.size;
|
||||
let mut verts = Vec::with_capacity(vertex_count);
|
||||
let mut uvs = Vec::with_capacity(vertex_count);
|
||||
let mut normals = Vec::with_capacity(vertex_count);
|
||||
let mut indices = Vec::with_capacity(vertex_count);
|
||||
|
||||
for z in 0..chunk.size {
|
||||
for x in 0..chunk.size {
|
||||
let height = chunk.points[x + z * chunk.size];
|
||||
let off_pos = Vec3::new(x as f32, height, z as f32);
|
||||
let grid_pos = to_hex_pos(off_pos);
|
||||
create_tile(grid_pos, &mut verts, &mut uvs, &mut normals, &mut indices);
|
||||
}
|
||||
}
|
||||
|
||||
let mesh = Mesh::new(
|
||||
PrimitiveTopology::TriangleList,
|
||||
RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD,
|
||||
)
|
||||
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, verts)
|
||||
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
|
||||
// .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
|
||||
.with_inserted_indices(Indices::U32(indices))
|
||||
.with_duplicated_vertices()
|
||||
.with_computed_flat_normals();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
//TODO: figure out texture index
|
||||
fn create_tile(
|
||||
pos: Vec3,
|
||||
verts: &mut Vec<Vec3>,
|
||||
uvs: &mut Vec<Vec2>,
|
||||
normals: &mut Vec<Vec3>,
|
||||
indices: &mut Vec<u32>,
|
||||
) {
|
||||
let idx = verts.len() as u32;
|
||||
let center = Vec3::new(pos.x, 0., pos.z);
|
||||
normals.push(Vec3::Y);
|
||||
uvs.push(pos.xz());
|
||||
verts.push(pos);
|
||||
for i in 0..6 {
|
||||
let p = pos + HEX_CORNERS[i];
|
||||
verts.push(p);
|
||||
uvs.push(p.xz());
|
||||
normals.push((p - center).normalize());
|
||||
indices.push(idx);
|
||||
indices.push(idx + 1 + i as u32);
|
||||
indices.push(idx + 1 + ((i as u32 + 1) % 6));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user