1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//!
//! A collection of objects (implementing the [Object] trait) that can be rendered directly or used in a render call, for example [render_pass].
//! Can be a combination of any [geometry] and [material] by using the [Gm] struct.
//!

mod gm;
#[doc(inline)]
pub use gm::*;

mod model;
#[doc(inline)]
pub use model::*;

mod instanced_model;
#[doc(inline)]
pub use instanced_model::*;

mod line;
#[doc(inline)]
pub use line::*;

mod rectangle;
#[doc(inline)]
pub use rectangle::*;

mod circle;
#[doc(inline)]
pub use circle::*;

mod skybox;
#[doc(inline)]
pub use skybox::*;

mod imposters;
#[doc(inline)]
pub use imposters::*;

mod axes;
#[doc(inline)]
pub use axes::*;

mod bounding_box;
#[doc(inline)]
pub use bounding_box::*;

use crate::core::*;
use crate::renderer::*;

///
/// Represents a 3D object which can be rendered directly or used in a render call, for example [render_pass].
///
pub trait Object: Geometry {
    ///
    /// Render the object.
    /// Must be called in a render target render function,
    /// for example in the callback function of [Screen::write](crate::Screen::write).
    /// You can use an empty array for the `lights` argument, if you know the object does not require lights to be rendered.
    ///
    fn render(&self, camera: &Camera, lights: &[&dyn Light]) -> ThreeDResult<()>;

    ///
    /// Returns whether or not this object should be considered transparent.
    ///
    fn is_transparent(&self) -> bool;
}

impl<T: Object + ?Sized> Object for &T {
    fn render(&self, camera: &Camera, lights: &[&dyn Light]) -> ThreeDResult<()> {
        (*self).render(camera, lights)
    }

    fn is_transparent(&self) -> bool {
        (*self).is_transparent()
    }
}

impl<T: Object + ?Sized> Object for &mut T {
    fn render(&self, camera: &Camera, lights: &[&dyn Light]) -> ThreeDResult<()> {
        (**self).render(camera, lights)
    }

    fn is_transparent(&self) -> bool {
        (**self).is_transparent()
    }
}

impl<T: Object> Object for Box<T> {
    fn render(&self, camera: &Camera, lights: &[&dyn Light]) -> ThreeDResult<()> {
        self.as_ref().render(camera, lights)
    }

    fn is_transparent(&self) -> bool {
        self.as_ref().is_transparent()
    }
}

impl<T: Object> Object for std::rc::Rc<T> {
    fn render(&self, camera: &Camera, lights: &[&dyn Light]) -> ThreeDResult<()> {
        self.as_ref().render(camera, lights)
    }

    fn is_transparent(&self) -> bool {
        self.as_ref().is_transparent()
    }
}

impl<T: Object> Object for std::rc::Rc<std::cell::RefCell<T>> {
    fn render(&self, camera: &Camera, lights: &[&dyn Light]) -> ThreeDResult<()> {
        self.borrow().render(camera, lights)
    }

    fn is_transparent(&self) -> bool {
        self.borrow().is_transparent()
    }
}

// Object2D trait

///
/// Represents a 2D object which can be rendered.
///
pub trait Object2D: Geometry2D {
    ///
    /// Render the object.
    /// Must be called in a render target render function,
    /// for example in the callback function of [Screen::write](crate::Screen::write).
    ///
    fn render(&self, viewport: Viewport) -> ThreeDResult<()>;

    ///
    /// Returns whether or not this object should be considered transparent.
    ///
    fn is_transparent(&self) -> bool;
}

impl<T: Object2D + ?Sized> Object2D for &T {
    fn render(&self, viewport: Viewport) -> ThreeDResult<()> {
        (*self).render(viewport)
    }

    fn is_transparent(&self) -> bool {
        (*self).is_transparent()
    }
}

impl<T: Object2D + ?Sized> Object2D for &mut T {
    fn render(&self, viewport: Viewport) -> ThreeDResult<()> {
        (**self).render(viewport)
    }

    fn is_transparent(&self) -> bool {
        (**self).is_transparent()
    }
}

impl<T: Object2D> Object2D for Box<T> {
    fn render(&self, viewport: Viewport) -> ThreeDResult<()> {
        self.as_ref().render(viewport)
    }

    fn is_transparent(&self) -> bool {
        self.as_ref().is_transparent()
    }
}

impl<T: Object2D> Object2D for std::rc::Rc<T> {
    fn render(&self, viewport: Viewport) -> ThreeDResult<()> {
        self.as_ref().render(viewport)
    }

    fn is_transparent(&self) -> bool {
        self.as_ref().is_transparent()
    }
}

impl<T: Object2D> Object2D for std::rc::Rc<std::cell::RefCell<T>> {
    fn render(&self, viewport: Viewport) -> ThreeDResult<()> {
        self.borrow().render(viewport)
    }

    fn is_transparent(&self) -> bool {
        self.borrow().is_transparent()
    }
}