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 }