Skip to content

Commit

Permalink
Expose VoxelData
Browse files Browse the repository at this point in the history
  • Loading branch information
Utsira committed Jan 27, 2024
1 parent 90c823c commit f1286af
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 19 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ All Magica Voxel material types except "cloud" are supported. Bevy's screen spac

## Usage

1. Add the crate using cargo: `cargo add bevy_vox_scene`
1. Add the crate using the command line (`cargo add bevy_vox_scene`) or by adding it to `Cargo.toml`:

```toml
[dependencies]
bevy_vox_scene = "0.11.4"
```

Then in code:

Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![forbid(missing_docs, unsafe_code)]
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
//! A plugin for the Bevy engine which allows loading Magica Voxel .vox files as scene graphs.
//!
//!```
Expand Down Expand Up @@ -43,8 +45,6 @@
//! # exit.send(AppExit);
//! # }
//!```
#![forbid(missing_docs, unsafe_code)]
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
use bevy::{
app::{App, Plugin, SpawnScene},
Expand All @@ -65,7 +65,7 @@ use load::VoxSceneLoader;
pub use model::{
modify::{ModifyVoxelCommandsExt, VoxelRegion, VoxelRegionMode},
queryable::VoxelQueryable,
Voxel, VoxelModel,
Voxel, VoxelData, VoxelModel,
};
pub use scene::{
VoxelLayer, VoxelModelInstance, VoxelScene, VoxelSceneBundle, VoxelSceneHook,
Expand Down
29 changes: 23 additions & 6 deletions src/model/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bevy::{
asset::{Asset, Handle},
asset::{Asset, Assets, Handle},
ecs::system::ResMut,
pbr::StandardMaterial,
reflect::TypePath,
render::mesh::Mesh,
Expand Down Expand Up @@ -28,14 +29,30 @@ pub struct VoxelModel {
pub(crate) material: Handle<StandardMaterial>,
}

impl VoxelModel {
/// Create a new VoxelModel from [`VoxelData`]
pub fn new(
data: VoxelData,
meshes: &mut ResMut<Assets<Mesh>>,
material: Handle<StandardMaterial>,
) -> Self {
let mesh = data.remesh();
VoxelModel {
data,
mesh: meshes.add(mesh),
material,
}
}
}

/// The voxel data used to create a mesh and a material.
///
/// Note that all coordinates are in Bevy's right-handed Y-up space
pub(crate) struct VoxelData {
pub shape: RuntimeShape<u32, 3>,
pub voxels: Vec<RawVoxel>,
pub ior_for_voxel: HashMap<u8, f32>,
pub mesh_outer_faces: bool,
pub struct VoxelData {
pub(crate) shape: RuntimeShape<u32, 3>,
pub(crate) voxels: Vec<RawVoxel>,
pub(crate) ior_for_voxel: HashMap<u8, f32>,
pub(crate) mesh_outer_faces: bool,
}

impl Default for VoxelData {
Expand Down
26 changes: 25 additions & 1 deletion src/model/queryable.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{Voxel, VoxelData, VoxelModel};
use super::{RawVoxel, Voxel, VoxelData, VoxelModel};
use bevy::{
math::{BVec3, IVec3, UVec3, Vec3},
transform::components::GlobalTransform,
Expand Down Expand Up @@ -93,6 +93,30 @@ impl VoxelQueryable for VoxelData {
Some(voxel)
}
}

#[derive(Debug, Clone)]
pub struct OutOfBoundsError;

impl VoxelData {
/// Writes a voxel to a point in the model
///
/// ### Arguments
/// * `voxel` - the [`Voxel`] to be written
/// * `point` - the position at which the voxel will be written
///
/// ### Returns
/// `Ok(())` if the operation was successful, or [`OutOfBoundsError`] if `point` lies outside the model
pub fn set_voxel(&mut self, voxel: Voxel, point: Vec3) -> Result<(), OutOfBoundsError> {
let position = self
.point_in_model(point.as_ivec3())
.ok_or(OutOfBoundsError)?;
let leading_padding = UVec3::splat(self.padding() / 2);
let index = self.shape.linearize((position + leading_padding).into()) as usize;
let raw_voxel: RawVoxel = voxel.into();
self.voxels[index] = raw_voxel;
Ok(())
}
}
trait BitwiseComparable {
fn less_than(&self, other: Self) -> BVec3;

Expand Down
2 changes: 1 addition & 1 deletion src/scene/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub use hook::VoxelSceneHook;
/// The root of the spawned scene will be the entity that has this bundle.
/// In addition to the standard components bevy uses to organise and render pbr meshes,
/// spawned entities will also have [`VoxelLayer`] and [`VoxelModelInstance`] components added.
/// ```no_run
/// ```
/// # use bevy::prelude::*;
/// # use bevy_vox_scene::VoxelSceneBundle;
///
Expand Down
15 changes: 8 additions & 7 deletions src/scene/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,14 @@ fn spawn_voxel_node_recursive(
}
if let Some(model_handle) = &voxel_node.model_id.and_then(|id| scene.models.get(id)) {
if let Some(model) = vox_models.get(*model_handle) {
entity_commands.insert(VoxelModelInstance((**model_handle).clone()));
#[cfg(not(test))]
entity_commands.insert(PbrBundle {
mesh: model.mesh.clone(),
material: model.material.clone(),
..Default::default()
});
entity_commands.insert((
VoxelModelInstance((**model_handle).clone()),
PbrBundle {
mesh: model.mesh.clone(),
material: model.material.clone(),
..Default::default()
},
));
} else {
warn!("Model not found, omitting: {:?}", model_handle);
entity_commands.insert(SpatialBundle::default());
Expand Down

0 comments on commit f1286af

Please sign in to comment.