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}