fixed hex coords, added tile walls
This commit is contained in:
@@ -17,16 +17,17 @@ pub fn generate_heightmap(height: usize, width: usize, cfg: &GenerationConfig, s
|
||||
}
|
||||
|
||||
pub fn generate_chunk(chunk_x: f64, chunk_z: f64, cfg: &GenerationConfig, seed: u32) -> Chunk {
|
||||
let mut result: Vec<f32> = Vec::with_capacity(Chunk::SIZE * Chunk::SIZE);
|
||||
let mut result: [f32; Chunk::SIZE * Chunk::SIZE] = [0.; Chunk::SIZE * Chunk::SIZE];
|
||||
let noise = SuperSimplex::new(seed);
|
||||
for z in 0..Chunk::SIZE {
|
||||
for x in 0..Chunk::SIZE {
|
||||
result.push(sample_point(
|
||||
let sample = sample_point(
|
||||
x as f64 + chunk_x * Chunk::SIZE as f64,
|
||||
z as f64 + chunk_z * Chunk::SIZE as f64,
|
||||
&cfg,
|
||||
&noise,
|
||||
));
|
||||
);
|
||||
result[x + z * Chunk::SIZE] = sample;
|
||||
}
|
||||
}
|
||||
return Chunk {
|
||||
|
||||
@@ -16,11 +16,13 @@ pub fn offset_to_world(offset: IVec2, height: f32) -> Vec3 {
|
||||
}
|
||||
|
||||
pub fn offset_to_hex(offset: IVec2) -> IVec3 {
|
||||
return IVec3 {
|
||||
x: offset.x,
|
||||
let mut v = IVec3 {
|
||||
x: offset.x - (offset.y / 2),
|
||||
y: offset.y,
|
||||
z: -offset.x - offset.y,
|
||||
z: 0,
|
||||
};
|
||||
v.z = -v.x - v.y;
|
||||
return v;
|
||||
}
|
||||
|
||||
pub fn snap_to_hex_grid(world_pos: Vec3) -> Vec3 {
|
||||
@@ -54,21 +56,29 @@ pub struct HexCoord {
|
||||
|
||||
impl HexCoord {
|
||||
pub const DIRECTIONS: [IVec3; 6] = [
|
||||
IVec3::new(1, 1, 0),
|
||||
IVec3::new(0, 1, -1),
|
||||
IVec3::new(1, 0, -1),
|
||||
IVec3::new(1, -1, 0),
|
||||
IVec3::new(0, -1, 1),
|
||||
IVec3::new(-1, 0, 1),
|
||||
IVec3::new(0, 1, -1),
|
||||
IVec3::new(-1, 1, 0),
|
||||
];
|
||||
|
||||
pub const ZERO: HexCoord = HexCoord { hex: IVec3::ZERO };
|
||||
|
||||
pub fn new(x: i32, z: i32) -> Self {
|
||||
return Self::from_offset(IVec2::new(x, z));
|
||||
return HexCoord {
|
||||
hex: IVec3::new(x, z, -x - z),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn from_hex(hex: IVec2) -> Self {
|
||||
return HexCoord {
|
||||
hex: IVec3::new(hex.x, hex.y, -hex.x - hex.y),
|
||||
};
|
||||
}
|
||||
pub fn from_grid_pos(x: usize, z: usize) -> Self {
|
||||
return HexCoord::new(x as i32, z as i32);
|
||||
return HexCoord::new(x as i32 - (z as i32 / 2), z as i32);
|
||||
}
|
||||
pub fn from_offset(offset_pos: IVec2) -> Self {
|
||||
return HexCoord {
|
||||
@@ -77,11 +87,12 @@ impl HexCoord {
|
||||
}
|
||||
|
||||
pub fn is_in_bounds(&self, map_height: usize, map_width: usize) -> bool {
|
||||
if self.hex.x < 0 || self.hex.y < 0 {
|
||||
let off = self.to_offset();
|
||||
if off.x < 0 || off.y < 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.hex.x >= map_width as i32 || self.hex.y >= map_height as i32 {
|
||||
if off.x >= map_width as i32 || off.y >= map_height as i32 {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -89,33 +100,36 @@ impl HexCoord {
|
||||
}
|
||||
|
||||
pub fn to_chunk_pos(&self) -> IVec2 {
|
||||
let off = self.to_offset();
|
||||
|
||||
return IVec2 {
|
||||
x: (self.hex.x as f32 / Chunk::SIZE as f32).floor() as i32,
|
||||
y: (self.hex.y as f32 / Chunk::SIZE as f32).floor() as i32,
|
||||
x: (off.x as f32 / Chunk::SIZE as f32).floor() as i32,
|
||||
y: (off.y as f32 / Chunk::SIZE as f32).floor() as i32,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn to_chunk(&self) -> HexCoord {
|
||||
let c_pos = self.to_chunk_pos();
|
||||
let off = self.to_offset();
|
||||
return HexCoord::from_offset(
|
||||
(
|
||||
self.hex.x - (c_pos.x * Chunk::SIZE as i32),
|
||||
self.hex.y - (c_pos.y * Chunk::SIZE as i32),
|
||||
off.x - (c_pos.x * Chunk::SIZE as i32),
|
||||
off.y - (c_pos.y * Chunk::SIZE as i32),
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn to_world(&self, height: f32) -> Vec3 {
|
||||
return offset_to_world(self.hex.xy(), height);
|
||||
return offset_to_world(self.to_offset(), height);
|
||||
}
|
||||
|
||||
pub fn to_offset(&self) -> IVec2 {
|
||||
return self.hex.xy();
|
||||
return IVec2::new(self.hex.x + (self.hex.y / 2), self.hex.y);
|
||||
}
|
||||
|
||||
pub fn to_index(&self, width: usize) -> i32 {
|
||||
return self.hex.x + self.hex.y * width as i32 + self.hex.y / 2;
|
||||
return (self.hex.x + self.hex.y * width as i32) + (self.hex.y / 2);
|
||||
}
|
||||
pub fn to_chunk_index(&self, width: usize) -> i32 {
|
||||
let pos = self.to_chunk_pos();
|
||||
@@ -150,7 +164,7 @@ impl HexCoord {
|
||||
pc = Self::slide_left(pc);
|
||||
}
|
||||
}
|
||||
return HexCoord::from_offset(pc.xy() + center.hex.xy());
|
||||
return HexCoord::from_hex(pc.xy() + center.hex.xy());
|
||||
}
|
||||
|
||||
fn slide_left(hex: IVec3) -> IVec3 {
|
||||
@@ -163,12 +177,12 @@ impl HexCoord {
|
||||
|
||||
pub fn scale(&self, dir: i32, radius: usize) -> HexCoord {
|
||||
let s = Self::DIRECTIONS[(dir % 6) as usize] * radius as i32;
|
||||
return Self::from_offset(self.hex.xy() + s.xy());
|
||||
return Self::from_hex(self.hex.xy() + s.xy());
|
||||
}
|
||||
|
||||
pub fn get_neighbor(&self, dir: usize) -> HexCoord {
|
||||
let d = Self::DIRECTIONS[dir % 6];
|
||||
return Self::from_offset(self.hex.xy() + d.xy());
|
||||
return Self::from_hex(self.hex.xy() + d.xy());
|
||||
}
|
||||
|
||||
pub fn get_neighbors(&self) -> [HexCoord; 6] {
|
||||
|
||||
@@ -21,7 +21,7 @@ pub mod prelude {
|
||||
pub first_layer_mask: bool,
|
||||
}
|
||||
pub struct Chunk {
|
||||
pub points: Vec<f32>,
|
||||
pub points: [f32; Chunk::SIZE * Chunk::SIZE],
|
||||
pub chunk_offset: IVec2,
|
||||
}
|
||||
|
||||
@@ -39,16 +39,18 @@ pub mod prelude {
|
||||
impl Map {
|
||||
pub fn get_neighbors(&self, pos: &HexCoord) -> [Option<f32>; 6] {
|
||||
let mut results: [Option<f32>; 6] = [None; 6];
|
||||
let w = self.width * Chunk::SIZE;
|
||||
let h = self.height * Chunk::SIZE;
|
||||
let n_tiles = pos.get_neighbors();
|
||||
for i in 0..6 {
|
||||
let n_tile = n_tiles[i];
|
||||
if !n_tile.is_in_bounds(self.height, self.width) {
|
||||
if !n_tile.is_in_bounds(h, w) {
|
||||
continue;
|
||||
}
|
||||
let c_idx = n_tile.to_chunk_index(self.width);
|
||||
let chunk = &self.chunks[c_idx as usize];
|
||||
let local = n_tile.to_chunk_local_index();
|
||||
results[i] = (Some(chunk.points[local as usize]));
|
||||
results[i] = Some(chunk.points[local as usize]);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -21,30 +21,21 @@ const HEX_CORNERS: [Vec3; 6] = [
|
||||
];
|
||||
|
||||
pub fn generate_chunk_mesh(chunk: &Chunk, map: &Map) -> Mesh {
|
||||
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE;
|
||||
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
||||
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 coord = HexCoord::from_grid_pos(x, z);
|
||||
let height = chunk.points[coord.to_index(Chunk::SIZE) as usize];
|
||||
let height = chunk.points[x + z * Chunk::SIZE];
|
||||
let off_pos = Vec3::new(x as f32, height, z as f32);
|
||||
let grid_pos = offset3d_to_world(off_pos);
|
||||
let n = map.get_neighbors(&HexCoord::from_offset(
|
||||
coord.to_offset() + chunk.chunk_offset,
|
||||
));
|
||||
create_tile(
|
||||
grid_pos,
|
||||
&n,
|
||||
&mut verts,
|
||||
&mut uvs,
|
||||
&mut normals,
|
||||
&mut indices,
|
||||
0,
|
||||
let tile_pos = offset3d_to_world(off_pos);
|
||||
let coord = HexCoord::from_offset(
|
||||
IVec2::new(x as i32, z as i32) + (chunk.chunk_offset * Chunk::SIZE as i32),
|
||||
);
|
||||
let n = map.get_neighbors(&coord);
|
||||
create_tile(tile_pos, &n, &mut verts, &mut uvs, &mut indices, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +45,6 @@ pub fn generate_chunk_mesh(chunk: &Chunk, map: &Map) -> Mesh {
|
||||
)
|
||||
.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();
|
||||
@@ -67,20 +57,16 @@ fn create_tile(
|
||||
neighbors: &[Option<f32>; 6],
|
||||
verts: &mut Vec<Vec3>,
|
||||
uvs: &mut Vec<Vec2>,
|
||||
normals: &mut Vec<Vec3>,
|
||||
indices: &mut Vec<u32>,
|
||||
texture_index: 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));
|
||||
@@ -90,17 +76,8 @@ fn create_tile(
|
||||
let cur_n = neighbors[i];
|
||||
match cur_n {
|
||||
Some(n_height) => {
|
||||
if true {
|
||||
create_tile_wall(
|
||||
pos,
|
||||
i,
|
||||
pos.y + 1.,
|
||||
verts,
|
||||
uvs,
|
||||
normals,
|
||||
indices,
|
||||
texture_index,
|
||||
);
|
||||
if n_height < pos.y {
|
||||
create_tile_wall(pos, i, n_height, verts, uvs, indices, texture_index);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -114,18 +91,14 @@ fn create_tile_wall(
|
||||
height: f32,
|
||||
verts: &mut Vec<Vec3>,
|
||||
uvs: &mut Vec<Vec2>,
|
||||
normals: &mut Vec<Vec3>,
|
||||
indices: &mut Vec<u32>,
|
||||
_texture_index: u32,
|
||||
) {
|
||||
println!("{dir}");
|
||||
let p1 = HEX_CORNERS[(dir + 1) % 6] + pos;
|
||||
let p2 = HEX_CORNERS[(dir + 2) % 6] + pos;
|
||||
let p1 = HEX_CORNERS[(dir) % 6] + pos;
|
||||
let p2 = HEX_CORNERS[(dir + 1) % 6] + pos;
|
||||
let p3 = Vec3::new(p1.x, height, p1.z);
|
||||
let p4 = Vec3::new(p2.x, height, p2.z);
|
||||
|
||||
let normal = Vec3::Y;
|
||||
|
||||
let idx = verts.len() as u32;
|
||||
|
||||
verts.push(p1);
|
||||
@@ -133,11 +106,6 @@ fn create_tile_wall(
|
||||
verts.push(p3);
|
||||
verts.push(p4);
|
||||
|
||||
normals.push(normal);
|
||||
normals.push(normal);
|
||||
normals.push(normal);
|
||||
normals.push(normal);
|
||||
|
||||
indices.push(idx);
|
||||
indices.push(idx + 2);
|
||||
indices.push(idx + 1);
|
||||
|
||||
Reference in New Issue
Block a user