Skip to main content

viewport_lib/scene/
traits.rs

1//! Core viewport object trait and related types.
2//!
3//! Applications implement [`ViewportObject`](crate::scene::traits::ViewportObject) on their scene object types
4//! so the renderer and picking system can work with them generically.
5
6use crate::scene::material::Material;
7
8/// Render mode for a viewport object.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[non_exhaustive]
11pub enum RenderMode {
12    /// Filled solid geometry (triangle list, depth-tested).
13    Solid,
14    /// Wireframe overlay (edge list).
15    Wireframe,
16}
17
18/// Trait that application objects must implement to be rendered and picked
19/// in the viewport.
20pub trait ViewportObject {
21    /// Unique object identifier.
22    fn id(&self) -> u64;
23    /// GPU mesh key (index into mesh storage). None if no mesh uploaded yet.
24    fn mesh_id(&self) -> Option<u64>;
25    /// World-space model matrix (Translation * Rotation * Scale).
26    fn model_matrix(&self) -> glam::Mat4;
27    /// World-space position.
28    fn position(&self) -> glam::Vec3;
29    /// Orientation as a quaternion.
30    fn rotation(&self) -> glam::Quat;
31    /// Per-axis scale factors. Defaults to (1, 1, 1) if not overridden.
32    fn scale(&self) -> glam::Vec3 {
33        glam::Vec3::ONE
34    }
35    /// Whether this object should be rendered.
36    fn is_visible(&self) -> bool;
37    /// RGB color in linear 0..1 range.
38    fn color(&self) -> glam::Vec3;
39    /// Whether to render per-vertex normal visualization.
40    fn show_normals(&self) -> bool {
41        false
42    }
43    /// Render mode override.
44    fn render_mode(&self) -> RenderMode {
45        RenderMode::Solid
46    }
47    /// Alpha transparency (1.0 = fully opaque).
48    fn transparency(&self) -> f32 {
49        1.0
50    }
51    /// Material for this object. Default derives from `color()`.
52    ///
53    /// Override to provide per-object ambient, diffuse, specular, shininess,
54    /// opacity, or texture parameters. The default implementation wraps
55    /// `self.color()` in a [`Material::from_color`] call so existing
56    /// implementations continue to work without any changes.
57    fn material(&self) -> Material {
58        Material::from_color(self.color().into())
59    }
60}