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}