Struct gemini_engine::elements3d::view3d::Viewport

source ·
pub struct Viewport {
    pub transform: Transform3D,
    pub fov: f64,
    pub origin: Vec2D,
    pub character_width_multiplier: f64,
    pub clipping_distace: f64,
}
Expand description

The Viewport handles printing 3D objects to a 2D View, and also acts as the scene’s camera.

Fields§

§transform: Transform3D

How the Viewport is oriented in the 3D scene

§fov: f64

The Viewport’s field of view

§origin: Vec2D

The center of the view you intend to print to. View.center() returns exactly what you need for this

§character_width_multiplier: f64

Most terminals don’t have perfectly square characters. The value you set here is how much the final image will be stretched in the X axis to account for this. The default value is 2.2 but it will be different in most terminals

§clipping_distace: f64

Any face with vertices closer to the viewport than this value will be clipped

Implementations§

source§

impl Viewport

source

pub const fn new(transform: Transform3D, fov: f64, screen_origin: Vec2D) -> Self

Create a new Viewport with a default character_width_multiplier of 2.2

Examples found in repository?
examples/spinning-cube.rs (lines 13-17)
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
fn main() {
    let mut view = View::new(200, 90, ColChar::BACKGROUND);

    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 1.5, 4.0), Vec3D::new(-0.4, 0.0, 0.0)),
        FOV,
        view.center(),
    );

    let mut cube = Mesh3D::default_cube();

    fps_gameloop!(
        {
            view.clear();
            cube.transform.rotation.y -= 0.05;
        },
        {
            view.blit(
                &viewport.render(vec![&cube], DisplayMode::Solid),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS,
        |elapsed: gameloop::Duration, frame_skip| {
            println!(
                "Elapsed: {:.2?}µs | Frame skip: {}",
                elapsed.as_micros(),
                frame_skip
            );
        }
    );
}
More examples
Hide additional examples
examples/donut.rs (lines 16-20)
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
fn main() {
    let mut view = View::new(82, 32, ColChar::EMPTY);
    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 0.0, 20.0), Vec3D::ZERO),
        FOV,
        view.center(),
    );

    let lights = vec![
        Light::new_ambient(0.3),
        Light::new_directional(0.7, Vec3D::new(1.0, -1.0, -1.0)),
    ];

    let mut donut = Mesh3D::torus(1.8, 1.0, 32, 16);

    fps_gameloop!(
        {
            donut.transform.rotation.x += 0.05;
            donut.transform.rotation.z += 0.05;
        },
        {
            view.clear();
            view.blit(
                &viewport.render(
                    vec![&donut],
                    DisplayMode::Illuminated {
                        lights: lights.clone(),
                    },
                ),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS
    );
}
source

pub fn render( &self, objects: Vec<&Mesh3D>, display_mode: DisplayMode ) -> PixelContainer

Render the Mesh3Ds given the Viewport’s properties. Returns a PixelContainer which can then be blit to a View

Examples found in repository?
examples/spinning-cube.rs (line 28)
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
fn main() {
    let mut view = View::new(200, 90, ColChar::BACKGROUND);

    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 1.5, 4.0), Vec3D::new(-0.4, 0.0, 0.0)),
        FOV,
        view.center(),
    );

    let mut cube = Mesh3D::default_cube();

    fps_gameloop!(
        {
            view.clear();
            cube.transform.rotation.y -= 0.05;
        },
        {
            view.blit(
                &viewport.render(vec![&cube], DisplayMode::Solid),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS,
        |elapsed: gameloop::Duration, frame_skip| {
            println!(
                "Elapsed: {:.2?}µs | Frame skip: {}",
                elapsed.as_micros(),
                frame_skip
            );
        }
    );
}
More examples
Hide additional examples
examples/donut.rs (lines 37-42)
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
fn main() {
    let mut view = View::new(82, 32, ColChar::EMPTY);
    let viewport = Viewport::new(
        Transform3D::new_tr(Vec3D::new(0.0, 0.0, 20.0), Vec3D::ZERO),
        FOV,
        view.center(),
    );

    let lights = vec![
        Light::new_ambient(0.3),
        Light::new_directional(0.7, Vec3D::new(1.0, -1.0, -1.0)),
    ];

    let mut donut = Mesh3D::torus(1.8, 1.0, 32, 16);

    fps_gameloop!(
        {
            donut.transform.rotation.x += 0.05;
            donut.transform.rotation.z += 0.05;
        },
        {
            view.clear();
            view.blit(
                &viewport.render(
                    vec![&donut],
                    DisplayMode::Illuminated {
                        lights: lights.clone(),
                    },
                ),
                Wrapping::Ignore,
            );
            let _ = view.display_render();
        },
        FPS
    );
}

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.