001/*
002 * Renderer 4. The MIT License.
003 * Copyright (c) 2022 rlkraft@pnw.edu
004 * See LICENSE for details.
005*/
006
007package renderer.scene;
008
009/**
010   This {@code Camera} data structure represents a camera
011   located at the origin, looking down the negative z-axis.
012<p>
013   This {@code Camera} has associated to it a "view volume"
014   that determines what part of space the camera "sees" when
015   we use the camera to take a picture (that is, when we
016   render a {@link Scene}).
017<p>
018   This {@code Camera} can "take a picture" two ways, using
019   a perspective projection or a parallel (orthographic)
020   projection. Each way of taking a picture has a different
021   shape for its view volume.
022<p>
023   For the perspective projection, the view volume is an
024   infinitely long pyramid that is formed by the pyramid
025   with its apex at the origin and its base in the plane
026   {@code z = -1} with edges {@code x = -1}, {@code x = +1},
027   {@code y = -1}, and {@code y = +1}.
028<p>
029   For the orthographic projection, the view volume is an
030   infinitely long rectangular cylinder parallel to the
031   z-axis and with sides {@code x = -1}, {@code x = +1},
032   {@code y = -1}, and {@code y = +1} (an infinite parallelepiped).
033<p>
034   When the graphics rendering {@link renderer.pipeline.Pipeline}
035   uses this {@code Camera} to render a {@link Scene}, the renderer
036   "sees" the geometry from the scene that is contained in this
037   camera's view volume. (Notice that this means the orthographic
038   camera will see geometry that is behind the camera. In fact, the
039   perspective camera also sees geometry that is behind the camera.)
040   The renderer's {@link renderer.pipeline.Rasterize} pipeline stage
041   is responsible for making sure that the scene's geometry that is
042   outside of this camera's view volume is not visible.
043<p>
044   The plane {@code z = -1} is the camera's "image plane". The
045   rectangle in the image plane with corners {@code (-1, -1, -1)}
046   and {@code (+1, +1, -1)} is the camera's "view rectangle". The
047   view rectangle is like the film in a real camera, it is where
048   the camera's image appears when you take a picture. The contents
049   of the camera's view rectangle is what gets rasterized, by the
050   renderer's {@link renderer.pipeline.Rasterize} pipeline stage,
051   into a {@link renderer.framebuffer.FrameBuffer}'s
052   {@link renderer.framebuffer.FrameBuffer.Viewport}.
053*/
054public final class Camera
055{
056   // Choose either perspective or parallel projection.
057   public final boolean perspective;
058
059   /**
060      A private {@code Camera} constructor for
061      use by the static factory methods.
062   */
063   private Camera(final boolean perspective)
064   {
065      this.perspective = perspective;
066   }
067
068
069   /**
070      This is a static factory method.
071      <p>
072      Set up this {@code Camera}'s view volume as a perspective projection
073      of an infinite view pyramid extending along the negative z-axis.
074
075      @return a new {@code Camera} object with the default perspective parameter
076   */
077   public static Camera projPerspective()
078   {
079      return new Camera(true);
080   }
081
082
083   /**
084      This is a static factory method.
085      <p>
086      Set up this {@code Camera}'s view volume as a parallel (orthographic)
087      projection of an infinite view parallelepiped extending along the z-axis.
088
089      @return a new {@code Camera} object with the default orthographic parameter
090   */
091   public static Camera projOrtho()
092   {
093      return new Camera(false);
094   }
095
096
097   /**
098      For debugging.
099
100      @return {@link String} representation of this {@code Camera} object
101   */
102   @Override
103   public String toString()
104   {
105      String result = "";
106      result += "Camera: \n";
107      result += "perspective = " + perspective;
108      return result;
109   }
110}