Add mountainous heightmap terrain

This commit is contained in:
mars 2022-05-12 17:49:32 -06:00
parent 50510e6946
commit 55b3979ea7
2 changed files with 93 additions and 6 deletions

View File

@ -7,6 +7,7 @@ edition = "2021"
bytemuck = { version = "^1.0", features = ["derive"] }
glam = "0.20"
multimap = "0.8"
noise = "^0.7"
notify = "^4"
parking_lot = "^0.11"
pollster = "0.2"

View File

@ -37,8 +37,8 @@ impl Default for SpawnDistributions {
fn default() -> Self {
Self {
theta: rand::distributions::Uniform::new(0.0, std::f32::consts::TAU),
radius: rand::distributions::Uniform::new(4.0, 5.0),
up: rand::distributions::Uniform::new(10.0, 15.0),
radius: rand::distributions::Uniform::new(3.0, 4.0),
up: rand::distributions::Uniform::new(8.0, 12.0),
}
}
}
@ -94,10 +94,7 @@ fn update_transforms(transform: &mut cyborg::scene::Transform, particle: &Partic
}
#[system(for_each)]
fn update_debug(
draw_list: &mut cyborg::scene::DebugDrawList,
velocity: &Velocity,
) {
fn update_debug(draw_list: &mut cyborg::scene::DebugDrawList, velocity: &Velocity) {
draw_list.clear();
draw_list.indices.extend_from_slice(&[0, 1]);
@ -125,6 +122,83 @@ fn build_update_schedule() -> Schedule {
builder.build()
}
fn make_terrain(attributes: &mesh::Attributes) -> MeshBuffer {
const MOUNTAINS_RADIUS: f32 = 25.0;
const MOUNTAINS_WIDTH: f32 = 10.0;
const MOUNTAINS_HEIGHT: f32 = 5.0;
const MOUNTAINS_FREQUENCY: f32 = 1.0;
use noise::NoiseFn;
let noise = noise::OpenSimplex::new();
let sample = |xy: glam::Vec2| -> f32 {
let mountains_dist = (xy.length() - MOUNTAINS_RADIUS).abs() / MOUNTAINS_WIDTH;
let mountains_scale = 1.0 - mountains_dist;
if mountains_scale > 0.0 {
let noise_input = (xy * MOUNTAINS_FREQUENCY).as_dvec2();
let sampled = noise.get(noise_input.to_array()) as f32;
((sampled + 0.5) / 0.5) * MOUNTAINS_HEIGHT * mountains_scale
} else {
0.0
}
};
const GRID_FREQUENCY: f32 = 0.2;
const GRID_RADIUS: isize = ((MOUNTAINS_RADIUS + MOUNTAINS_WIDTH) / GRID_FREQUENCY) as isize;
const GRID_WIDTH: isize = GRID_RADIUS * 2 + 1;
let tile_num = (GRID_RADIUS * GRID_RADIUS) as usize;
let mut vertices = Vec::with_capacity(tile_num);
let mut indices = Vec::with_capacity(tile_num * 6);
for x in -GRID_RADIUS..=GRID_RADIUS {
for z in -GRID_RADIUS..=GRID_RADIUS {
let x = x as f32 * GRID_FREQUENCY;
let z = z as f32 * GRID_FREQUENCY;
let y = sample(glam::Vec2::new(x, z));
vertices.push(mesh::Vertex {
position: [x, y, z],
tan_frame: 0,
});
}
}
let mut cursor: mesh::Index = 0;
for _x in -GRID_RADIUS..GRID_RADIUS {
for _z in -GRID_RADIUS..GRID_RADIUS {
let next_line = cursor + GRID_WIDTH as mesh::Index;
indices.extend_from_slice(&[
cursor,
next_line,
cursor + 1,
next_line,
cursor + 1,
next_line + 1,
]);
cursor += 1;
}
cursor += 1;
}
let vertices = AttrBuffer {
id: attributes.vertex,
count: vertices.len(),
data: bytemuck::cast_slice(&vertices).to_vec(),
};
let indices = AttrBuffer {
id: attributes.index,
count: indices.len(),
data: bytemuck::cast_slice(&indices).to_vec(),
};
let mut mesh = MeshBuffer::default();
mesh.attributes.push(vertices);
mesh.attributes.push(indices);
mesh
}
fn main() {
let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
@ -205,6 +279,18 @@ fn main() {
example_mesh.attributes.push(example_indices);
let example_mesh = mesh_pass.get_mesh_pool().load(example_mesh).unwrap();
world.push((
cyborg::scene::Mesh {
mesh: mesh_pass
.get_mesh_pool()
.load(make_terrain(attributes))
.unwrap(),
},
cyborg::scene::Transform {
transform: glam::Mat4::from_translation(glam::Vec3::new(0.0, -10.0, 0.0)),
},
));
drop(mesh_pass);
let r = 6;