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 009import java.util.List; 010import java.util.ArrayList; 011 012/** 013 A {@code Scene} data structure is a {@link List} of {@link Position} 014 data structures and a {@link Camera} data structure. 015<p> 016 Each {@link Position} object represents a {@link Model} object in a 017 distinct position in three-dimensional camera space. 018<p> 019 Each {@link Model} object represents a distinct geometric object 020 in the scene. 021<p> 022 The {@link Camera} object determines a "view volume", which 023 determines how much of the scene is actually visible (to the 024 camera) and gets rendered into the framebuffer. 025*/ 026public final class Scene 027{ 028 public final String name; 029 public final Camera camera; 030 public final List<Position> positionList; 031 032 public boolean debug; 033 034 /** 035 Construct a {@code Scene} with a default perspective 036 {@link Camera} object. 037 */ 038 public Scene() 039 { 040 this("", // name 041 Camera.projPerspective(), 042 new ArrayList<>(), // positionList 043 false); // debug 044 } 045 046 047 /** 048 Construct a {@code Scene} with a default perspective 049 {@link Camera} object and the given {@link String} name. 050 051 @param name {@link String} name for this {@code Scene} 052 @throws NullPointerException if {@code name} is {@code null} 053 */ 054 public Scene(final String name) 055 { 056 this(name, 057 Camera.projPerspective(), 058 new ArrayList<>(), // positionList 059 false); // debug 060 } 061 062 063 /** 064 Construct a {@code Scene} with the given {@link Camera} object. 065 066 @param camera {@link Camera} object for this {@code Scene} 067 @throws NullPointerException if {@code camera} is {@code null} 068 */ 069 public Scene(final Camera camera) 070 { 071 this("", // name 072 camera, 073 new ArrayList<>(), // positionList 074 false); // debug 075 } 076 077 078 /** 079 Construct a {@code Scene} with the given {@link Camera} object 080 and the given {@link String} name. 081 082 @param name {@link String} name for this {@code Scene} 083 @param camera {@link Camera} object for this {@code Scene} 084 @throws NullPointerException if {@code name} is {@code null} 085 @throws NullPointerException if {@code camera} is {@code null} 086 */ 087 public Scene(final String name, 088 final Camera camera) 089 { 090 this(name, 091 camera, 092 new ArrayList<>(), // positionList 093 false); // debug 094 } 095 096 097 /** 098 Construct a {@code Scene} object with all the given data. 099 100 @param name {@link String} name for this {@code Scene} 101 @param camera {@link Camera} object for this {@code Scene} 102 @param positionList {@link List} of {@link Position} objects 103 @param debug debug status for this {@code Scene} 104 @throws NullPointerException if {@code camera} is {@code null} 105 @throws NullPointerException if {@code positionList} is {@code null} 106 @throws NullPointerException if {@code name} is {@code null} 107 */ 108 public Scene(final String name, 109 final Camera camera, 110 final List<Position> positionList, 111 final boolean debug) 112 { 113 if (null == name) 114 throw new NullPointerException("name must not be null"); 115 if (null == camera) 116 throw new NullPointerException("camera must not be null"); 117 if (null == positionList) 118 throw new NullPointerException("positionList must not be null"); 119 120 this.name = name; 121 this.camera = camera; 122 this.positionList = positionList; 123 this.debug = debug; 124 } 125 126 127 /** 128 Create a new {@code Scene} that is essentially the same as this 129 {@code Scene} but holding a refernece to the given {@link Camera} 130 object. 131 132 @param camera {@link Camera} object for the new {@code Scene} 133 @return a new {@code Scene} object holding the given {@link Camera} object 134 @throws NullPointerException if {@code camera} is {@code null} 135 */ 136 public Scene changeCamera(final Camera camera) 137 { 138 return new Scene(this.name, 139 camera, 140 this.positionList, 141 this.debug); 142 } 143 144 145 /** 146 Get a reference to the {@link Position} object at the given index in this {@code Scene}'s 147 {@link List} of {@link Position}s. 148 149 @param index index of the {@link Position} to return 150 @return {@link Position} at the specified index in the {@link List} of {@link Position}s 151 @throws IndexOutOfBoundsException if the index is out of range 152 {@code (index < 0 || index >= size())} 153 */ 154 public Position getPosition(final int index) 155 { 156 return positionList.get(index); 157 } 158 159 160 /** 161 Set a reference to the given {@link Position} object at the given index in this {@code Scene}'s 162 {@link List} of {@link Position}s. 163 164 @param index index of the {@link Position} to set 165 @param position {@link Position} object to place at the specified index in the {@link List} of {@link Position}s 166 @throws NullPointerException if {@link Position} is {@code null} 167 @throws IndexOutOfBoundsException if the index is out of range 168 {@code (index < 0 || index >= size())} 169 */ 170 public void setPosition(final int index, final Position position) 171 { 172 if (null == position) 173 throw new NullPointerException("Position must not be null"); 174 175 positionList.set(index, position); 176 } 177 178 179 /** 180 Add a {@link Position} (or Positions) to this {@code Scene}. 181 182 @param pArray array of {@link Position}s to add to this {@code Scene} 183 @throws NullPointerException if any {@link Position} is {@code null} 184 */ 185 public void addPosition(final Position... pArray) 186 { 187 for (final Position position : pArray) 188 { 189 if (null == position) 190 throw new NullPointerException("Position must not be null"); 191 192 positionList.add(position); 193 } 194 } 195 196 197 /** 198 Get a reference to the first {@link Model} object with the given name from 199 this {@code Scene}'s {@link List} of {@link Position}s. 200 201 @param name {@link String} name of the {@link Model} to search for 202 @return a {@link Model} with the give name from the {@link List} of {@link Position}s 203 */ 204 public Model getModelByName(final String name) 205 { 206 Model result = null; 207 for (final Position position : positionList) 208 { 209 if ( name.equals(position.getModel().name) ) 210 { 211 result = position.getModel(); 212 break; 213 } 214 } 215 return result; 216 } 217 218 219 /** 220 Get a reference to the first {@link Position} object that holds a {@link Model} 221 with the given name from this {@code Scene}'s {@link List} of {@link Position}s. 222 223 @param name {@link String} name of the {@link Model} to search for 224 @return a {@link Model} with the give name from the {@link List} of {@link Position}s 225 */ 226 public Position getPositionByModelName(final String name) 227 { 228 Position result = null; 229 for (final Position position : positionList) 230 { 231 if ( name.equals(position.getModel().name) ) 232 { 233 result = position; 234 break; 235 } 236 } 237 return result; 238 } 239 240 241 /** 242 For debugging. 243 244 @return {@link String} representation of this {@code Scene} object 245 */ 246 @Override 247 public String toString() 248 { 249 String result = ""; 250 result += "Scene: " + name + "\n"; 251 result += camera.toString() + "\n"; 252 result += "This Scene has " + positionList.size() + " positions\n"; 253 int i = 0; 254 for (final Position p : positionList) 255 { 256 result += "Position " + (i++) + "\n"; 257 result += p.toString(); 258 } 259 return result; 260 } 261}