-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
145 additions
and
153 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,73 @@ | ||
use building_blocks::mesh::{OrientedCubeFace, UnorientedQuad}; | ||
|
||
/// Helper struct to organize mesh data for bevy. | ||
#[derive(Default)] | ||
pub(crate) struct VoxMesh { | ||
pub positions: Vec<[f32; 3]>, | ||
pub normals: Vec<[f32; 3]>, | ||
pub colors: Vec<[u8; 4]>, | ||
pub uvs: Vec<[f32; 2]>, | ||
pub indices: Vec<u32>, | ||
} | ||
use bevy::render::{ | ||
mesh::{Indices, Mesh, VertexAttributeValues}, | ||
render_resource::PrimitiveTopology, | ||
}; | ||
use block_mesh::{greedy_quads, GreedyQuadsBuffer, QuadCoordinateConfig}; | ||
use ndshape::{Shape, Shape3u32}; | ||
|
||
impl VoxMesh { | ||
pub(crate) fn add_quad( | ||
&mut self, | ||
face: &OrientedCubeFace, | ||
quad: &UnorientedQuad, | ||
palette_index: u32, | ||
palette: &[[u8; 4]], | ||
flip_v: bool | ||
) { | ||
let start_index = self.positions.len() as u32; | ||
use crate::voxel::Voxel; | ||
|
||
//todo: maybe use u8's instead of f32's for position and normal attributes since magica voxel max size per model per dimension is 256. | ||
pub(crate) fn mesh_model( | ||
buffer_shape: Shape3u32, | ||
buffer: &[Voxel], | ||
palette: &[[u8; 4]], | ||
quads_config: &QuadCoordinateConfig, | ||
v_flip_face: bool, | ||
) -> Mesh { | ||
let mut greedy_quads_buffer = GreedyQuadsBuffer::new(buffer_shape.size() as usize); | ||
|
||
self.positions | ||
.extend_from_slice(&face.quad_mesh_positions(quad)); | ||
greedy_quads( | ||
buffer, | ||
&buffer_shape, | ||
[0; 3], | ||
buffer_shape.as_array().map(|x| x - 1), | ||
&quads_config.faces, | ||
&mut greedy_quads_buffer, | ||
); | ||
|
||
self.normals.extend_from_slice(&face.quad_mesh_normals()); | ||
let num_indices = greedy_quads_buffer.quads.num_quads() * 6; | ||
let num_vertices = greedy_quads_buffer.quads.num_quads() * 4; | ||
|
||
self.colors | ||
.extend_from_slice(&[palette[palette_index as usize]; 4]); | ||
let mut indices = Vec::with_capacity(num_indices); | ||
let mut positions = Vec::with_capacity(num_vertices); | ||
let mut normals = Vec::with_capacity(num_vertices); | ||
let mut uvs = Vec::with_capacity(num_vertices); | ||
let mut colors = Vec::with_capacity(num_vertices); | ||
|
||
self.uvs | ||
.extend_from_slice(&face.simple_tex_coords(flip_v, &quad)); | ||
let mut render_mesh = Mesh::new(PrimitiveTopology::TriangleList); | ||
|
||
self.indices | ||
.extend_from_slice(&face.quad_mesh_indices(start_index)); | ||
for (group, face) in greedy_quads_buffer | ||
.quads | ||
.groups | ||
.iter() | ||
.zip(quads_config.faces.as_ref()) | ||
{ | ||
for quad in group.iter() { | ||
let palette_index = buffer[buffer_shape.linearize(quad.minimum) as usize].0; | ||
colors.extend_from_slice(&[palette[palette_index as usize]; 4]); | ||
indices.extend_from_slice(&face.quad_mesh_indices(positions.len() as u32)); | ||
positions.extend_from_slice(&face.quad_mesh_positions(quad, 1.0)); | ||
uvs.extend_from_slice(&face.tex_coords(quads_config.u_flip_face, v_flip_face, quad)); | ||
normals.extend_from_slice(&face.quad_mesh_normals()); | ||
} | ||
} | ||
|
||
render_mesh.set_attribute( | ||
Mesh::ATTRIBUTE_POSITION, | ||
VertexAttributeValues::Float32x3(positions), | ||
); | ||
|
||
render_mesh.set_attribute( | ||
Mesh::ATTRIBUTE_NORMAL, | ||
VertexAttributeValues::Float32x3(normals), | ||
); | ||
render_mesh.set_attribute(Mesh::ATTRIBUTE_UV_0, VertexAttributeValues::Float32x2(uvs)); | ||
render_mesh.set_attribute( | ||
Mesh::ATTRIBUTE_COLOR, | ||
VertexAttributeValues::Unorm8x4(colors), | ||
); | ||
|
||
render_mesh.set_indices(Some(Indices::U32(indices.clone()))); | ||
|
||
render_mesh | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use block_mesh::{MergeVoxel, Voxel as BlockyVoxel}; | ||
use dot_vox::Model; | ||
use ndshape::{Shape, Shape3u32}; | ||
|
||
// trait implementation rules requires the use of a newtype to allow meshing. | ||
#[derive(Clone, Copy, PartialEq, Eq)] | ||
pub(crate) struct Voxel(pub(crate) u8); | ||
|
||
pub(crate) const EMPTY_VOXEL: Voxel = Voxel(255); | ||
|
||
impl BlockyVoxel for Voxel { | ||
fn is_empty(&self) -> bool { | ||
self.0 == EMPTY_VOXEL.0 | ||
} | ||
|
||
fn is_opaque(&self) -> bool { | ||
self.0 != EMPTY_VOXEL.0 | ||
} | ||
} | ||
|
||
impl MergeVoxel for Voxel { | ||
type MergeValue = Voxel; | ||
|
||
fn merge_value(&self) -> Self::MergeValue { | ||
*self | ||
} | ||
} | ||
|
||
pub(crate) fn load_from_model(model: &Model) -> (Shape3u32, Vec<Voxel>) { | ||
let model_shape = Shape3u32::new([model.size.x + 2, model.size.z + 2, model.size.y + 2]); | ||
let mut data = vec![EMPTY_VOXEL; model_shape.size() as usize]; | ||
|
||
model.voxels.iter().for_each(|voxel| { | ||
let index = | ||
model_shape.linearize([voxel.x as u32 + 1, voxel.z as u32 + 1, voxel.y as u32 + 1]) | ||
as usize; | ||
data[index] = Voxel(voxel.i); | ||
}); | ||
|
||
(model_shape, data) | ||
} |