working generating terrain
This commit is contained in:
+46
-66
@@ -1,10 +1,12 @@
|
|||||||
use cgmath::{Point3, InnerSpace};
|
use cgmath::{Point3, InnerSpace};
|
||||||
use noise::{Perlin, NoiseFn};
|
use noise::{Perlin, NoiseFn};
|
||||||
use rand::Rng;
|
use rand::{Rng, prelude::ThreadRng};
|
||||||
|
|
||||||
use crate::renderer::Level;
|
use crate::renderer::Level;
|
||||||
use crate::renderer::buffers::{BLOCK_SIZE, NODE_TEX_SIZE, Block};
|
use crate::renderer::buffers::{BLOCK_SIZE, NODE_TEX_SIZE, Block};
|
||||||
|
|
||||||
|
const SCALE: f64 = 150.0;
|
||||||
|
|
||||||
|
|
||||||
pub struct WorldGen {
|
pub struct WorldGen {
|
||||||
|
|
||||||
@@ -16,85 +18,63 @@ impl WorldGen {
|
|||||||
Self{}
|
Self{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate height map for given block position
|
||||||
|
*/
|
||||||
|
fn gen_height_map(x: usize, z: usize, rand: &mut ThreadRng, noise: &Perlin) -> ([[usize;BLOCK_SIZE]; BLOCK_SIZE], usize) {
|
||||||
|
let x = x * BLOCK_SIZE;
|
||||||
|
let z = z * BLOCK_SIZE;
|
||||||
|
|
||||||
|
// Generate map
|
||||||
|
let mut max: usize = 0;
|
||||||
|
let mut map = [[0_usize; BLOCK_SIZE]; BLOCK_SIZE];
|
||||||
|
for lx in 0..BLOCK_SIZE {
|
||||||
|
for lz in 0..BLOCK_SIZE {
|
||||||
|
let value = (noise.get([(x + lx) as f64 / SCALE, (z + lz) as f64 /SCALE]) + 1.0) / 2.0;
|
||||||
|
let mut h = (value * 30.0) as usize + 1;
|
||||||
|
h += (rand.gen::<f32>() * 2.0) as usize;
|
||||||
|
if h > max { max = h; }
|
||||||
|
map[lx][lz] = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(map, max)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate world
|
* Generate world
|
||||||
*/
|
*/
|
||||||
pub fn generate(&mut self, level: &mut dyn Level, noise: &Perlin) {
|
pub fn generate(&mut self, level: &mut dyn Level, noise: &Perlin) {
|
||||||
|
|
||||||
const SCALE: f64 = 150.0;
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
let mut dirty: Vec<usize> = Vec::new();
|
||||||
|
|
||||||
|
for bx in 0..48 {
|
||||||
for bx in 0..16 {
|
for bz in 0..48 {
|
||||||
for bz in 0..16 {
|
// Generate height map
|
||||||
|
let (map, max) = WorldGen::gen_height_map(bx, bz, &mut rng, noise);
|
||||||
|
let bh = max % BLOCK_SIZE;
|
||||||
|
// Generate blocks
|
||||||
|
for by in 0..bh {
|
||||||
|
// Get
|
||||||
|
let b = level.block_get(Point3{x:bx, y:by, z:bz});
|
||||||
|
dirty.push(b.id);
|
||||||
|
// Fill
|
||||||
for x in 0..BLOCK_SIZE {
|
for x in 0..BLOCK_SIZE {
|
||||||
for z in 0..BLOCK_SIZE {
|
for z in 0..BLOCK_SIZE {
|
||||||
// world x,z
|
// TODO
|
||||||
let wx = bx * BLOCK_SIZE + x;
|
let h = map[x][z];
|
||||||
let wz = bz * BLOCK_SIZE + z;
|
for y in 0..h {
|
||||||
// world h
|
let val = if y+1 == h { 2 } else { 1 };
|
||||||
let value1 = (noise.get([wx as f64 /SCALE*2.0, wz as f64 /SCALE*2.0]) + 1.0) / 1.5 - 0.6;
|
b.set(Point3{x, y, z}, val);
|
||||||
let value2 = (noise.get([wx as f64 /SCALE, wz as f64 /SCALE]) + 1.0) / 2.0;
|
|
||||||
let value = if value1 > value2 { value1 } else {value2};
|
|
||||||
|
|
||||||
let mut wh = (value * 40.0) as usize + 1;
|
|
||||||
wh += (rng.gen::<f32>() * 2.0) as usize;
|
|
||||||
|
|
||||||
// fill column
|
|
||||||
for wy in 0..wh {
|
|
||||||
let y = wy % BLOCK_SIZE;
|
|
||||||
let by = wy / BLOCK_SIZE;
|
|
||||||
let val = if wy == wh-1 { 2 } else { 1 };
|
|
||||||
|
|
||||||
level.block_get(Point3{x:bx, y:by, z:bz}).set(Point3{x, y, z}, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for id in dirty {
|
||||||
// let mut rng = rand::thread_rng();
|
level.block_dirty(id);
|
||||||
// let mut apply = false;
|
}
|
||||||
|
|
||||||
|
|
||||||
// let voxel_pos = pos * BLOCK_SIZE;
|
|
||||||
|
|
||||||
// // Genereate grass
|
|
||||||
// if pos.y < 1 {
|
|
||||||
// for x in 0..32 {
|
|
||||||
// for z in 0..32 {
|
|
||||||
// let wx = voxel_pos.x + x;
|
|
||||||
// let wz = voxel_pos.z + z;
|
|
||||||
|
|
||||||
// let value = (noise.get([wx as f64 * 0.0123, wz as f64 * 0.0123]) + 1.0) / 2.0;
|
|
||||||
// let h = (value * 30.0) as usize + 1;
|
|
||||||
|
|
||||||
// for y in 0..h {
|
|
||||||
// renderer.block_set_voxel(block_id, x, y, z, 2);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// apply = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Generate wall
|
|
||||||
// if pos.x == 8 && pos.y < 3 && pos.z < 8 && pos.z > 4 {
|
|
||||||
// for z in 0..32 {
|
|
||||||
// for y in 0..32 {
|
|
||||||
// renderer.block_set_voxel(block_id, 16, y, z, 3);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// apply = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Apply
|
|
||||||
// if apply {
|
|
||||||
// if block_id != renderer.block_get_id(pos, true) {
|
|
||||||
// panic!("Block already consumed?");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,9 @@ impl Blocks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_id(&mut self, queue: &wgpu::Queue, block_id: usize) {
|
pub fn write_id(&mut self, queue: &wgpu::Queue, block_id: usize) {
|
||||||
let block = self.get(block_id).unwrap();
|
|
||||||
|
// Get block from id
|
||||||
|
let block = &self.blocks[block_id];
|
||||||
|
|
||||||
// Calculate block position in texture
|
// Calculate block position in texture
|
||||||
let y = (block.id%BLOCK_TEX_SIZE * BLOCK_SIZE) as u32;
|
let y = (block.id%BLOCK_TEX_SIZE * BLOCK_SIZE) as u32;
|
||||||
@@ -117,6 +119,10 @@ impl Blocks {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get(&mut self, block_id: usize) -> &mut Block {
|
||||||
|
&mut self.blocks[block_id]
|
||||||
|
}
|
||||||
|
|
||||||
// /*
|
// /*
|
||||||
// Write block data to gpu, should be called to apply changes
|
// Write block data to gpu, should be called to apply changes
|
||||||
// */
|
// */
|
||||||
@@ -147,16 +153,4 @@ impl Blocks {
|
|||||||
self.free_block += 1;
|
self.free_block += 1;
|
||||||
&mut self.blocks[self.free_block - 1]
|
&mut self.blocks[self.free_block - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets block with id
|
|
||||||
*/
|
|
||||||
pub fn get(&mut self, id: usize) -> Option<&mut Block> {
|
|
||||||
for b in self.blocks.iter_mut() {
|
|
||||||
if b.id == id {
|
|
||||||
return Some(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ pub const NODE_TEX_SIZE: usize = 48; // 32x32x32 nodes in texture
|
|||||||
|
|
||||||
pub const NODE_TEX_LEN: usize = NODE_TEX_SIZE*NODE_TEX_SIZE*NODE_TEX_SIZE; // Number of u32 in node texture
|
pub const NODE_TEX_LEN: usize = NODE_TEX_SIZE*NODE_TEX_SIZE*NODE_TEX_SIZE; // Number of u32 in node texture
|
||||||
pub const BLOCK_LEN : usize = BLOCK_SIZE*BLOCK_SIZE*BLOCK_SIZE; // Number of u8 in one block
|
pub const BLOCK_LEN : usize = BLOCK_SIZE*BLOCK_SIZE*BLOCK_SIZE; // Number of u8 in one block
|
||||||
pub const BLOCK_ARR_LEN: usize = BLOCK_TEX_SIZE*BLOCK_TEX_SIZE; // Number of blocks in texture
|
pub const BLOCK_ARR_LEN: usize = NODE_TEX_SIZE*NODE_TEX_SIZE; // Number of blocks in texture
|
||||||
pub const BLOCK_TEX_LEN: usize = BLOCK_TEX_SIZE*BLOCK_TEX_SIZE * BLOCK_LEN; // Number of u8 in block texture
|
pub const BLOCK_TEX_LEN: usize = BLOCK_TEX_SIZE*BLOCK_TEX_SIZE * BLOCK_LEN; // Number of u8 in block texture
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::renderer::{Renderer, buffers};
|
|||||||
|
|
||||||
pub trait Level {
|
pub trait Level {
|
||||||
fn block_get(&mut self, block_pos: Point3<usize>) -> &mut buffers::Block;
|
fn block_get(&mut self, block_pos: Point3<usize>) -> &mut buffers::Block;
|
||||||
fn block_dirty(&mut self, block: &buffers::Block);
|
fn block_dirty(&mut self, id: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Level for Renderer {
|
impl Level for Renderer {
|
||||||
@@ -17,15 +17,17 @@ impl Level for Renderer {
|
|||||||
// Allocate new block
|
// Allocate new block
|
||||||
if node_value == 0 {
|
if node_value == 0 {
|
||||||
let block = self.buffers.brick_buffer.alloc();
|
let block = self.buffers.brick_buffer.alloc();
|
||||||
self.buffers.node_buffer.nodes[node_idx] = block.id as u32;
|
self.buffers.node_buffer.nodes[node_idx] = (block.id+1) as u32;
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return existing block
|
// Return existing block
|
||||||
self.buffers.brick_buffer.get(node_idx).unwrap()
|
self.buffers.brick_buffer.get((node_value-1) as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_dirty(&mut self, block: &buffers::Block) {
|
fn block_dirty(&mut self, id: usize) {
|
||||||
self.changed_bricks.push(block.id);
|
if !self.changed_bricks.contains(&id) {
|
||||||
|
self.changed_bricks.push(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
@@ -62,7 +62,7 @@ vec3 solve()
|
|||||||
// Calculate ray direction
|
// Calculate ray direction
|
||||||
vec3 view_dir = (_ProjMatrixInv * vec4(_InUV, 0, 1)).xyz;
|
vec3 view_dir = (_ProjMatrixInv * vec4(_InUV, 0, 1)).xyz;
|
||||||
vec3 rayDir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz;
|
vec3 rayDir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz;
|
||||||
Ray primaryRay = Ray(_CamPos / SCALE, rayDir);
|
Ray primaryRay = Ray((_CamPos + vec3(16, 0, 16)) / SCALE, rayDir);
|
||||||
|
|
||||||
// Raycast
|
// Raycast
|
||||||
HitResult primary = castNodes(primaryRay, 100);
|
HitResult primary = castNodes(primaryRay, 100);
|
||||||
|
|||||||
Reference in New Issue
Block a user