1use crate::builder::GltfBuilder;
2use crate::constants::{sampler_filter, sampler_wrap};
3use crate::error::Result;
4use crate::models::{Image, Sampler, Texture};
5use crate::texture;
6use image::DynamicImage;
7
8impl GltfBuilder {
9 pub fn add_textured_material(&mut self, name: Option<String>,
11 base_color_texture: Option<usize>,
12 metallic_roughness_texture: Option<usize>,
13 normal_texture: Option<usize>,
14 occlusion_texture: Option<usize>,
15 emissive_texture: Option<usize>,
16 emissive_factor: Option<[f32; 3]>,
17 metallic_factor: Option<f32>,
18 roughness_factor: Option<f32>,
19 alpha_mode: Option<String>,
20 alpha_cutoff: Option<f32>,
21 double_sided: Option<bool>) -> usize {
22 use crate::material;
23
24 let material = material::create_textured_material(
25 name,
26 base_color_texture,
27 metallic_roughness_texture,
28 normal_texture,
29 occlusion_texture,
30 emissive_texture,
31 emissive_factor,
32 metallic_factor,
33 roughness_factor,
34 alpha_mode,
35 alpha_cutoff,
36 double_sided
37 );
38
39 if let Some(materials) = &mut self.gltf.materials {
40 let index = materials.len();
41 materials.push(material);
42 index
43 } else {
44 self.gltf.materials = Some(vec![material]);
45 0
46 }
47 }
48
49 pub fn create_textured_material(&mut self, name: Option<String>,
51 base_color_texture: usize) -> usize {
52 self.add_textured_material(
53 name,
54 Some(base_color_texture),
55 None,
56 None,
57 None,
58 None,
59 None,
60 Some(1.0),
61 Some(1.0),
62 None,
63 None,
64 None
65 )
66 }
67
68 pub(crate) fn add_image_from_dynamic_image(&mut self, name: Option<String>,
70 image: &DynamicImage,
71 format: texture::TextureFormat) -> Result<usize> {
72 let bytes = texture::image_to_bytes(image, format)?;
73
74 Ok(self.add_image_from_buffer(name, format.mime_type().to_string(), &bytes))
75 }
76
77 pub fn create_default_sampler(&mut self) -> usize {
79 self.add_sampler(
80 Some(sampler_filter::LINEAR),
81 Some(sampler_filter::LINEAR_MIPMAP_LINEAR),
82 Some(sampler_wrap::REPEAT),
83 Some(sampler_wrap::REPEAT)
84 )
85 }
86
87 pub fn create_texture_from_image(&mut self, name: Option<String>,
89 image: &DynamicImage,
90 format: texture::TextureFormat) -> Result<usize> {
91 let image_index = self.add_image_from_dynamic_image(name.clone(), image, format)?;
93
94 let sampler_index = self.create_default_sampler();
96
97 Ok(self.add_texture(name, image_index, Some(sampler_index)))
99 }
100
101 pub fn create_checkerboard_texture(&mut self,
103 width: u32,
104 height: u32,
105 cell_size: u32,
106 color1: [u8; 3],
107 color2: [u8; 3]) -> Result<usize> {
108 let image = texture::create_colored_checkerboard(
109 width,
110 height,
111 cell_size,
112 color1,
113 color2
114 );
115
116 self.create_texture_from_image(Some("checkerboard".to_string()), &image, texture::TextureFormat::PNG)
117 }
118
119 pub fn create_uv_test_texture(&mut self, width: u32, height: u32) -> Result<usize> {
121 let image = texture::create_uv_test_pattern(width, height);
122
123 self.create_texture_from_image(Some("uv_test".to_string()), &image, texture::TextureFormat::PNG)
124 }
125
126 pub(crate) fn add_sampler(&mut self, mag_filter: Option<usize>, min_filter: Option<usize>,
128 wrap_s: Option<usize>, wrap_t: Option<usize>) -> usize {
129 let sampler = Sampler {
130 mag_filter: mag_filter,
131 min_filter: min_filter,
132 wrap_s: wrap_s,
133 wrap_t: wrap_t,
134 };
135
136 if let Some(samplers) = &mut self.gltf.samplers {
137 let index = samplers.len();
138 samplers.push(sampler);
139 index
140 } else {
141 self.gltf.samplers = Some(vec![sampler]);
142 0
143 }
144 }
145
146 pub(crate) fn add_image_from_buffer(&mut self, name: Option<String>,
148 mime_type: String, data: &[u8]) -> usize {
149 let (offset, length) = self.add_buffer_data(data);
151
152 let buffer_view = self.add_buffer_view(offset, length, None);
154
155 let image = Image {
157 name,
158 uri: None,
159 mime_type: Some(mime_type),
160 buffer_view: Some(buffer_view),
161 };
162
163 if let Some(images) = &mut self.gltf.images {
164 let index = images.len();
165 images.push(image);
166 index
167 } else {
168 self.gltf.images = Some(vec![image]);
169 0
170 }
171 }
172
173 pub(crate) fn add_texture(&mut self, name: Option<String>, source: usize,
175 sampler: Option<usize>) -> usize {
176 let texture = Texture {
177 name,
178 source,
179 sampler,
180 };
181
182 if let Some(textures) = &mut self.gltf.textures {
183 let index = textures.len();
184 textures.push(texture);
185 index
186 } else {
187 self.gltf.textures = Some(vec![texture]);
188 0
189 }
190 }
191}