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
mod tone_mapping;
pub use tone_mapping::*;

mod color_space;
pub use color_space::*;

use crate::core::*;

///
/// Represents a camera used for viewing 2D and 3D objects.
///
#[derive(Clone, Debug)]
pub struct Camera {
    camera: three_d_asset::Camera,
    /// This tone mapping is applied to the final color of renders using this camera.
    pub tone_mapping: ToneMapping,
    /// This color mapping is applied to the final color of renders using this camera.
    pub color_mapping: ColorMapping,
}

impl Camera {
    ///
    /// New camera which projects the world with an orthographic projection.
    ///
    pub fn new_orthographic(
        viewport: Viewport,
        position: Vec3,
        target: Vec3,
        up: Vec3,
        height: f32,
        z_near: f32,
        z_far: f32,
    ) -> Self {
        Self {
            camera: three_d_asset::Camera::new_orthographic(
                viewport, position, target, up, height, z_near, z_far,
            ),
            tone_mapping: ToneMapping::default(),
            color_mapping: ColorMapping::default(),
        }
    }

    ///
    /// New camera which projects the world with a perspective projection.
    ///
    pub fn new_perspective(
        viewport: Viewport,
        position: Vec3,
        target: Vec3,
        up: Vec3,
        field_of_view_y: impl Into<Radians>,
        z_near: f32,
        z_far: f32,
    ) -> Self {
        Self {
            camera: three_d_asset::Camera::new_perspective(
                viewport,
                position,
                target,
                up,
                field_of_view_y,
                z_near,
                z_far,
            ),
            tone_mapping: ToneMapping::default(),
            color_mapping: ColorMapping::default(),
        }
    }

    ///
    /// Returns an orthographic camera for viewing 2D content.
    /// The camera is placed at the center of the given viewport.
    /// The (0, 0) position is at the bottom left corner and the
    /// (`viewport.width`, `viewport.height`) position is at the top right corner.
    ///
    pub fn new_2d(viewport: Viewport) -> Self {
        Self::new_orthographic(
            viewport,
            vec3(
                viewport.width as f32 * 0.5,
                viewport.height as f32 * 0.5,
                1.0,
            ),
            vec3(
                viewport.width as f32 * 0.5,
                viewport.height as f32 * 0.5,
                0.0,
            ),
            vec3(0.0, 1.0, 0.0),
            viewport.height as f32,
            0.0,
            10.0,
        )
    }

    ///
    /// Disables the tone and color mapping so as to be ready for rendering into an intermediate render target with this camera.
    ///
    pub fn disable_tone_and_color_mapping(&mut self) {
        self.tone_mapping = ToneMapping::None;
        self.color_mapping = ColorMapping::None;
    }

    ///
    /// Sets the tone and color mapping to default so as to be ready for rendering into the final render target (usually the screen) with this camera.
    ///
    pub fn set_default_tone_and_color_mapping(&mut self) {
        self.tone_mapping = ToneMapping::default();
        self.color_mapping = ColorMapping::default();
    }
}

use std::ops::Deref;
impl Deref for Camera {
    type Target = three_d_asset::Camera;
    fn deref(&self) -> &Self::Target {
        &self.camera
    }
}

impl std::ops::DerefMut for Camera {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.camera
    }
}