simplify meshing
generate collision mesh add physics
This commit is contained in:
@@ -2,15 +2,51 @@ pub mod biome_painter;
|
|||||||
pub mod heightmap;
|
pub mod heightmap;
|
||||||
pub mod hex_utils;
|
pub mod hex_utils;
|
||||||
pub mod mesh_generator;
|
pub mod mesh_generator;
|
||||||
|
pub mod packed_mesh_generator;
|
||||||
pub mod tile_manager;
|
pub mod tile_manager;
|
||||||
pub mod tile_mapper;
|
pub mod tile_mapper;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
use crate::hex_utils::HexCoord;
|
use crate::hex_utils::{HexCoord, INNER_RADIUS, OUTER_RADIUS};
|
||||||
use bevy::math::{IVec2, UVec2};
|
use bevy::math::{IVec2, UVec2, Vec2, Vec3};
|
||||||
use bevy::prelude::Resource;
|
use bevy::prelude::Resource;
|
||||||
use bevy::render::mesh::MeshVertexAttribute;
|
use bevy::render::mesh::MeshVertexAttribute;
|
||||||
use bevy::render::render_resource::VertexFormat;
|
use bevy::render::render_resource::VertexFormat;
|
||||||
|
pub const TEX_MULTI: Vec2 = Vec2::new(1000., 1.);
|
||||||
|
|
||||||
|
pub 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 const HEX_NORMALS: [Vec3; 6] = [
|
||||||
|
Vec3::new(
|
||||||
|
INNER_RADIUS / 2.,
|
||||||
|
0.,
|
||||||
|
(OUTER_RADIUS + 0.5 * OUTER_RADIUS) / 2.,
|
||||||
|
),
|
||||||
|
Vec3::Z,
|
||||||
|
Vec3::new(
|
||||||
|
INNER_RADIUS / -2.,
|
||||||
|
0.,
|
||||||
|
(OUTER_RADIUS + 0.5 * OUTER_RADIUS) / 2.,
|
||||||
|
),
|
||||||
|
Vec3::new(
|
||||||
|
INNER_RADIUS / -2.,
|
||||||
|
0.,
|
||||||
|
(OUTER_RADIUS + 0.5 * OUTER_RADIUS) / -2.,
|
||||||
|
),
|
||||||
|
Vec3::NEG_Z,
|
||||||
|
Vec3::new(
|
||||||
|
INNER_RADIUS / 2.,
|
||||||
|
0.,
|
||||||
|
(OUTER_RADIUS + 0.5 * OUTER_RADIUS) / -2.,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
pub struct GenerationConfig {
|
pub struct GenerationConfig {
|
||||||
pub noise_scale: f64,
|
pub noise_scale: f64,
|
||||||
|
|||||||
@@ -2,10 +2,7 @@ use crate::biome_painter::BiomePainterAsset;
|
|||||||
use crate::hex_utils::HexCoord;
|
use crate::hex_utils::HexCoord;
|
||||||
use crate::tile_manager::TileAsset;
|
use crate::tile_manager::TileAsset;
|
||||||
use crate::tile_mapper::TileMapperAsset;
|
use crate::tile_mapper::TileMapperAsset;
|
||||||
use crate::{
|
use crate::{hex_utils::offset3d_to_world, prelude::*};
|
||||||
hex_utils::{offset3d_to_world, INNER_RADIUS, OUTER_RADIUS},
|
|
||||||
prelude::*,
|
|
||||||
};
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
render::{
|
render::{
|
||||||
@@ -13,41 +10,79 @@ use bevy::{
|
|||||||
render_asset::RenderAssetUsages,
|
render_asset::RenderAssetUsages,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::vec::Vec;
|
|
||||||
|
|
||||||
const HEX_CORNERS: [Vec3; 6] = [
|
pub fn generate_chunk_collider(chunk: &Chunk, map: &Map) -> (Vec<Vec3>, Vec<[u32; 3]>) {
|
||||||
Vec3::new(0., 0., OUTER_RADIUS),
|
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
||||||
Vec3::new(INNER_RADIUS, 0., 0.5 * OUTER_RADIUS),
|
let mut verts = Vec::with_capacity(vertex_count);
|
||||||
Vec3::new(INNER_RADIUS, 0., -0.5 * OUTER_RADIUS),
|
let mut indices = Vec::with_capacity(vertex_count);
|
||||||
Vec3::new(0., 0., -OUTER_RADIUS),
|
for z in 0..Chunk::SIZE {
|
||||||
Vec3::new(-INNER_RADIUS, 0., -0.5 * OUTER_RADIUS),
|
for x in 0..Chunk::SIZE {
|
||||||
Vec3::new(-INNER_RADIUS, 0., 0.5 * OUTER_RADIUS),
|
let height = chunk.heights[x + z * Chunk::SIZE];
|
||||||
];
|
let coord = HexCoord::from_offset(
|
||||||
|
IVec2::new(x as i32, z as i32) + (chunk.chunk_offset * Chunk::SIZE as i32),
|
||||||
|
);
|
||||||
|
let neighbors = map.get_neighbors(&coord);
|
||||||
|
let off_pos = Vec3::new(x as f32, height, z as f32);
|
||||||
|
let tile_pos = offset3d_to_world(off_pos);
|
||||||
|
create_tile_collider(tile_pos, &mut verts, &mut indices, &neighbors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (verts, indices);
|
||||||
|
}
|
||||||
|
|
||||||
const HEX_NORMALS: [Vec3; 6] = [
|
fn create_tile_collider(
|
||||||
Vec3::new(
|
pos: Vec3,
|
||||||
INNER_RADIUS / 2.,
|
verts: &mut Vec<Vec3>,
|
||||||
0.,
|
indices: &mut Vec<[u32; 3]>,
|
||||||
(OUTER_RADIUS + 0.5 * OUTER_RADIUS) / 2.,
|
neighbors: &[Option<f32>; 6],
|
||||||
),
|
) {
|
||||||
Vec3::Z,
|
let idx = verts.len() as u32;
|
||||||
Vec3::new(
|
for i in 0..6 {
|
||||||
INNER_RADIUS / -2.,
|
let p = pos + HEX_CORNERS[i];
|
||||||
0.,
|
verts.push(p);
|
||||||
(OUTER_RADIUS + 0.5 * OUTER_RADIUS) / 2.,
|
}
|
||||||
),
|
for i in 0..3 {
|
||||||
Vec3::new(
|
let off = i * 2;
|
||||||
INNER_RADIUS / -2.,
|
|
||||||
0.,
|
indices.push([off + idx, ((off + 1) % 6) + idx, ((off + 2) % 6) + idx]);
|
||||||
(OUTER_RADIUS + 0.5 * OUTER_RADIUS) / -2.,
|
}
|
||||||
),
|
|
||||||
Vec3::NEG_Z,
|
indices.push([idx, idx + 2, idx + 4]);
|
||||||
Vec3::new(
|
|
||||||
INNER_RADIUS / 2.,
|
for i in 0..neighbors.len() {
|
||||||
0.,
|
let cur_n = neighbors[i];
|
||||||
(OUTER_RADIUS + 0.5 * OUTER_RADIUS) / -2.,
|
match cur_n {
|
||||||
),
|
Some(n_height) => {
|
||||||
];
|
if n_height < pos.y {
|
||||||
|
create_tile_wall_collider(
|
||||||
|
idx,
|
||||||
|
Vec3::new(pos.x, n_height, pos.z),
|
||||||
|
i,
|
||||||
|
verts,
|
||||||
|
indices,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_tile_wall_collider(
|
||||||
|
idx: u32,
|
||||||
|
pos: Vec3,
|
||||||
|
dir: usize,
|
||||||
|
verts: &mut Vec<Vec3>,
|
||||||
|
indices: &mut Vec<[u32; 3]>,
|
||||||
|
) {
|
||||||
|
let idx2 = verts.len() as u32;
|
||||||
|
|
||||||
|
verts.push(pos + HEX_CORNERS[dir]);
|
||||||
|
verts.push(pos + HEX_CORNERS[(dir + 1) % 6]);
|
||||||
|
|
||||||
|
indices.push([idx, idx + 1, idx2]);
|
||||||
|
indices.push([idx, idx2 + 1, idx2]);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn generate_chunk_mesh(
|
pub fn generate_chunk_mesh(
|
||||||
chunk: &Chunk,
|
chunk: &Chunk,
|
||||||
@@ -102,132 +137,6 @@ pub fn generate_chunk_mesh(
|
|||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_packed_chunk_mesh(
|
|
||||||
chunk: &Chunk,
|
|
||||||
map: &Map,
|
|
||||||
painter: &BiomePainterAsset,
|
|
||||||
tiles: &Res<Assets<TileAsset>>,
|
|
||||||
mappers: &Res<Assets<TileMapperAsset>>,
|
|
||||||
) -> Mesh {
|
|
||||||
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
|
||||||
let mut packed_data = Vec::with_capacity(vertex_count);
|
|
||||||
let mut indices = Vec::with_capacity(vertex_count);
|
|
||||||
let mut heights = Vec::with_capacity(vertex_count);
|
|
||||||
|
|
||||||
for z in 0..Chunk::SIZE {
|
|
||||||
for x in 0..Chunk::SIZE {
|
|
||||||
let height = chunk.heights[x + z * Chunk::SIZE];
|
|
||||||
let moisture = chunk.moisture[x + z * Chunk::SIZE];
|
|
||||||
let temperature = chunk.temperature[x + z * Chunk::SIZE];
|
|
||||||
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);
|
|
||||||
let biome = mappers.get(painter.sample_biome(moisture, temperature));
|
|
||||||
let tile_handle = biome.unwrap().sample_tile(height);
|
|
||||||
let tile = tiles.get(tile_handle).unwrap();
|
|
||||||
|
|
||||||
create_packed_tile(
|
|
||||||
UVec2::new(x as u32, z as u32),
|
|
||||||
height,
|
|
||||||
&n,
|
|
||||||
&mut packed_data,
|
|
||||||
&mut indices,
|
|
||||||
&mut heights,
|
|
||||||
tile.texture_id,
|
|
||||||
tile.side_texture_id,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mesh = Mesh::new(
|
|
||||||
PrimitiveTopology::TriangleList,
|
|
||||||
RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD,
|
|
||||||
)
|
|
||||||
.with_inserted_attribute(ATTRIBUTE_PACKED_VERTEX_DATA, packed_data)
|
|
||||||
.with_inserted_attribute(ATTRIBUTE_VERTEX_HEIGHT, heights)
|
|
||||||
.with_inserted_indices(Indices::U32(indices));
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TEX_MULTI: Vec2 = Vec2::new(1000., 1.);
|
|
||||||
|
|
||||||
fn create_packed_tile(
|
|
||||||
offset: UVec2,
|
|
||||||
height: f32,
|
|
||||||
neighbors: &[Option<f32>; 6],
|
|
||||||
packed_data: &mut Vec<u32>,
|
|
||||||
indices: &mut Vec<u32>,
|
|
||||||
heights: &mut Vec<f32>,
|
|
||||||
texture_index: u32,
|
|
||||||
side_texture_index: u32,
|
|
||||||
) {
|
|
||||||
let idx = packed_data.len() as u32;
|
|
||||||
|
|
||||||
packed_data.push(pack_vertex_data(offset, 0, texture_index));
|
|
||||||
heights.push(height);
|
|
||||||
for i in 0..6 {
|
|
||||||
packed_data.push(pack_vertex_data(offset, i + 1, texture_index));
|
|
||||||
indices.push(idx);
|
|
||||||
indices.push(idx + 1 + i as u32);
|
|
||||||
indices.push(idx + 1 + ((i as u32 + 1) % 6));
|
|
||||||
heights.push(height);
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 0..neighbors.len() {
|
|
||||||
let cur_n = neighbors[i];
|
|
||||||
match cur_n {
|
|
||||||
Some(n_height) => {
|
|
||||||
if n_height < height {
|
|
||||||
create_packed_tile_wall(
|
|
||||||
offset,
|
|
||||||
height,
|
|
||||||
n_height,
|
|
||||||
i,
|
|
||||||
packed_data,
|
|
||||||
indices,
|
|
||||||
heights,
|
|
||||||
side_texture_index,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_packed_tile_wall(
|
|
||||||
offset: UVec2,
|
|
||||||
height_top: f32,
|
|
||||||
height_bottom: f32,
|
|
||||||
side: usize,
|
|
||||||
packed_data: &mut Vec<u32>,
|
|
||||||
indices: &mut Vec<u32>,
|
|
||||||
heights: &mut Vec<f32>,
|
|
||||||
side_texture_index: u32,
|
|
||||||
) {
|
|
||||||
let idx = packed_data.len() as u32;
|
|
||||||
|
|
||||||
let side_2 = ((side + 1) % 6) + 1;
|
|
||||||
packed_data.push(pack_vertex_data(offset, side + 1, side_texture_index));
|
|
||||||
packed_data.push(pack_vertex_data(offset, side_2, side_texture_index));
|
|
||||||
packed_data.push(pack_vertex_data(offset, side + 1, side_texture_index));
|
|
||||||
packed_data.push(pack_vertex_data(offset, side_2, side_texture_index));
|
|
||||||
|
|
||||||
heights.push(height_top);
|
|
||||||
heights.push(height_top);
|
|
||||||
heights.push(height_bottom);
|
|
||||||
heights.push(height_bottom);
|
|
||||||
|
|
||||||
indices.push(idx);
|
|
||||||
indices.push(idx + 2);
|
|
||||||
indices.push(idx + 1);
|
|
||||||
|
|
||||||
indices.push(idx + 1);
|
|
||||||
indices.push(idx + 2);
|
|
||||||
indices.push(idx + 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_tile(
|
fn create_tile(
|
||||||
pos: Vec3,
|
pos: Vec3,
|
||||||
neighbors: &[Option<f32>; 6],
|
neighbors: &[Option<f32>; 6],
|
||||||
@@ -243,19 +152,22 @@ fn create_tile(
|
|||||||
let side_tex_off = Vec2::new(side_texture_index as f32, 0.);
|
let side_tex_off = Vec2::new(side_texture_index as f32, 0.);
|
||||||
|
|
||||||
let idx = verts.len() as u32;
|
let idx = verts.len() as u32;
|
||||||
uvs.push((uv_offset / TEX_MULTI) + tex_off);
|
|
||||||
verts.push(pos);
|
|
||||||
normals.push(Vec3::Y);
|
|
||||||
for i in 0..6 {
|
for i in 0..6 {
|
||||||
let p = pos + HEX_CORNERS[i];
|
let p = pos + HEX_CORNERS[i];
|
||||||
verts.push(p);
|
verts.push(p);
|
||||||
let uv = (HEX_CORNERS[i].xz() / 2.) + uv_offset;
|
let uv = (HEX_CORNERS[i].xz() / 2.) + uv_offset;
|
||||||
uvs.push((uv / TEX_MULTI) + tex_off);
|
uvs.push((uv / TEX_MULTI) + tex_off);
|
||||||
indices.push(idx);
|
|
||||||
indices.push(idx + 1 + i as u32);
|
|
||||||
indices.push(idx + 1 + ((i as u32 + 1) % 6));
|
|
||||||
normals.push(Vec3::Y);
|
normals.push(Vec3::Y);
|
||||||
}
|
}
|
||||||
|
for i in 0..3 {
|
||||||
|
let off = i * 2;
|
||||||
|
indices.push(off + idx);
|
||||||
|
indices.push(((off + 1) % 6) + idx);
|
||||||
|
indices.push(((off + 2) % 6) + idx);
|
||||||
|
}
|
||||||
|
indices.push(idx);
|
||||||
|
indices.push(idx + 2);
|
||||||
|
indices.push(idx + 4);
|
||||||
|
|
||||||
for i in 0..neighbors.len() {
|
for i in 0..neighbors.len() {
|
||||||
let cur_n = neighbors[i];
|
let cur_n = neighbors[i];
|
||||||
@@ -311,15 +223,3 @@ fn create_tile_wall(
|
|||||||
uvs.push((Vec2::new(0., pos.y - height) / TEX_MULTI) + tex_off);
|
uvs.push((Vec2::new(0., pos.y - height) / TEX_MULTI) + tex_off);
|
||||||
uvs.push((Vec2::new(1., pos.y - height) / TEX_MULTI) + tex_off);
|
uvs.push((Vec2::new(1., pos.y - height) / TEX_MULTI) + tex_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pack_vertex_data(offset: UVec2, vert: usize, tex: u32) -> u32 {
|
|
||||||
//6 + 6 bits offset
|
|
||||||
//4 bits vert
|
|
||||||
//12 bits texture
|
|
||||||
let mut data = offset.x;
|
|
||||||
data += (offset.y) << 6;
|
|
||||||
data += (vert as u32) << (6 + 6);
|
|
||||||
data += tex << (6 + 6 + 4);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|||||||
148
engine/world_generation/src/packed_mesh_generator.rs
Normal file
148
engine/world_generation/src/packed_mesh_generator.rs
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
use crate::biome_painter::BiomePainterAsset;
|
||||||
|
use crate::hex_utils::HexCoord;
|
||||||
|
use crate::prelude::*;
|
||||||
|
use crate::tile_manager::TileAsset;
|
||||||
|
use crate::tile_mapper::TileMapperAsset;
|
||||||
|
use bevy::{
|
||||||
|
prelude::*,
|
||||||
|
render::{
|
||||||
|
mesh::{Indices, PrimitiveTopology},
|
||||||
|
render_asset::RenderAssetUsages,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn generate_packed_chunk_mesh(
|
||||||
|
chunk: &Chunk,
|
||||||
|
map: &Map,
|
||||||
|
painter: &BiomePainterAsset,
|
||||||
|
tiles: &Res<Assets<TileAsset>>,
|
||||||
|
mappers: &Res<Assets<TileMapperAsset>>,
|
||||||
|
) -> Mesh {
|
||||||
|
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
||||||
|
let mut packed_data = Vec::with_capacity(vertex_count);
|
||||||
|
let mut indices = Vec::with_capacity(vertex_count);
|
||||||
|
let mut heights = Vec::with_capacity(vertex_count);
|
||||||
|
|
||||||
|
for z in 0..Chunk::SIZE {
|
||||||
|
for x in 0..Chunk::SIZE {
|
||||||
|
let height = chunk.heights[x + z * Chunk::SIZE];
|
||||||
|
let moisture = chunk.moisture[x + z * Chunk::SIZE];
|
||||||
|
let temperature = chunk.temperature[x + z * Chunk::SIZE];
|
||||||
|
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);
|
||||||
|
let biome = mappers.get(painter.sample_biome(moisture, temperature));
|
||||||
|
let tile_handle = biome.unwrap().sample_tile(height);
|
||||||
|
let tile = tiles.get(tile_handle).unwrap();
|
||||||
|
|
||||||
|
create_packed_tile(
|
||||||
|
UVec2::new(x as u32, z as u32),
|
||||||
|
height,
|
||||||
|
&n,
|
||||||
|
&mut packed_data,
|
||||||
|
&mut indices,
|
||||||
|
&mut heights,
|
||||||
|
tile.texture_id,
|
||||||
|
tile.side_texture_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mesh = Mesh::new(
|
||||||
|
PrimitiveTopology::TriangleList,
|
||||||
|
RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD,
|
||||||
|
)
|
||||||
|
.with_inserted_attribute(ATTRIBUTE_PACKED_VERTEX_DATA, packed_data)
|
||||||
|
.with_inserted_attribute(ATTRIBUTE_VERTEX_HEIGHT, heights)
|
||||||
|
.with_inserted_indices(Indices::U32(indices));
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_packed_tile(
|
||||||
|
offset: UVec2,
|
||||||
|
height: f32,
|
||||||
|
neighbors: &[Option<f32>; 6],
|
||||||
|
packed_data: &mut Vec<u32>,
|
||||||
|
indices: &mut Vec<u32>,
|
||||||
|
heights: &mut Vec<f32>,
|
||||||
|
texture_index: u32,
|
||||||
|
side_texture_index: u32,
|
||||||
|
) {
|
||||||
|
let idx = packed_data.len() as u32;
|
||||||
|
|
||||||
|
packed_data.push(pack_vertex_data(offset, 0, texture_index));
|
||||||
|
heights.push(height);
|
||||||
|
for i in 0..6 {
|
||||||
|
packed_data.push(pack_vertex_data(offset, i + 1, texture_index));
|
||||||
|
indices.push(idx);
|
||||||
|
indices.push(idx + 1 + i as u32);
|
||||||
|
indices.push(idx + 1 + ((i as u32 + 1) % 6));
|
||||||
|
heights.push(height);
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..neighbors.len() {
|
||||||
|
let cur_n = neighbors[i];
|
||||||
|
match cur_n {
|
||||||
|
Some(n_height) => {
|
||||||
|
if n_height < height {
|
||||||
|
create_packed_tile_wall(
|
||||||
|
offset,
|
||||||
|
height,
|
||||||
|
n_height,
|
||||||
|
i,
|
||||||
|
packed_data,
|
||||||
|
indices,
|
||||||
|
heights,
|
||||||
|
side_texture_index,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_packed_tile_wall(
|
||||||
|
offset: UVec2,
|
||||||
|
height_top: f32,
|
||||||
|
height_bottom: f32,
|
||||||
|
side: usize,
|
||||||
|
packed_data: &mut Vec<u32>,
|
||||||
|
indices: &mut Vec<u32>,
|
||||||
|
heights: &mut Vec<f32>,
|
||||||
|
side_texture_index: u32,
|
||||||
|
) {
|
||||||
|
let idx = packed_data.len() as u32;
|
||||||
|
|
||||||
|
let side_2 = ((side + 1) % 6) + 1;
|
||||||
|
packed_data.push(pack_vertex_data(offset, side + 1, side_texture_index));
|
||||||
|
packed_data.push(pack_vertex_data(offset, side_2, side_texture_index));
|
||||||
|
packed_data.push(pack_vertex_data(offset, side + 1, side_texture_index));
|
||||||
|
packed_data.push(pack_vertex_data(offset, side_2, side_texture_index));
|
||||||
|
|
||||||
|
heights.push(height_top);
|
||||||
|
heights.push(height_top);
|
||||||
|
heights.push(height_bottom);
|
||||||
|
heights.push(height_bottom);
|
||||||
|
|
||||||
|
indices.push(idx);
|
||||||
|
indices.push(idx + 2);
|
||||||
|
indices.push(idx + 1);
|
||||||
|
|
||||||
|
indices.push(idx + 1);
|
||||||
|
indices.push(idx + 2);
|
||||||
|
indices.push(idx + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pack_vertex_data(offset: UVec2, vert: usize, tex: u32) -> u32 {
|
||||||
|
//6 + 6 bits offset
|
||||||
|
//4 bits vert
|
||||||
|
//12 bits texture
|
||||||
|
let mut data = offset.x;
|
||||||
|
data += (offset.y) << 6;
|
||||||
|
data += (vert as u32) << (6 + 6);
|
||||||
|
data += tex << (6 + 6 + 4);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use bevy::pbr::wireframe::WireframePlugin;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::render::texture::{ImageAddressMode, ImageFilterMode, ImageSamplerDescriptor};
|
use bevy::render::texture::{ImageAddressMode, ImageFilterMode, ImageSamplerDescriptor};
|
||||||
use bevy::window::PresentMode;
|
use bevy::window::PresentMode;
|
||||||
@@ -32,6 +33,7 @@ fn main() {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
WorldInspectorPlugin::new(),
|
WorldInspectorPlugin::new(),
|
||||||
|
WireframePlugin,
|
||||||
PhosGamePlugin,
|
PhosGamePlugin,
|
||||||
))
|
))
|
||||||
.run();
|
.run();
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::shader_extensions::chunk_material::ChunkMaterial;
|
use crate::shader_extensions::chunk_material::ChunkMaterial;
|
||||||
use bevy::asset::LoadState;
|
use bevy::asset::LoadState;
|
||||||
use bevy::pbr::ExtendedMaterial;
|
use bevy::pbr::{ExtendedMaterial, PbrPlugin};
|
||||||
use bevy::{pbr::CascadeShadowConfig, prelude::*};
|
use bevy::{
|
||||||
|
pbr::{wireframe::WireframeConfig, CascadeShadowConfig},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
use bevy_rapier3d::dynamics::{RigidBody, Velocity};
|
||||||
|
use bevy_rapier3d::geometry::{Collider, Restitution};
|
||||||
use bevy_rapier3d::plugin::{NoUserData, RapierPhysicsPlugin};
|
use bevy_rapier3d::plugin::{NoUserData, RapierPhysicsPlugin};
|
||||||
use bevy_rapier3d::render::RapierDebugRenderPlugin;
|
use camera_system::prelude::PhosCamera;
|
||||||
use camera_system::PhosCameraPlugin;
|
use camera_system::PhosCameraPlugin;
|
||||||
use iyes_perf_ui::prelude::*;
|
use iyes_perf_ui::prelude::*;
|
||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
@@ -12,6 +17,7 @@ use world_generation::biome_painter::{
|
|||||||
BiomePainterAsset, BiomePainterLoadState, BiomePainterPlugin,
|
BiomePainterAsset, BiomePainterLoadState, BiomePainterPlugin,
|
||||||
};
|
};
|
||||||
use world_generation::hex_utils::offset_to_world;
|
use world_generation::hex_utils::offset_to_world;
|
||||||
|
use world_generation::mesh_generator::generate_chunk_collider;
|
||||||
use world_generation::tile_manager::{TileAsset, TileAssetLoadState, TileAssetPlugin, TileManager};
|
use world_generation::tile_manager::{TileAsset, TileAssetLoadState, TileAssetPlugin, TileManager};
|
||||||
use world_generation::tile_mapper::{TileMapperAsset, TileMapperAssetPlugin, TileMapperLoadState};
|
use world_generation::tile_mapper::{TileMapperAsset, TileMapperAssetPlugin, TileMapperLoadState};
|
||||||
use world_generation::{
|
use world_generation::{
|
||||||
@@ -32,7 +38,7 @@ impl Plugin for PhosGamePlugin {
|
|||||||
.add_systems(Startup, (load_textures, load_tiles, create_map).chain());
|
.add_systems(Startup, (load_textures, load_tiles, create_map).chain());
|
||||||
|
|
||||||
//Systems - Update
|
//Systems - Update
|
||||||
app.add_systems(Update, (finalize_texture, spawn_map));
|
app.add_systems(Update, (finalize_texture, spawn_map, spawn_sphere));
|
||||||
|
|
||||||
//Perf UI
|
//Perf UI
|
||||||
app.add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin)
|
app.add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin)
|
||||||
@@ -45,12 +51,17 @@ impl Plugin for PhosGamePlugin {
|
|||||||
app.add_plugins(TileMapperAssetPlugin);
|
app.add_plugins(TileMapperAssetPlugin);
|
||||||
app.add_plugins(BiomePainterPlugin);
|
app.add_plugins(BiomePainterPlugin);
|
||||||
//Physics
|
//Physics
|
||||||
app.add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
|
app.add_plugins(RapierPhysicsPlugin::<NoUserData>::default());
|
||||||
.add_plugins(RapierDebugRenderPlugin::default());
|
// .add_plugins(RapierDebugRenderPlugin::default());
|
||||||
|
|
||||||
|
app.insert_resource(WireframeConfig {
|
||||||
|
global: false,
|
||||||
|
default_color: Color::hex("FF0064").unwrap(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_game(mut commands: Commands) {
|
fn init_game(mut commands: Commands, mut materials: ResMut<Assets<StandardMaterial>>) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
PerfUiRoot::default(),
|
PerfUiRoot::default(),
|
||||||
PerfUiEntryFPS::default(),
|
PerfUiEntryFPS::default(),
|
||||||
@@ -65,7 +76,7 @@ fn init_game(mut commands: Commands) {
|
|||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
cascade_shadow_config: CascadeShadowConfig {
|
cascade_shadow_config: CascadeShadowConfig {
|
||||||
bounds: vec![500., 1000., 2000., 5000.],
|
bounds: vec![500., 1000., 1500., 2000.],
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
transform: Transform::from_xyz(500., 260.0, 500.).looking_at(Vec3::ZERO, Vec3::Y),
|
transform: Transform::from_xyz(500., 260.0, 500.).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
@@ -74,6 +85,13 @@ fn init_game(mut commands: Commands) {
|
|||||||
|
|
||||||
commands.insert_resource(PhosMap::default());
|
commands.insert_resource(PhosMap::default());
|
||||||
commands.insert_resource(TileManager::default());
|
commands.insert_resource(TileManager::default());
|
||||||
|
|
||||||
|
let sphere_mat = StandardMaterial {
|
||||||
|
base_color: Color::CYAN,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
let handle = materials.add(sphere_mat);
|
||||||
|
commands.insert_resource(SphereMat(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_textures(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn load_textures(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
@@ -221,14 +239,16 @@ fn spawn_map(
|
|||||||
.map(|chunk: &Chunk| {
|
.map(|chunk: &Chunk| {
|
||||||
let mesh =
|
let mesh =
|
||||||
generate_chunk_mesh(chunk, &heightmap, cur_painter, &tile_assets, &tile_mappers);
|
generate_chunk_mesh(chunk, &heightmap, cur_painter, &tile_assets, &tile_mappers);
|
||||||
|
let collision = generate_chunk_collider(chunk, &heightmap);
|
||||||
return (
|
return (
|
||||||
mesh,
|
mesh,
|
||||||
|
collision,
|
||||||
offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.),
|
offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for (mesh, pos) in chunk_meshes {
|
for (mesh, (col_verts, col_indicies), pos) in chunk_meshes {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
MaterialMeshBundle {
|
MaterialMeshBundle {
|
||||||
mesh: meshes.add(mesh),
|
mesh: meshes.add(mesh),
|
||||||
@@ -237,30 +257,36 @@ fn spawn_map(
|
|||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
PhosChunk,
|
PhosChunk,
|
||||||
|
Collider::trimesh(col_verts, col_indicies),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// for chunk in &heightmap.chunks {
|
|
||||||
// let mesh = generate_chunk_mesh(
|
|
||||||
// &chunk,
|
|
||||||
// &heightmap,
|
|
||||||
// b_painter.unwrap(),
|
|
||||||
// &tile_assets,
|
|
||||||
// &tile_mappers,
|
|
||||||
// );
|
|
||||||
// let pos = offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.);
|
|
||||||
// commands.spawn((
|
|
||||||
// MaterialMeshBundle {
|
|
||||||
// mesh: meshes.add(mesh),
|
|
||||||
// material: chunk_material.clone(),
|
|
||||||
// transform: Transform::from_translation(pos),
|
|
||||||
// ..default()
|
|
||||||
// },
|
|
||||||
// PhosChunk::from_translation(pos),
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct SphereMat(Handle<StandardMaterial>);
|
||||||
|
|
||||||
|
fn spawn_sphere(
|
||||||
|
mut commands: Commands,
|
||||||
|
cam: Query<&Transform, With<PhosCamera>>,
|
||||||
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
mat: Res<SphereMat>,
|
||||||
|
) {
|
||||||
|
if keyboard_input.just_pressed(KeyCode::KeyF) {
|
||||||
|
let cam_transform = cam.single();
|
||||||
|
commands.spawn((
|
||||||
|
MaterialMeshBundle {
|
||||||
|
mesh: meshes.add(Sphere::new(0.5)),
|
||||||
|
material: mat.0.clone(),
|
||||||
|
transform: Transform::from_translation(cam_transform.translation),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
Collider::ball(0.5),
|
||||||
|
RigidBody::Dynamic,
|
||||||
|
Velocity::linear(cam_transform.forward() * 100.),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
// fn render_distance_system(
|
// fn render_distance_system(
|
||||||
// mut chunks: Query<(&PhosChunk, &mut Visibility)>,
|
// mut chunks: Query<(&PhosChunk, &mut Visibility)>,
|
||||||
// camera: Query<&Transform, With<PhosCamera>>,
|
// camera: Query<&Transform, With<PhosCamera>>,
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
use bevy::asset::{Asset, Handle};
|
use bevy::asset::{Asset, Handle};
|
||||||
use bevy::pbr::MaterialExtension;
|
use bevy::pbr::MaterialExtension;
|
||||||
use bevy::reflect::TypePath;
|
use bevy::reflect::TypePath;
|
||||||
use bevy::render::mesh::Mesh;
|
|
||||||
use bevy::render::render_resource::{AsBindGroup, ShaderRef};
|
use bevy::render::render_resource::{AsBindGroup, ShaderRef};
|
||||||
use bevy::render::texture::Image;
|
use bevy::render::texture::Image;
|
||||||
use world_generation::prelude::{ATTRIBUTE_PACKED_VERTEX_DATA, ATTRIBUTE_VERTEX_HEIGHT};
|
|
||||||
|
|
||||||
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
|
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
|
||||||
pub struct ChunkMaterial {
|
pub struct ChunkMaterial {
|
||||||
|
|||||||
Reference in New Issue
Block a user