@@ -7,6 +7,7 @@ use bevy::{
77 asset:: { io:: Reader , AssetLoader , AsyncReadExt , Handle , LoadContext } ,
88 color:: LinearRgba ,
99 log:: info,
10+ math:: Vec3 ,
1011 pbr:: StandardMaterial ,
1112 scene:: Scene ,
1213 utils:: HashSet ,
@@ -33,17 +34,18 @@ pub(super) struct VoxSceneLoader {
3334}
3435
3536/// Settings for the VoxSceneLoader.
36- #[ derive( Serialize , Deserialize , Clone ) ]
37+ #[ derive( Serialize , Deserialize , Clone , Debug ) ]
3738pub struct VoxLoaderSettings {
3839 /// The length of each side of a single voxel. Defaults to 1.0.
3940 pub voxel_size : f32 ,
4041 /// Whether the outer-most faces of the model should be meshed. Defaults to true. Set this to false if the outer faces of a
4142 /// model will never be visible, for instance if the model id part of a 3D tileset.
4243 pub mesh_outer_faces : bool ,
43- /// Multiplier for emissive strength. Defaults to 2.0.
44+ /// Amount that the vertex positions of the mesh will be offset described as unit of their size.
45+ /// Defaults to [`UnitOffset::CENTER`] the center of the model, as this is where MagicaVoxel places the origin in its world editor
46+ pub mesh_offset : UnitOffset ,
47+ /// Multiplier for emissive strength. Defaults to 10.0.
4448 pub emission_strength : f32 ,
45- /// Defaults to `true` to more accurately reflect the colours in Magica Voxel.
46- pub uses_srgb : bool ,
4749 /// Magica Voxel doesn't let you adjust the roughness for the default "diffuse" block type, so it can be adjusted with this setting. Defaults to 0.8.
4850 pub diffuse_roughness : f32 ,
4951}
@@ -53,13 +55,30 @@ impl Default for VoxLoaderSettings {
5355 Self {
5456 voxel_size : 1.0 ,
5557 mesh_outer_faces : true ,
58+ mesh_offset : UnitOffset :: CENTER ,
5659 emission_strength : 10.0 ,
57- uses_srgb : true ,
5860 diffuse_roughness : 0.8 ,
5961 }
6062 }
6163}
6264
65+ /// An offset applied to the vertex positions of the mesh expressed as a unit of the mesh's size.
66+ /// For a fully centered mesh, use [`UnitOffset::CENTER`]
67+ /// For a mesh centred around it's base, use [`UnitOffset::CENTER_BASE`]
68+ #[ derive( Serialize , Deserialize , Clone , Debug ) ]
69+ pub struct UnitOffset ( pub ( crate ) Vec3 ) ;
70+
71+ impl UnitOffset {
72+ /// Vertex positions will not be offset at all, so that the origin will be the minimum of the model's AABB
73+ pub const ZERO : Self = UnitOffset ( Vec3 :: ZERO ) ;
74+
75+ /// Offset representing the center of a model
76+ pub const CENTER : Self = UnitOffset ( Vec3 :: splat ( 0.5 ) ) ;
77+
78+ /// Offset representing the center base of a model
79+ pub const CENTER_BASE : Self = UnitOffset ( Vec3 :: new ( 0.5 , 0.0 , 0.5 ) ) ;
80+ }
81+
6382#[ derive( Error , Debug ) ]
6483pub enum VoxLoaderError {
6584 #[ error( transparent) ]
@@ -160,8 +179,7 @@ impl VoxSceneLoader {
160179 . enumerate ( )
161180 . for_each ( |( index, ( maybe_name, model) ) | {
162181 let name = maybe_name. clone ( ) . unwrap_or ( format ! ( "model-{}" , index) ) ;
163- let data =
164- VoxelData :: from_model ( & model, settings. mesh_outer_faces , settings. voxel_size ) ;
182+ let data = VoxelData :: from_model ( & model, settings. clone ( ) ) ;
165183 let ( visible_voxels, ior) = data. visible_voxels ( & indices_of_refraction) ;
166184 let mesh = load_context. labeled_asset_scope ( format ! ( "{}@mesh" , name) , |_| {
167185 crate :: model:: mesh:: mesh_model ( & visible_voxels, & data)
0 commit comments