Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_pbr/src/gltf.rs
30635 views
1
use bevy_gltf::{
2
extensions::{ErasedGltfExtensionHandler, GltfExtensionHandler, GltfExtensionHandlers},
3
gltf, GltfAssetLabel, GltfMaterial,
4
};
5
6
use crate::{MeshMaterial3d, StandardMaterial};
7
use bevy_app::App;
8
use bevy_asset::Handle;
9
use bevy_ecs::prelude::*;
10
11
use bevy_asset::LoadContext;
12
13
pub(crate) fn add_gltf(app: &mut App) {
14
#[cfg(target_family = "wasm")]
15
bevy_tasks::block_on(async {
16
app.world_mut()
17
.resource_mut::<GltfExtensionHandlers>()
18
.0
19
.write()
20
.await
21
.push(Box::new(GltfExtensionHandlerPbr));
22
});
23
24
#[cfg(not(target_family = "wasm"))]
25
app.world_mut()
26
.resource_mut::<GltfExtensionHandlers>()
27
.0
28
.write_blocking()
29
.push(Box::new(GltfExtensionHandlerPbr));
30
}
31
32
/// Converts a [`GltfMaterial`] to a [`StandardMaterial`]
33
pub fn standard_material_from_gltf_material(material: &GltfMaterial) -> StandardMaterial {
34
StandardMaterial {
35
base_color: material.base_color,
36
base_color_channel: material.base_color_channel.clone(),
37
base_color_texture: material.base_color_texture.clone(),
38
emissive: material.emissive,
39
emissive_channel: material.emissive_channel.clone(),
40
emissive_texture: material.emissive_texture.clone(),
41
perceptual_roughness: material.perceptual_roughness,
42
metallic: material.metallic,
43
metallic_roughness_channel: material.metallic_roughness_channel.clone(),
44
metallic_roughness_texture: material.metallic_roughness_texture.clone(),
45
reflectance: material.reflectance,
46
specular_tint: material.specular_tint,
47
specular_transmission: material.specular_transmission,
48
#[cfg(feature = "pbr_transmission_textures")]
49
specular_transmission_channel: material.specular_transmission_channel.clone(),
50
#[cfg(feature = "pbr_transmission_textures")]
51
specular_transmission_texture: material.specular_transmission_texture.clone(),
52
thickness: material.thickness,
53
#[cfg(feature = "pbr_transmission_textures")]
54
thickness_channel: material.thickness_channel.clone(),
55
#[cfg(feature = "pbr_transmission_textures")]
56
thickness_texture: material.thickness_texture.clone(),
57
ior: material.ior,
58
attenuation_distance: material.attenuation_distance,
59
attenuation_color: material.attenuation_color,
60
normal_map_channel: material.normal_map_channel.clone(),
61
normal_map_texture: material.normal_map_texture.clone(),
62
occlusion_channel: material.occlusion_channel.clone(),
63
occlusion_texture: material.occlusion_texture.clone(),
64
#[cfg(feature = "pbr_specular_textures")]
65
specular_channel: material.specular_channel.clone(),
66
#[cfg(feature = "pbr_specular_textures")]
67
specular_texture: material.specular_texture.clone(),
68
#[cfg(feature = "pbr_specular_textures")]
69
specular_tint_channel: material.specular_tint_channel.clone(),
70
#[cfg(feature = "pbr_specular_textures")]
71
specular_tint_texture: material.specular_tint_texture.clone(),
72
clearcoat: material.clearcoat,
73
clearcoat_perceptual_roughness: material.clearcoat_perceptual_roughness,
74
#[cfg(feature = "pbr_multi_layer_material_textures")]
75
clearcoat_roughness_channel: material.clearcoat_roughness_channel.clone(),
76
#[cfg(feature = "pbr_multi_layer_material_textures")]
77
clearcoat_roughness_texture: material.clearcoat_roughness_texture.clone(),
78
#[cfg(feature = "pbr_multi_layer_material_textures")]
79
clearcoat_normal_channel: material.clearcoat_normal_channel.clone(),
80
#[cfg(feature = "pbr_multi_layer_material_textures")]
81
clearcoat_normal_texture: material.clearcoat_normal_texture.clone(),
82
anisotropy_strength: material.anisotropy_strength,
83
anisotropy_rotation: material.anisotropy_rotation,
84
#[cfg(feature = "pbr_anisotropy_texture")]
85
anisotropy_channel: material.anisotropy_channel.clone(),
86
#[cfg(feature = "pbr_anisotropy_texture")]
87
anisotropy_texture: material.anisotropy_texture.clone(),
88
double_sided: material.double_sided,
89
cull_mode: material.cull_mode,
90
unlit: material.unlit,
91
alpha_mode: material.alpha_mode,
92
uv_transform: material.uv_transform,
93
..Default::default()
94
}
95
}
96
97
#[derive(Default, Clone)]
98
struct GltfExtensionHandlerPbr;
99
100
impl GltfExtensionHandler for GltfExtensionHandlerPbr {
101
fn dyn_clone(&self) -> Box<dyn ErasedGltfExtensionHandler> {
102
Box::new((*self).clone())
103
}
104
fn on_root(
105
&mut self,
106
load_context: &mut LoadContext<'_>,
107
_gltf: &gltf::Gltf,
108
_settings: &bevy_gltf::GltfLoaderSettings,
109
) {
110
// create the `StandardMaterial` for the glTF `DefaultMaterial` so
111
// it can be accessed when meshes don't have materials.
112
let std_label = format!("{}/std", GltfAssetLabel::DefaultMaterial);
113
114
load_context.add_labeled_asset(
115
std_label,
116
standard_material_from_gltf_material(&GltfMaterial::default()),
117
);
118
}
119
120
fn on_material(
121
&mut self,
122
load_context: &mut LoadContext<'_>,
123
_gltf_material: &gltf::Material,
124
_material: Handle<GltfMaterial>,
125
material_asset: &GltfMaterial,
126
material_label: &str,
127
) {
128
let std_label = format!("{}/std", material_label);
129
130
load_context.add_labeled_asset(
131
std_label,
132
standard_material_from_gltf_material(material_asset),
133
);
134
}
135
136
fn on_spawn_mesh_and_material(
137
&mut self,
138
load_context: &mut LoadContext<'_>,
139
_primitive: &gltf::Primitive,
140
_mesh: &gltf::Mesh,
141
_material: &gltf::Material,
142
entity: &mut EntityWorldMut,
143
material_label: &str,
144
) {
145
let std_label = format!("{}/std", material_label);
146
let handle = load_context.get_label_handle::<StandardMaterial>(std_label);
147
148
entity.insert(MeshMaterial3d(handle));
149
}
150
}
151
152