mesh_tools/
builder_material.rs

1use crate::builder::GltfBuilder;
2use crate::material;
3
4impl GltfBuilder {
5    /// Add a customizable PBR material to the glTF document
6    /// 
7    /// This function allows you to create a fully customizable PBR (Physically Based Rendering) material
8    /// with control over base color, metallic factor, roughness factor, and double-sided rendering.
9    /// 
10    /// # Parameters
11    /// 
12    /// * `name` - Optional name for the material
13    /// * `base_color` - Optional RGBA color array `[r, g, b, a]` where each component is in range 0.0-1.0
14    /// * `metallic_factor` - Optional metallic property (0.0 = non-metal, 1.0 = metal)
15    /// * `roughness_factor` - Optional roughness property (0.0 = smooth, 1.0 = rough)
16    /// * `double_sided` - Optional flag to enable double-sided rendering
17    /// 
18    /// # Returns
19    /// 
20    /// The index of the created material in the glTF document
21    /// 
22    /// # Examples
23    /// 
24    /// ```rust
25    /// use mesh_tools::GltfBuilder;
26    /// 
27    /// let mut builder = GltfBuilder::new();
28    /// 
29    /// // Create a shiny blue metal material
30    /// let blue_metal = builder.add_material(
31    ///     Some("Blue Metal".to_string()),
32    ///     Some([0.1, 0.2, 0.8, 1.0]),  // Blue color
33    ///     Some(0.9),                    // Highly metallic
34    ///     Some(0.2),                    // Low roughness (shiny)
35    ///     Some(false)                   // Single-sided
36    /// );
37    /// 
38    /// // Create a rough plastic material
39    /// let red_plastic = builder.add_material(
40    ///     Some("Red Plastic".to_string()),
41    ///     Some([0.8, 0.1, 0.1, 1.0]),  // Red color
42    ///     Some(0.0),                    // Non-metallic
43    ///     Some(0.8),                    // High roughness
44    ///     Some(true)                    // Double-sided
45    /// );
46    /// 
47    /// // Create a simple material with defaults for some properties
48    /// let green_material = builder.add_material(
49    ///     Some("Green".to_string()),
50    ///     Some([0.1, 0.8, 0.1, 1.0]),  // Green color
51    ///     None,                         // Default metallic factor
52    ///     None,                         // Default roughness factor
53    ///     None                          // Default single-sided
54    /// );
55    /// 
56    /// // Use the material with a mesh
57    /// let cube = builder.create_box(1.0, Some(blue_metal));
58    /// ```
59    pub fn add_material(&mut self, name: Option<String>, 
60                        base_color: Option<[f32; 4]>,
61                        metallic_factor: Option<f32>,
62                        roughness_factor: Option<f32>,
63                        double_sided: Option<bool>) -> usize {
64        let mut builder = material::MaterialBuilder::new(name);
65        
66        if let Some(color) = base_color {
67            builder = builder.with_base_color(color);
68        }
69        
70        if let Some(metallic) = metallic_factor {
71            builder = builder.with_metallic_factor(metallic);
72        }
73        
74        if let Some(roughness) = roughness_factor {
75            builder = builder.with_roughness_factor(roughness);
76        }
77        
78        if let Some(double_sided) = double_sided {
79            builder = builder.with_double_sided(double_sided);
80        }
81        
82        let material = builder.build();
83        
84        if let Some(materials) = &mut self.gltf.materials {
85            let index = materials.len();
86            materials.push(material);
87            index
88        } else {
89            self.gltf.materials = Some(vec![material]);
90            0
91        }
92    }
93
94    /// Create a basic material with the specified color
95    pub fn create_basic_material(&mut self, name: Option<String>, color: [f32; 4]) -> usize {
96        let material = material::create_basic_material(name, color);
97        
98        if let Some(materials) = &mut self.gltf.materials {
99            let index = materials.len();
100            materials.push(material);
101            index
102        } else {
103            self.gltf.materials = Some(vec![material]);
104            0
105        }
106    }
107
108    /// Create a metallic material
109    pub fn create_metallic_material(&mut self, name: Option<String>, 
110                                   color: [f32; 4], 
111                                   metallic: f32,
112                                   roughness: f32) -> usize {
113        let material = material::create_metallic_material(name, color, metallic, roughness);
114        
115        if let Some(materials) = &mut self.gltf.materials {
116            let index = materials.len();
117            materials.push(material);
118            index
119        } else {
120            self.gltf.materials = Some(vec![material]);
121            0
122        }
123    }
124}