Skip to main content

Camera

Struct Camera 

Source
pub struct Camera { /* private fields */ }
Expand description

A View and a Projection: where a frame is viewed from, and how that view is projected.

A frame is drawn from the last call to FrameContext::set_camera; each frame needs its own.

Implementations§

Source§

impl Camera

Source

pub const fn new(view: View, projection: Projection) -> Self

A camera from view and projection.

Examples found in repository?
examples/material-playground.rs (lines 788-791)
787    fn camera(&self) -> Camera {
788        Camera::new(
789            View::look_at(self.eye, self.eye + self.forward()),
790            Projection::perspective(CAMERA_FOV),
791        )
792    }
More examples
Hide additional examples
examples/stress-preview.rs (lines 288-291)
287    fn camera(&self) -> Camera {
288        Camera::new(
289            View::look_at(self.eye, self.eye + self.forward()),
290            Projection::perspective(CAMERA_FOV),
291        )
292    }
293}
294
295struct StressPreview {
296    settings: Settings,
297    applied_instance_count: u32,
298    applied_seed_count: u32,
299    field: Vec<FieldEntry>,
300    frame_times: FrameTimer,
301    /// Set at the instant a pan, a wheel step or a drag first moves the
302    /// camera; from then on the orbit never runs again.
303    player: Option<Player>,
304}
305
306impl StressPreview {
307    fn init(_ctx: &mut InitContext<'_, Self>) -> Result<Self, Error> {
308        let settings = Settings::default();
309        let field = build_field(settings.instance_count, settings.seed_count);
310        Ok(Self {
311            applied_instance_count: settings.instance_count,
312            applied_seed_count: settings.seed_count,
313            settings,
314            field,
315            frame_times: FrameTimer::new(),
316            player: None,
317        })
318    }
319
320    /// Rebuilds the field where the instance count or the seed count
321    /// changed since the last frame.
322    fn apply_settings(&mut self) {
323        if self.settings.instance_count == self.applied_instance_count
324            && self.settings.seed_count == self.applied_seed_count
325        {
326            return;
327        }
328        self.field = build_field(self.settings.instance_count, self.settings.seed_count);
329        self.applied_instance_count = self.settings.instance_count;
330        self.applied_seed_count = self.settings.seed_count;
331    }
332
333    /// The camera's place along the orbit at `elapsed`, before the player
334    /// takes it over.
335    fn orbit_eye(elapsed: f32) -> Vec3 {
336        let angle = elapsed * CAMERA_ANGULAR_SPEED;
337        Vec3::new(
338            angle.cos() * CAMERA_ORBIT_RADIUS,
339            CAMERA_HEIGHT,
340            angle.sin() * CAMERA_ORBIT_RADIUS,
341        )
342    }
343
344    /// The frame's camera: the orbit at `elapsed`, or the player's own
345    /// place once they have taken over.
346    fn camera(&self, elapsed: f32) -> Camera {
347        match &self.player {
348            Some(player) => player.camera(),
349            None => Camera::new(
350                View::look_at(Self::orbit_eye(elapsed), Vec3::ZERO),
351                Projection::perspective(CAMERA_FOV),
352            ),
353        }
354    }
examples/breakout-game.rs (lines 583-586)
582    fn camera() -> Camera {
583        Camera::new(
584            View::look_at(Vec3::new(0.0, 13.5, 12.5), Vec3::new(0.0, 0.0, 0.5)),
585            Projection::perspective(50.0),
586        )
587    }
examples/isometric-board.rs (lines 384-387)
382    fn camera() -> Camera {
383        let eye = Vec3::new(9.0, 9.0, 9.0);
384        Camera::new(
385            View::look_at(eye, Vec3::ZERO),
386            Projection::orthographic(11.0),
387        )
388    }
examples/sprite-adventure.rs (lines 1037-1040)
1036    fn camera(position: Vec3, offset: Vec3) -> Camera {
1037        Camera::new(
1038            View::look_at(position + offset, position),
1039            Projection::perspective(CAMERA_FOV),
1040        )
1041    }
examples/sound-lab.rs (lines 452-458)
450    fn camera(player: Vec2) -> Camera {
451        let ground = Vec3::new(player.x, 0.0, player.y);
452        Camera::new(
453            View::look_at(
454                ground + Vec3::new(0.0, CHASE_UP, CHASE_BACK),
455                ground + Vec3::Y * 0.5,
456            ),
457            Projection::perspective(55.0),
458        )
459    }
Source

pub const fn view(&self) -> View

The world’s viewpoint.

Source

pub const fn projection(&self) -> Projection

The view’s projection onto the screen.

Source

pub fn ray_through(&self, pixel: Vec2, size: UVec2) -> Ray

The ray through pixel on a surface size across, in world space.

Both are physical pixels, as FrameContext::window_size reports them. The ray starts at the View::eye where the lens foreshortens, and in the view plane where it does not.

Examples found in repository?
examples/ui-fonts.rs (line 637)
634    fn handle_hail(&mut self, ctx: &mut TickContext<'_, Self>) {
635        let ray = ctx
636            .last_camera()
637            .ray_through(ctx.pointer(), ctx.window_size());
638        let Some(station) = hit_station(ray) else {
639            return;
640        };
641
642        if self.hailed != Some(station) {
643            self.hailed = Some(station);
644            let look = station.look();
645            self.dialogue = Some(Dialogue::start(look.name, look.lines.map(str::to_owned)));
646            return;
647        }
648        let Some(dialogue) = &mut self.dialogue else {
649            return;
650        };
651        if !dialogue.advance() {
652            self.dialogue = None;
653            self.hailed = None;
654        }
655    }
656
657    fn draw_station(&self, ctx: &mut FrameContext<'_, Self>, station: StationKind) {
658        let look = station.look();
659        let center = station.center();
660        let front_offset =
661            STATION_SIZE.z * 0.5 - STATION_FRONT_SIZE.z * 0.5 + STATION_FRONT_OUTWARD;
662        let front = center - Vec3::new(0.0, 0.0, front_offset);
663        for (size, position, material) in [
664            (STATION_SIZE, center, Material::lit(look.color)),
665            (
666                STATION_FRONT_SIZE,
667                front,
668                Material::color(Color::BLACK).emissive(look.glow),
669            ),
670        ] {
671            ctx.draw(
672                Cube.at(Transform::from_scale_rotation_translation(
673                    size,
674                    Quat::IDENTITY,
675                    position,
676                ))
677                .material(material),
678            );
679        }
680    }
681
682    fn draw_bracket(&self, ctx: &mut FrameContext<'_, Self>, camera: Camera, station: StationKind) {
683        let top = station.center() + Vec3::Y * (STATION_SIZE.y * 0.5);
684        let window_size = ctx.window_size();
685        let Some(pixel) = camera.pixel_of(top, window_size) else {
686            return;
687        };
688        let at = logical(pixel, ctx.pixels_per_point());
689
690        let name = ctx.text_layout(station.look().name, egui::FontId::proportional(BODY_SIZE));
691        let (reading_text, number_text) = station.reading(self.elapsed.as_secs_f32());
692        let reading = ctx.text_layout(&reading_text, egui::FontId::monospace(BODY_SIZE));
693        let number = ctx.text_layout(
694            &number_text,
695            egui::FontId::new(NUMBER_SIZE, egui::FontFamily::Name(DISPLAY_FAMILY.into())),
696        );
697
698        ctx.ui(|ui| bracket(ui.painter(), at, name, reading, number));
699    }
700
701    /// A `Prompt` for `Trigger::Hail`, above every `StationKind` but
702    /// `hovered`: what a player presses to reach one, apart from a hover.
703    fn draw_prompts(
704        &self,
705        ctx: &mut FrameContext<'_, Self>,
706        camera: Camera,
707        hovered: Option<StationKind>,
708    ) {
709        let Some(binding) = ctx.bindings(Trigger::Hail).into_iter().next() else {
710            return;
711        };
712        let hint = prompt(&binding);
713        let glyph = ctx.text_layout(&hint.text(), egui::FontId::new(PROMPT_SIZE, hint.family()));
714        let window_size = ctx.window_size();
715        let pixels_per_point = ctx.pixels_per_point();
716
717        ctx.ui(|ui| {
718            let painter = ui.painter();
719            for station in StationKind::ALL {
720                if Some(station) == hovered {
721                    continue;
722                }
723                let top = station.center() + Vec3::Y * (STATION_SIZE.y * 0.5);
724                let Some(pixel) = camera.pixel_of(top, window_size) else {
725                    continue;
726                };
727                let at = logical(pixel, pixels_per_point);
728                let at = egui::pos2(at.x, at.y - PROMPT_LIFT);
729                prompt_at(painter, at, glyph.clone());
730            }
731        });
732    }
733
734    /// The title, a line and the reading, each in a font this game loaded
735    /// rather than egui's own.
736    fn panel(&self, ctx: &mut FrameContext<'_, Self>) {
737        ctx.ui(|ui| {
738            ui.label(styled(
739                "a game's own fonts",
740                egui::FontId::proportional(HEADING_SIZE),
741            ));
742            ui.label(styled(
743                "drawn in Pixel Operator, the game's proportional font",
744                egui::FontId::proportional(BODY_SIZE),
745            ));
746            ui.label(styled(
747                "the readings above each station in Pixel Operator Mono",
748                egui::FontId::monospace(BODY_SIZE),
749            ));
750        });
751    }
752
753    fn draw_dialogue(&self, ctx: &mut FrameContext<'_, Self>) {
754        let Some(dialogue) = &self.dialogue else {
755            return;
756        };
757        let whole = ctx.text_layout(
758            dialogue.current_line(),
759            egui::FontId::proportional(BODY_SIZE),
760        );
761        let size = whole.size();
762        ctx.ui(|ui| dialogue.draw(ui, size));
763    }
764
765    /// The `StationKind` under the pointer, `None` while the UI holds it.
766    fn hovered(ctx: &FrameContext<'_, Self>) -> Option<StationKind> {
767        if ctx.ui_wants_pointer() {
768            return None;
769        }
770        hit_station(
771            ctx.last_camera()
772                .ray_through(ctx.pointer(), ctx.window_size()),
773        )
774    }
More examples
Hide additional examples
examples/sound-lab.rs (line 486)
474    fn handle_drag(&mut self, ctx: &mut TickContext<'_, SoundCheck>) {
475        // Read before the check below for the UI's own claim on the
476        // pointer, so a release over it still frees a source a drag moved
477        // there.
478        if ctx.released(Button::Select) {
479            self.dragging = None;
480        }
481        if ctx.ui_wants_pointer() {
482            return;
483        }
484        let ray = ctx
485            .last_camera()
486            .ray_through(ctx.pointer(), ctx.window_size());
487
488        if ctx.pressed(Button::Select) {
489            self.dragging = self.sources.iter().position(|source| {
490                ray.hit_sphere(source.position, SOURCE_PICK_RADIUS)
491                    .is_some()
492            });
493        }
494
495        let Some(index) = self.dragging else {
496            return;
497        };
498        let Some(distance) = ray.hit_plane(ray::Plane {
499            point: Vec3::ZERO,
500            normal: Vec3::Y,
501        }) else {
502            return;
503        };
504        let hit = ray.at(distance);
505        let dropped =
506            Vec2::new(hit.x, hit.z).clamp(Vec2::splat(-PLAY_BOUND), Vec2::splat(PLAY_BOUND));
507        self.sources[index].position = Vec3::new(dropped.x, SOURCE_HEIGHT, dropped.y);
508    }
examples/isometric-board.rs (line 420)
414    fn handle_click(&mut self, ctx: &mut TickContext<'_, Board>) {
415        if ctx.ui_wants_pointer() || !ctx.pressed(Button::Select) {
416            return;
417        }
418        let ray = ctx
419            .last_camera()
420            .ray_through(ctx.pointer(), ctx.window_size());
421        let (lift, half) = unit_geometry(self.turn);
422
423        if self.current().target.is_none() {
424            let center = self.current().position;
425            if ray.hit_aabb(center - half, center + half).is_some() {
426                self.selected = !self.selected;
427                return;
428            }
429        }
430        if !self.selected {
431            return;
432        }
433
434        let Some(distance) = ray.hit_plane(ray::Plane {
435            point: Vec3::ZERO,
436            normal: Vec3::Y,
437        }) else {
438            return;
439        };
440        let Some(tile) = tile_at(ray.at(distance)) else {
441            return;
442        };
443        if tile == self.current().tile || tile == self.other().tile {
444            return;
445        }
446
447        let destination = tile_center(tile) + Vec3::Y * lift;
448        let heading = destination.x - self.current().position.x;
449        let current = self.current_mut();
450        if heading.abs() > f32::EPSILON {
451            current.facing_right = heading > 0.0;
452        }
453        current.target = Some(destination);
454        self.selected = false;
455        ctx.play(Sound::Click);
456    }
457
458    /// Cursor target, `None` while the UI has the pointer.
459    fn hovered(&self, ctx: &FrameContext<'_, Board>) -> Hover {
460        if ctx.ui_wants_pointer() {
461            return Hover::None;
462        }
463        let ray = ctx
464            .last_camera()
465            .ray_through(ctx.pointer(), ctx.window_size());
466
467        if self.current().target.is_none() {
468            let (_, half) = unit_geometry(self.turn);
469            let center = self.current().position;
470            if ray.hit_aabb(center - half, center + half).is_some() {
471                return Hover::CurrentUnit;
472            }
473        }
474        let Some(distance) = ray.hit_plane(ray::Plane {
475            point: Vec3::ZERO,
476            normal: Vec3::Y,
477        }) else {
478            return Hover::None;
479        };
480        match tile_at(ray.at(distance)) {
481            Some(tile) => Hover::Tile(tile),
482            None => Hover::None,
483        }
484    }
Source

pub fn pixel_of(&self, point: Vec3, size: UVec2) -> Option<Vec2>

The pixel point draws at, on a surface size across, in physical pixels.

The inverse of Camera::ray_through at the same size, counted from the drawing area’s top left. A point off screen returns a pixel outside the surface, for the caller to clamp. None where point lies at or behind the View::eye, where either side of size is zero, or where the view or the lens has no shape to draw through.

Examples found in repository?
examples/stress-preview.rs (line 441)
440    fn in_view(camera: &Camera, position: Vec3, window_size: UVec2) -> bool {
441        camera.pixel_of(position, window_size).is_some_and(|pixel| {
442            pixel.x >= 0.0
443                && pixel.y >= 0.0
444                && pixel.x < window_size.x as f32
445                && pixel.y < window_size.y as f32
446        })
447    }
More examples
Hide additional examples
examples/ui-fonts.rs (line 685)
682    fn draw_bracket(&self, ctx: &mut FrameContext<'_, Self>, camera: Camera, station: StationKind) {
683        let top = station.center() + Vec3::Y * (STATION_SIZE.y * 0.5);
684        let window_size = ctx.window_size();
685        let Some(pixel) = camera.pixel_of(top, window_size) else {
686            return;
687        };
688        let at = logical(pixel, ctx.pixels_per_point());
689
690        let name = ctx.text_layout(station.look().name, egui::FontId::proportional(BODY_SIZE));
691        let (reading_text, number_text) = station.reading(self.elapsed.as_secs_f32());
692        let reading = ctx.text_layout(&reading_text, egui::FontId::monospace(BODY_SIZE));
693        let number = ctx.text_layout(
694            &number_text,
695            egui::FontId::new(NUMBER_SIZE, egui::FontFamily::Name(DISPLAY_FAMILY.into())),
696        );
697
698        ctx.ui(|ui| bracket(ui.painter(), at, name, reading, number));
699    }
700
701    /// A `Prompt` for `Trigger::Hail`, above every `StationKind` but
702    /// `hovered`: what a player presses to reach one, apart from a hover.
703    fn draw_prompts(
704        &self,
705        ctx: &mut FrameContext<'_, Self>,
706        camera: Camera,
707        hovered: Option<StationKind>,
708    ) {
709        let Some(binding) = ctx.bindings(Trigger::Hail).into_iter().next() else {
710            return;
711        };
712        let hint = prompt(&binding);
713        let glyph = ctx.text_layout(&hint.text(), egui::FontId::new(PROMPT_SIZE, hint.family()));
714        let window_size = ctx.window_size();
715        let pixels_per_point = ctx.pixels_per_point();
716
717        ctx.ui(|ui| {
718            let painter = ui.painter();
719            for station in StationKind::ALL {
720                if Some(station) == hovered {
721                    continue;
722                }
723                let top = station.center() + Vec3::Y * (STATION_SIZE.y * 0.5);
724                let Some(pixel) = camera.pixel_of(top, window_size) else {
725                    continue;
726                };
727                let at = logical(pixel, pixels_per_point);
728                let at = egui::pos2(at.x, at.y - PROMPT_LIFT);
729                prompt_at(painter, at, glyph.clone());
730            }
731        });
732    }
examples/sprite-adventure.rs (line 1653)
1638    fn draw_door_prompt(&self, ctx: &mut FrameContext<'_, Keep>, camera: Camera) {
1639        let near = self.position.distance(INTERACT_POINT) < INTERACT_RADIUS;
1640        let swinging = self.door_opening && self.swing_ticks < DOOR_SWING_TICKS;
1641        let text = if swinging {
1642            "opening"
1643        } else if near && !self.door_opening {
1644            "e opens the door"
1645        } else {
1646            return;
1647        };
1648
1649        let galley = ctx.text_layout(text, egui::FontId::proportional(DOOR_PROMPT_SIZE));
1650        let point = INTERACT_POINT + Vec3::Y * (DOOR_HEIGHT + DOOR_PROMPT_LIFT);
1651        let window_size = ctx.window_size();
1652        let pixels_per_point = ctx.pixels_per_point();
1653        let Some(pixel) = camera.pixel_of(point, window_size) else {
1654            return;
1655        };
1656
1657        ctx.ui(|ui| {
1658            let painter = ui.painter();
1659            let at = logical(pixel, pixels_per_point);
1660            let ink = galley.mesh_bounds;
1661            let pos = egui::pos2(at.x - ink.center().x, at.y - ink.center().y);
1662            let backdrop = egui::Rect::from_center_size(
1663                at,
1664                ink.size() + egui::Vec2::splat(DOOR_PROMPT_PADDING * 2.0),
1665            );
1666            painter.rect_filled(
1667                backdrop,
1668                DOOR_PROMPT_PADDING,
1669                egui::Color32::from_black_alpha(DOOR_PROMPT_BACKDROP),
1670            );
1671            painter.galley(pos, galley, DOOR_PROMPT_COLOR);
1672        });
1673    }
examples/isometric-board.rs (line 686)
671    fn draw_prompt(&self, ctx: &mut FrameContext<'_, Board>, camera: Camera, hover: Hover) {
672        let Some(text) = self.click_effect(hover) else {
673            return;
674        };
675        let point = match hover {
676            Hover::CurrentUnit => {
677                let (lift, _) = unit_geometry(self.turn);
678                self.current().position + Vec3::Y * (lift * 2.0 + PROMPT_UNIT_LIFT)
679            }
680            Hover::Tile(tile) => tile_center(tile) + Vec3::Y * PROMPT_TILE_LIFT,
681            Hover::None => return,
682        };
683        let galley = ctx.text_layout(text, egui::FontId::proportional(PROMPT_SIZE));
684        let window_size = ctx.window_size();
685        let pixels_per_point = ctx.pixels_per_point();
686        let Some(pixel) = camera.pixel_of(point, window_size) else {
687            return;
688        };
689        let at = logical(pixel, pixels_per_point);
690        ctx.ui(|ui| {
691            let painter = ui.painter();
692            let ink = galley.mesh_bounds;
693            let pos = egui::pos2(at.x - ink.center().x, at.y - ink.center().y);
694            let backdrop = egui::Rect::from_center_size(
695                at,
696                ink.size() + egui::Vec2::splat(PROMPT_PADDING * 2.0),
697            );
698            painter.rect_filled(
699                backdrop,
700                PROMPT_PADDING,
701                egui::Color32::from_black_alpha(PROMPT_BACKDROP),
702            );
703            painter.galley(pos, galley, PROMPT_TEXT_COLOR);
704        });
705    }
examples/animation.rs (line 853)
823    fn draw_prompts(&self, ctx: &mut FrameContext<'_, Scene>, camera: Camera) {
824        let sit_key = ctx
825            .bindings(Button::Interact)
826            .into_iter()
827            .next()
828            .map_or_else(|| "interact".to_owned(), |binding| binding.to_string());
829        let sit = ctx.text_layout(
830            &format!("{sit_key} sits"),
831            egui::FontId::proportional(PROMPT_SIZE),
832        );
833        let hurts = ctx.text_layout("hurts", egui::FontId::proportional(PROMPT_SIZE));
834        let walk_closer = ctx.text_layout("walk closer", egui::FontId::proportional(PROMPT_SIZE));
835
836        let mut prompts = vec![(
837            SCRUBBED_ELF_POSITION + Vec3::Y * (ELF_HEIGHT + PROMPT_LIFT),
838            walk_closer,
839        )];
840        if !self.elf_animator.state().seated() {
841            prompts.push((
842                SEAT_POSITION + Vec3::Y * (SEAT_HEAD_HEIGHT + PROMPT_LIFT),
843                sit,
844            ));
845        }
846        prompts.extend(HURT_PATCHES.map(|patch| (patch + Vec3::Y * PROMPT_LIFT, hurts.clone())));
847
848        let window_size = ctx.window_size();
849        let pixels_per_point = ctx.pixels_per_point();
850        ctx.ui(|ui| {
851            let painter = ui.painter();
852            for (point, galley) in prompts {
853                let Some(pixel) = camera.pixel_of(point, window_size) else {
854                    continue;
855                };
856                let at = logical(pixel, pixels_per_point);
857                let ink = galley.mesh_bounds;
858                let pos = egui::pos2(at.x - ink.center().x, at.y - ink.center().y);
859                let backdrop = egui::Rect::from_center_size(
860                    at,
861                    ink.size() + egui::Vec2::splat(PROMPT_PADDING * 2.0),
862                );
863                painter.rect_filled(
864                    backdrop,
865                    PROMPT_PADDING,
866                    egui::Color32::from_black_alpha(PANEL_BACKDROP),
867                );
868                painter.galley(pos, galley, PANEL_TEXT_COLOR);
869            }
870        });
871    }
Source

pub fn pixels_per_meter(&self, point: Vec3, size: UVec2) -> Option<f32>

The pixels a meter across the view covers at the depth of point in front of the View::eye, on a surface size across: the scale.

The scale falls with depth under Lens::Perspective and stays the same at every depth under Lens::Orthographic. None where point lies at or behind the View::eye, where either side of size is zero, or where the view or the lens has no shape to draw through.

Source

pub fn shifted_so( &self, point: Vec3, lands_at: Vec2, size: UVec2, ) -> Option<Camera>

The same camera moved so that point draws at lands_at, on a surface size across.

Required if you want a drag to pan the view. lands_at is a pixel as pixel_of returns one: physical pixels from the drawing area’s top left. The camera is moved and never turned, and it moves in the view plane, so point keeps its depth and the View::eye and View::target move by the same vector. None where point lies at or behind the View::eye, where either side of size is zero, where the view or the lens has no shape to draw through, where lands_at is not finite, or where the camera it would return does not draw point: the View::eye and View::target landed together.

Source

pub fn zoomed_about( &self, point: Vec3, factor: f32, size: UVec2, ) -> Option<Camera>

The same camera zoomed about point, on a surface size across, so that point keeps the pixel it draws at.

Required if you want a wheel to zoom towards what the pointer is over. The distance from the View::eye to point becomes the fraction 1.0 / factor of what it was, so 2.0 halves it, and the direction the view looks and its field of view are left alone. Under Lens::Orthographic the View::eye keeps its own depth: the lens takes that same fraction of its world height and the View::eye moves in the view plane instead. None where point lies at or behind the View::eye, where either side of size is zero, where the view or the lens has no shape to draw through, where factor is not finite or not above zero, or where the camera it would return does not draw point: the View::eye and View::target landed together, or the lens was left with no finite height.

Source

pub fn turned_about(&self, point: Vec3, yaw: f32, pitch: f32) -> Option<Camera>

The same camera turned about point, so that point keeps the pixel it draws at.

Required if you want a drag to orbit the view about what the pointer is over. The View::eye turns about point by pitch radians about the direction across the view to the right, then by yaw radians about the View::up direction, and the direction the view looks turns with it, so the distance from the View::eye to point and the Projection are left alone. None where point lies at or behind the View::eye, where the view has no shape to draw through, where yaw or pitch is not finite, or where the turn takes the direction the view looks past the View::up direction — the pole.

Trait Implementations§

Source§

impl Clone for Camera

Source§

fn clone(&self) -> Camera

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Camera

Source§

impl Debug for Camera

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Camera

Source§

fn default() -> Self

Looks at the origin from 5 meters back and 2 meters up, at 60°.

Source§

impl PartialEq for Camera

Source§

fn eq(&self, other: &Camera) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Camera

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> SerializableAny for T
where T: 'static + Any + Clone + for<'a> Send + Sync,

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

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

Source§

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.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more