roast2d_internal 0.4.0

Roast2D internal crate
Documentation
use glam::Mat4;

use crate::color::{Color, WHITE};
use crate::handle::Handle;
use crate::light3d::Material3D;
use crate::mesh3d::{DrawMode, InstanceData, Mesh3D};

/// A single 3D draw call instance
pub struct Draw3D {
    pub mesh: Mesh3D,
    pub model: Mat4,
    /// Optional texture handle. If None, uses vertex colors/UV colors.
    pub texture: Option<Handle>,
    /// Color tint applied to the mesh (multiplied with texture or base color)
    pub color: Color,
    /// Material properties for lighting
    pub material: Material3D,
    /// Draw mode (Solid, Wireframe, or Points)
    pub draw_mode: DrawMode,
}

impl Draw3D {
    pub fn new(mesh: Mesh3D, model: Mat4) -> Self {
        Self {
            mesh,
            model,
            texture: None,
            color: WHITE,
            material: Material3D::default(),
            draw_mode: DrawMode::default(),
        }
    }

    /// Set the texture for this draw call.
    pub fn with_texture(mut self, texture: Handle) -> Self {
        self.texture = Some(texture);
        self
    }

    /// Set the color tint for this draw call.
    pub fn with_color(mut self, color: Color) -> Self {
        self.color = color;
        self
    }

    /// Set the material for this draw call.
    pub fn with_material(mut self, material: Material3D) -> Self {
        self.material = material;
        self
    }

    /// Set the draw mode for this draw call.
    pub fn with_draw_mode(mut self, draw_mode: DrawMode) -> Self {
        self.draw_mode = draw_mode;
        self
    }
}

/// Instanced 3D draw call - renders many instances of the same mesh efficiently.
///
/// Use this for rendering large numbers of similar objects like grass, trees,
/// particles, or any repeated geometry. All instances share the same mesh,
/// texture, and material, but each has its own transform and color.
///
/// # Example
/// ```ignore
/// // Create 1000 cubes in a grid
/// let instances: Vec<InstanceData> = (0..1000)
///     .map(|i| InstanceData::from_position_color(
///         Vec3::new((i % 10) as f32, (i / 10 % 10) as f32, (i / 100) as f32),
///         Color::rgb(rand(), rand(), rand()),
///     ))
///     .collect();
///
/// g.draw3d_instanced(InstancedDraw3D::new(cube_mesh.clone(), instances));
/// ```
pub struct InstancedDraw3D {
    /// The mesh to render (shared by all instances)
    pub mesh: Mesh3D,
    /// Per-instance transform and color data
    pub instances: Vec<InstanceData>,
    /// Optional texture handle (shared by all instances)
    pub texture: Option<Handle>,
    /// Material properties for lighting (shared by all instances)
    pub material: Material3D,
}

impl InstancedDraw3D {
    /// Create a new instanced draw call with the given mesh and instance data.
    pub fn new(mesh: Mesh3D, instances: Vec<InstanceData>) -> Self {
        Self {
            mesh,
            instances,
            texture: None,
            material: Material3D::default(),
        }
    }

    /// Set the texture for all instances.
    pub fn with_texture(mut self, texture: Handle) -> Self {
        self.texture = Some(texture);
        self
    }

    /// Set the material for all instances.
    pub fn with_material(mut self, material: Material3D) -> Self {
        self.material = material;
        self
    }

    /// Returns the number of instances.
    pub fn instance_count(&self) -> usize {
        self.instances.len()
    }
}