View Javadoc
1   /*
2    * Copyright (C) 2015 Alberto Irurueta Carro (alberto@irurueta.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.irurueta.geometry.io;
17  
18  /**
19   * Class containing a piece of 3D data loaded from a file.
20   * This class is used along with a LoaderIterator so that very large 3D files
21   * can be read in a step-by-step process returning consecutive DataChunk's of
22   * the file.
23   */
24  public class DataChunk {
25      /**
26       * Constant defining minimum number of color components, which is 1 for
27       * grayscale.
28       */
29      public static final int MIN_COLOR_COMPONENTS = 1;
30  
31      /**
32       * Constant defining default number of color components for RGB
33       */
34      public static final int DEFAULT_COLOR_COMPONENTS = 3;
35  
36      /**
37       * Array containing 3D coordinates for all points in a chunk in consecutive
38       * order, that is, array will contain values x0, y0, z0, x1, y1, z1, ...
39       * and so on.
40       */
41      private float[] coords;
42  
43      /**
44       * Array containing the color for each vertex in the chunk of data.
45       * Values will be stored consecutively as r0, g0, b0, r1, g1, b1, ...
46       * and so on. If transparency is provided, then array will be stored as
47       * r0, g0, b0, a0, r1, g1, b1, a1...
48       *
49       * @see #colorComponents
50       */
51      private short[] colors;
52  
53      /**
54       * Array containing indices of vertices to build the triangles forming
55       * the 3D shape on this chunk. Indices will be stored consecutively in sets
56       * of 3, indicating the 3 vertices of each triangle, that is: p1a, p2a, p3a,
57       * p1b, p2b, p3b, etc...
58       * The indices will be used to pick appropriate point coordinates, texture
59       * coordinates, normals or colors from their corresponding arrays.
60       */
61      private int[] indices;
62  
63      /**
64       * Array containing texture coordinates in a texture image for a given 3D
65       * point. All texture coordinates are stored consecutively in the array as:
66       * x0, y0, x1, y1, etc.
67       * Usually coordinates are stored in a normalized form having values between
68       * 0.0 and 1.0. Usually larger values indicate that the image will repeat
69       * when exceeding its borders, and negative values indicate that the image
70       * will be reversed.
71       */
72      private float[] textureCoords;
73  
74      /**
75       * Array containing normal coordinates for each vertex. Normal coordinates
76       * are useful to draw correct lighting. All normal coordinates are stored
77       * consecutively in the array as: x0, y0, z0, x1, y1, z1, etc.
78       */
79      private float[] normals;
80  
81      /**
82       * Indicates number of color components stored in the array.
83       * Usually for RGB it will be 3. When transparency is available, it will be
84       * 4.
85       */
86      private int colorComponents;
87  
88      /**
89       * X minimum coordinate of the bounding box containing all the data of this
90       * data chunk.
91       */
92      private float minX;
93  
94      /**
95       * Y minimum coordinate of the bounding box containing all the data of this
96       * data chunk.
97       */
98      private float minY;
99  
100     /**
101      * Z minimum coordinate of the bounding box containing all the data of this
102      * data chunk.
103      */
104     private float minZ;
105 
106     /**
107      * X maximum coordinate of the bounding box containing all the data of this
108      * data chunk.
109      */
110     private float maxX;
111 
112     /**
113      * Y maximum coordinate of the bounding box containing all the data of this
114      * data chunk.
115      */
116     private float maxY;
117 
118     /**
119      * Z maximum coordinate of the bounding box containing all the data of this
120      * data chunk.
121      */
122     private float maxZ;
123 
124     /**
125      * Material of this chunk. This will be used to define ambient colors,
126      * textures etc. for this chunk.
127      */
128     private Material material;
129 
130     /**
131      * Default Constructor
132      */
133     public DataChunk() {
134         coords = null;
135         colors = null;
136         indices = null;
137         textureCoords = null;
138         normals = null;
139 
140         colorComponents = DEFAULT_COLOR_COMPONENTS;
141 
142         minX = minY = minZ = Float.MAX_VALUE;
143         maxX = maxY = maxZ = -Float.MAX_VALUE;
144     }
145 
146     /**
147      * Sets array containing 3D coordinates for all points in a chunk in
148      * consecutive order, that is, array will contain values x0, y0, z0, x1, y1,
149      * z1, ... and so on.
150      *
151      * @param coords Array containing 3D coordinates for all points in a chunk.
152      */
153     public void setVerticesCoordinatesData(final float[] coords) {
154         this.coords = coords;
155     }
156 
157     /**
158      * Returns array containing 3D coordinates for all points in a chunk in
159      * consecutive order, that is, array will contain values x0, y0, z0, x1, y1,
160      * z1... and so on.
161      *
162      * @return Array containing 3D coordinates for all points in a chunk.
163      */
164     public float[] getVerticesCoordinatesData() {
165         return coords;
166     }
167 
168     /**
169      * Indicates if array containing 3D coordinates has been provided and is
170      * available for retrieval.
171      *
172      * @return True if available, false otherwise.
173      */
174     public boolean isVerticesCoordinatesDataAvailable() {
175         return coords != null;
176     }
177 
178     /**
179      * Sets array containing the color for each vertex in the chunk of data.
180      * Values will be stored consecutively as r0, g0, b0, r1, g1, b1, ...
181      * and so on. If transparency is provided, then array will be stored as
182      * r0, g0, b0, a0, r1, g1, b1, a1...
183      *
184      * @param colors Array containing the color for each vertex to be set
185      * @see #getColorComponents()
186      */
187     public void setColorData(final short[] colors) {
188         this.colors = colors;
189     }
190 
191     /**
192      * Returns array containing the color for each vertex in the chunk of data.
193      * Array usually contains data stored consecutively as
194      * r0, g0, b0, r1, g1, b1... and so on. If transparency is used, then array
195      * will be stored as r0, g0, b0, a0, r1, g1, b1, a1...
196      * There will be as many values per vertex as the number of color components
197      *
198      * @return array containing the color for each vertex in the chunk of data.
199      */
200     public short[] getColorData() {
201         return colors;
202     }
203 
204     /**
205      * Indicates if array containing the color for each vertex has been provided
206      * and is available for retrieval.
207      *
208      * @return True if available, false otherwise.
209      */
210     public boolean isColorDataAvailable() {
211         return colors != null;
212     }
213 
214     /**
215      * Sets array that contains indices of vertices to build the triangles
216      * forming the 3D shape on this chunk. Indices need to be stored
217      * consecutively in sets of 3, indicating the 3 vertices of each triangle,
218      * that is: p1a, p2a, p3a, p1b, p2b, p3b, etc.
219      * Provided indices will be used to pick appropriate point coordinates,
220      * texture coordinates, normals or colors from their corresponding arrays
221      *
222      * @param indices indices of vertices to build triangles.
223      */
224     public void setIndicesData(final int[] indices) {
225         this.indices = indices;
226     }
227 
228     /**
229      * Returns array containing indices of vertices to build the triangles
230      * forming the 3D shape on this chunk. Indices will be stored consecutively
231      * in sets of 3, indicating the 3 vertices of each triangle, that is: p1a,
232      * p2a, p3a, p1b, p2b, p3b, etc.
233      * Provided indices will be used to pick appropriate point coordinates,
234      * texture coordinates, normals or colors from their corresponding arrays.
235      *
236      * @return Array containing indices of vertices to build the triangles.
237      */
238     public int[] getIndicesData() {
239         return indices;
240     }
241 
242     /**
243      * Indicates if array containing the indices of vertices to build the
244      * triangles has been provided and is available for retrieval.
245      *
246      * @return True if available, false otherwise.
247      */
248     public boolean isIndicesDataAvailable() {
249         return indices != null;
250     }
251 
252     /**
253      * Sets array containing texture coordinates in a texture image for a given
254      * 3D point. All texture coordinates are stored consecutively in the array
255      * as: x0, y0, x1, y1, etc.
256      * Usually coordinates are stored in a normalized form having values between
257      * 0.0 and 1.0. Usually larger values indicate that the image will repeat
258      * when exceeding its borders, and negative values indicate that the image
259      * will be reversed.
260      *
261      * @param textureCoords Array containing texture coordinates in a texture
262      *                      image.
263      */
264     public void setTextureCoordinatesData(final float[] textureCoords) {
265         this.textureCoords = textureCoords;
266     }
267 
268     /**
269      * Returns array containing texture coordinates in a texture image for a
270      * given 3D point. All texture coordinates are stored consecutively in the
271      * array as: x0, y0, x1, y1, etc.
272      * Usually coordinates are stored in a normalized form having values between
273      * 0.0 and 1.0. Usually larger values indicate that the image will repeat
274      * when exceeding its borders, and negative values indicate that the image
275      * will be reversed.
276      *
277      * @return Array containing texture coordinates in a texture image.
278      */
279     public float[] getTextureCoordinatesData() {
280         return textureCoords;
281     }
282 
283     /**
284      * Indicates if array containing texture coordinates in a texture image has
285      * been provided and is available for retrieval.
286      *
287      * @return True if available, false otherwise.
288      */
289     public boolean isTextureCoordinatesDataAvailable() {
290         return textureCoords != null;
291     }
292 
293     /**
294      * Sets array containing normal coordinates for each vertex. Normal
295      * coordinates are useful to draw correct lighting. All normal coordinates
296      * are stored consecutively in the array as: x0, y0, z0, x1, y1, z1, etc.
297      *
298      * @param normals Array containing normal coordinates for each vertex.
299      */
300     public void setNormalsData(final float[] normals) {
301         this.normals = normals;
302     }
303 
304     /**
305      * Returns array containing normal coordinates for each vertex. Normal
306      * coordinates are useful to draw correct lighting. All normal coordinates
307      * are stored consecutively in the array as: x0, y0, z0, x1, y1, z1, etc.
308      *
309      * @return Array containing normal coordinates for each vertex.
310      */
311     public float[] getNormalsData() {
312         return normals;
313     }
314 
315     /**
316      * Indicates if array containing normal coordinates for each vertex has
317      * been provided and is available for retrieval.
318      *
319      * @return True if available, false otherwise.
320      */
321     public boolean isNormalsDataAvailable() {
322         return normals != null;
323     }
324 
325     /**
326      * Returns number of color components stored in the array.
327      * Usually for RGB it will be 3. When transparency is available, it will be
328      * 4. For gray-scale it will be 1.
329      *
330      * @return Number of color components.
331      */
332     public int getColorComponents() {
333         return colorComponents;
334     }
335 
336     /**
337      * Sets number of color components stored in the array.
338      * Usually for RGB it will be 3. When transparency is available, it will be
339      * 4. For gray-scale it will be 1.
340      *
341      * @param colorComponents Number of color components stored in the array.
342      * @throws IllegalArgumentException Raised if provided color components is
343      *                                  negative.
344      */
345     public void setColorComponents(final int colorComponents) {
346         if (colorComponents < MIN_COLOR_COMPONENTS) {
347             throw new IllegalArgumentException();
348         }
349 
350         this.colorComponents = colorComponents;
351     }
352 
353     /**
354      * Returns X minimum coordinate of the bounding box containing all the data
355      * of this data chunk.
356      *
357      * @return X minimum coordinate of the bounding box.
358      */
359     public float getMinX() {
360         return minX;
361     }
362 
363     /**
364      * Sets X minimum coordinate of the bounding box containing all the data of
365      * this data chunk.
366      *
367      * @param minX X minimum coordinate of the bounding box.
368      */
369     public void setMinX(final float minX) {
370         this.minX = minX;
371     }
372 
373     /**
374      * Returns Y minimum coordinate of the bounding box containing all the data
375      * of this data chunk.
376      *
377      * @return Y minimum coordinate of the bounding box.
378      */
379     public float getMinY() {
380         return minY;
381     }
382 
383     /**
384      * Sets Y minimum coordinate of the bounding box containing all the data of
385      * this data chunk.
386      *
387      * @param minY Y minimum coordinate of the bounding box.
388      */
389     public void setMinY(final float minY) {
390         this.minY = minY;
391     }
392 
393     /**
394      * Returns Z minimum coordinate of the bounding box containing all the data
395      * of this data chunk.
396      *
397      * @return Z minimum coordinate of the bounding box.
398      */
399     public float getMinZ() {
400         return minZ;
401     }
402 
403     /**
404      * Sets Z minimum coordinate of the bounding box containing all the data of
405      * this data chunk.
406      *
407      * @param minZ Z minimum coordinate of the bounding box.
408      */
409     public void setMinZ(final float minZ) {
410         this.minZ = minZ;
411     }
412 
413     /**
414      * Returns X maximum coordinate of the bounding box containing all the data
415      * of this data chunk.
416      *
417      * @return X maximum coordinate of the bounding box.
418      */
419     public float getMaxX() {
420         return maxX;
421     }
422 
423     /**
424      * Sets X maximum coordinate of the bounding box containing all the data of
425      * this data chunk.
426      *
427      * @param maxX X maximum coordinate of the bounding box.
428      */
429     public void setMaxX(final float maxX) {
430         this.maxX = maxX;
431     }
432 
433     /**
434      * Returns Y maximum coordinate of the bounding box containing all the data
435      * of this data chunk.
436      *
437      * @return Y maximum coordinate of the bounding box.
438      */
439     public float getMaxY() {
440         return maxY;
441     }
442 
443     /**
444      * Sets Y maximum coordinate of the bounding box containing all the data
445      * of this data chunk.
446      *
447      * @param maxY Y maximum coordinate of the bounding box.
448      */
449     public void setMaxY(final float maxY) {
450         this.maxY = maxY;
451     }
452 
453     /**
454      * Returns Z maximum coordinate of the bounding box containing all the data
455      * of this data chunk.
456      *
457      * @return Z maximum coordinate of the bounding box.
458      */
459     public float getMaxZ() {
460         return maxZ;
461     }
462 
463     /**
464      * Sets Z maximum coordinate of the bounding box containing all the data
465      * of this data chunk.
466      *
467      * @param maxZ Z maximum coordinate of the bounding box.
468      */
469     public void setMaxZ(final float maxZ) {
470         this.maxZ = maxZ;
471     }
472 
473     /**
474      * Returns material of this chunk. This will be used to define ambient
475      * colors, textures, etc. for this chunk.
476      *
477      * @return Materials of this chunk.
478      */
479     public Material getMaterial() {
480         return material;
481     }
482 
483     /**
484      * Sets material of this chunk. This will be used to define ambient colors,
485      * textures, etc. for this chunk.
486      *
487      * @param material Material of this chunk.
488      */
489     public void setMaterial(final Material material) {
490         this.material = material;
491     }
492 
493     /**
494      * Returns boolean indicating whether a material has been provided for this
495      * chunk.
496      *
497      * @return True if material is available, false otherwise.
498      */
499     public boolean isMaterialAvailable() {
500         return material != null;
501     }
502 
503     //TODO: create class to compute DataChunk statistics: bounding box, vertex
504     // average, color limits, standard deviation and average, normal limits,
505     // standard deviation and average, etc.
506 }