001/* 002 * Renderer 9. The MIT License. 003 * Copyright (c) 2022 rlkraft@pnw.edu 004 * See LICENSE for details. 005*/ 006 007package renderer.scene; 008 009/** 010 A {@code Position} data structure represents a geometric object 011 in a distinct location in three-dimensional view space as part 012 of a {@link Scene}. 013<p> 014 A {@code Position} object holds references to a {@link Model} object 015 and a {@link Matrix} object. The {@link Model} represents the geometric 016 object in the {@link Scene}. The {@link Matrix} determines the model's 017 location and orientation in the {@link Camera}'s view coordinate system. 018 The {@code Position}'s matrix helps us solve the problem of placing 019 and moving a model in a scene. 020<p> 021 When the renderer renders this {@code Position}'s {@link Model} into 022 a {@link renderer.framebuffer.FrameBuffer}, the first stage of the 023 rendering pipeline, {@link renderer.pipeline.Model2World}, multiplies 024 every {@link Vertex} in the {@link Model}'s vertex list by this 025 {@code Position}'s {@link Matrix}, which converts the coordinates in 026 each {@link Vertex} from the model's own local coordinate system to 027 the world coordinate system (which is "shared" by all the other models 028 in the scene). This matrix multiplication has the effect of "placing" 029 the model in world space at an appropriate location (using the 030 translation part of the matrix) and in the appropriate orientation 031 (using the rotation part of the matrix). 032*/ 033public final class Position 034{ 035 private Model model; 036 private Matrix matrix; 037 public final String name; 038 public boolean visible; 039 public boolean debug; 040 041 /** 042 Construct a {@code Position} with the identity {@link Matrix} 043 and the given {@link Model} object. 044 045 @param model {@link Model} object to place at this {@code Position} 046 @throws NullPointerException if {@code model} is {@code null} 047 */ 048 public Position(final Model model) 049 { 050 this(model, 051 model.name, // default Position name 052 Matrix.identity(), // default matrix 053 true, // visible 054 false); // debug 055 } 056 057 058 /** 059 Construct a {@code Position} with the identity {@link Matrix}, 060 the given {@link String} name, and the given {@link Model} object. 061 062 @param model {@link Model} object to place at this {@code Position} 063 @param name {@link String} name for this {@code Position} 064 @throws NullPointerException if {@code model} is {@code null} 065 @throws NullPointerException if {@code name} is {@code null} 066 */ 067 public Position(final Model model, final String name) 068 { 069 this(model, 070 name, 071 Matrix.identity(), // default matrix 072 true, // visible 073 false); // debug 074 } 075 076 077 /** 078 Construct a {@code Position} with the given transformation {@link Matrix}, 079 the given {@link String} name, and the given {@link Model} object. 080 081 @param model {@link Model} object to place at this {@code Position} 082 @param name {@link String} name for this {@code Position} 083 @param matrix transformation {@link Matrix} for this {@code Position} 084 @throws NullPointerException if {@code model} is {@code null} 085 @throws NullPointerException if {@code name} is {@code null} 086 @throws NullPointerException if {@code matrix} is {@code null} 087 */ 088 public Position(final Model model, 089 final String name, 090 final Matrix matrix) 091 { 092 this(model, 093 name, 094 matrix, 095 true, // visible 096 false); // debug 097 } 098 099 100 /** 101 Construct a {@code Position} with the given transformation {@link Matrix} 102 and the given {@link Model} object. 103 104 @param model {@link Model} object to place at this {@code Position} 105 @param matrix transformation {@link Matrix} for this {@code Position} 106 @throws NullPointerException if {@code model} is {@code null} 107 @throws NullPointerException if {@code matrix} is {@code null} 108 */ 109 public Position(final Model model, 110 final Matrix matrix) 111 { 112 this(model, 113 model.name, // default Position name 114 matrix, 115 true, // visible 116 false); // debug 117 } 118 119 120 /** 121 Construct a {@code Position} with the given translation {@link Vector}, 122 the given {@link String} name, and the given {@link Model} object. 123 124 @deprecated This constructor is here for compatibility with renderers 1 through 8. 125 126 @param model {@link Model} object to place at this {@code Position} 127 @param name {@link String} name for this {@code Position} 128 @param translation translation {@link Vector} for this {@code Position} 129 @throws NullPointerException if {@code model} is {@code null} 130 @throws NullPointerException if {@code name} is {@code null} 131 @throws NullPointerException if {@code translation} is {@code null} 132 */ 133 @Deprecated 134 public Position(final Model model, 135 final String name, 136 final Vector translation) 137 { 138 this(model, 139 name, 140 Matrix.translate(translation.x, translation.y, translation.z), 141 true, // visible 142 false); // debug 143 } 144 145 146 /** 147 Construct a {@code Position} with the given translation {@link Vector} 148 and the given {@link Model} object. 149 150 @deprecated This constructor is here for compatibility with renderers 1 through 8. 151 152 @param model {@link Model} object to place at this {@code Position} 153 @param translation translation {@link Vector} for this {@code Position} 154 @throws NullPointerException if {@code model} is {@code null} 155 @throws NullPointerException if {@code translation} is {@code null} 156 */ 157 @Deprecated 158 public Position(final Model model, 159 final Vector translation) 160 { 161 this(model, 162 model.name, // default Position name 163 Matrix.translate(translation.x, translation.y, translation.z), 164 true, // visible 165 false); // debug 166 } 167 168 169 /** 170 Construct a {@code Position} object with all the given data. 171 172 @deprecated This constructor is here for compatibility with renderers 1 through 8. 173 174 @param model {@link Model} object to place at this {@code Position} 175 @param name {@link String} name for this {@code Position} 176 @param translation translation {@link Vector} for this {@code Position} 177 @param visible boolean that determines this {@code Position}'s visibility 178 @param debug boolean that determines if this {@code Position} is logged 179 @throws NullPointerException if {@code model} is {@code null} 180 @throws NullPointerException if {@code translation} is {@code null} 181 @throws NullPointerException if {@code name} is {@code null} 182 */ 183 @Deprecated 184 public Position(final Model model, 185 final String name, 186 final Vector translation, 187 final boolean visible, 188 final boolean debug) 189 { 190 this(model, 191 model.name, // default Position name 192 Matrix.translate(translation.x, translation.y, translation.z), 193 visible, 194 debug); 195 } 196 197 198 /** 199 Construct a {@code Position} object with all the given data. 200 201 @param model {@link Model} object to place at this {@code Position} 202 @param name {@link String} name for this {@code Position} 203 @param matrix transformation {@link Matrix} for this {@code Position} 204 @param visible boolean that determines this {@code Position}'s visibility 205 @param debug boolean that determines if this {@code Position} is logged 206 @throws NullPointerException if {@code model} is {@code null} 207 @throws NullPointerException if {@code name} is {@code null} 208 @throws NullPointerException if {@code matrix} is {@code null} 209 */ 210 public Position(final Model model, 211 final String name, 212 final Matrix matrix, 213 final boolean visible, 214 final boolean debug) 215 { 216 if (null == model) 217 throw new NullPointerException("model must not be null"); 218 if (null == name) 219 throw new NullPointerException("name must not be null"); 220 if (null == matrix) 221 throw new NullPointerException("matrix must not be null"); 222 223 this.model = model; 224 this.matrix = matrix; 225 this.name = name; 226 this.visible = visible; 227 this.debug = debug; 228 } 229 230 231 /** 232 Get a reference to this {@code Position}'s {@link Model} object. 233 234 @return a reference to this {@code Position}'s {@link Model} object 235 */ 236 public Model getModel() 237 { 238 return this.model; 239 } 240 241 242 /** 243 Set this {@code Position}'s {@link Model} object. 244 245 @param model {@link Model} object to place at this {@code Position} 246 @return a reference to this {@link Position} object to facilitate chaining method calls 247 @throws NullPointerException if {@code model} is {@code null} 248 */ 249 public Position setModel(final Model model) 250 { 251 if (null == model) 252 throw new NullPointerException("model must not be null"); 253 254 this.model = model; 255 return this; 256 } 257 258 259 /** 260 Get a reference to this {@code Position}'s {@link Matrix} object. 261 262 @return a reference to this {@code Position}'s {@link Matrix} object 263 */ 264 public Matrix getMatrix() 265 { 266 return this.matrix; 267 } 268 269 270 /** 271 Set this {@code Position}'s transformation {@link Matrix}. 272 273 @param matrix {@link Matrix} object to use in this {@code Position} 274 @return a reference to this {@link Position} object to facilitate chaining method calls 275 @throws NullPointerException if {@code matrix} is {@code null} 276 */ 277 public Position transform(final Matrix matrix) 278 { 279 if (null == matrix) 280 throw new NullPointerException("matrix must not be null"); 281 282 this.matrix = matrix; 283 return this; 284 } 285 286 287 /** 288 Set this {@code Position}'s translation vector within 289 this {@code Position}'s {@link Matrix} object. 290 291 @deprecated Use the {@link Matrix} API instead of this method. 292 This method is here for compatibility with renderers 1 through 8. 293 294 @param x translation amount in the x-direction 295 @param y translation amount in the y-direction 296 @param z translation amount in the z-direction 297 @return a reference to this {@link Position} object to facilitate chaining method calls 298 */ 299 @Deprecated 300 public Position translate(final double x, 301 final double y, 302 final double z) 303 { 304 this.matrix = Matrix.translate(x, y, z); 305 return this; 306 } 307 308 309 /** 310 For debugging. 311 312 @return {@link String} representation of this {@code Position} object 313 */ 314 @Override 315 public String toString() 316 { 317 String result = ""; 318 result += "Position: " + name + "\n"; 319 result += "This Position's visibility is: " + visible + "\n"; 320 result += "This Position's Matrix is\n"; 321 result += matrix + "\n"; 322 result += "This Position's Model is\n"; 323 result += (null == model) ? "null\n" : model; 324 return result; 325 } 326}