001: /*
002: * $RCSfile: GeneralizedVertexList.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.3 $
041: * $Date: 2007/02/09 17:20:22 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.utils.geometry.compression;
046:
047: import java.util.ArrayList;
048: import javax.media.j3d.GeometryArray;
049: import javax.media.j3d.GeometryStripArray;
050: import javax.media.j3d.LineStripArray;
051: import javax.media.j3d.PointArray;
052: import javax.media.j3d.TriangleArray;
053: import javax.media.j3d.TriangleFanArray;
054: import javax.media.j3d.TriangleStripArray;
055: import javax.vecmath.Color3f;
056: import javax.vecmath.Color4f;
057: import javax.vecmath.Point3f;
058: import javax.vecmath.Vector3f;
059:
060: /**
061: * The GeneralizedVertexList class is a variable-size list used to
062: * collect the vertices for a generalized strip of points, lines, or
063: * triangles. This is used by the GeometryDecompressor. This class
064: * implements the GeneralizedStripFlags interface and provides methods
065: * for copying instance vertex data into various fixed-size
066: * GeometryArray representations.
067: *
068: * @see GeneralizedStrip
069: * @see GeometryDecompressor
070: */
071: class GeneralizedVertexList implements GeneralizedStripFlags {
072:
073: // The ArrayList containing the vertices.
074: private ArrayList vertices;
075:
076: // Booleans for individual vertex components.
077: private boolean hasColor3 = false;
078: private boolean hasColor4 = false;
079: private boolean hasNormals = false;
080:
081: // Indicates the vertex winding of front-facing triangles in this strip.
082: private int frontFace;
083:
084: /**
085: * Count of number of strips generated after conversion to GeometryArray.
086: */
087: int stripCount;
088:
089: /**
090: * Count of number of vertices generated after conversion to GeometryArray.
091: */
092: int vertexCount;
093:
094: /**
095: * Count of number of triangles generated after conversion to GeometryArray.
096: */
097: int triangleCount;
098:
099: /**
100: * Bits describing the data bundled with each vertex. This is specified
101: * using the GeometryArray mask components.
102: */
103: int vertexFormat;
104:
105: /**
106: * Creates a new GeneralizedVertexList for the specified vertex format.
107: * @param vertexFormat a mask indicating which components are
108: * present in each vertex, as used by GeometryArray.
109: * @param frontFace a flag, either GeneralizedStripFlags.FRONTFACE_CW or
110: * GeneralizedStripFlags.FRONTFACE_CCW, indicating front face winding
111: * @param initSize initial number of elements
112: * @see GeometryArray
113: */
114: GeneralizedVertexList(int vertexFormat, int frontFace, int initSize) {
115: this .frontFace = frontFace;
116: setVertexFormat(vertexFormat);
117:
118: if (initSize == 0)
119: vertices = new ArrayList();
120: else
121: vertices = new ArrayList(initSize);
122:
123: stripCount = 0;
124: vertexCount = 0;
125: triangleCount = 0;
126: }
127:
128: /**
129: * Creates a new GeneralizedVertexList for the specified vertex format.
130: * @param vertexFormat a mask indicating which components are
131: * present in each vertex, as used by GeometryArray.
132: * @param frontFace a flag, either GeneralizedStripFlags.FRONTFACE_CW or
133: * GeneralizedStripFlags.FRONTFACE_CCW, indicating front face winding
134: * @see GeometryArray
135: */
136: GeneralizedVertexList(int vertexFormat, int frontFace) {
137: this (vertexFormat, frontFace, 0);
138: }
139:
140: /**
141: * Sets the vertex format for this vertex list.
142: * @param vertexFormat a mask indicating which components are
143: * present in each vertex, as used by GeometryArray.
144: */
145: void setVertexFormat(int vertexFormat) {
146: this .vertexFormat = vertexFormat;
147:
148: if ((vertexFormat & GeometryArray.NORMALS) != 0)
149: hasNormals = true;
150:
151: if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4)
152: hasColor4 = true;
153: else if ((vertexFormat & GeometryArray.COLOR_3) == GeometryArray.COLOR_3)
154: hasColor3 = true;
155: }
156:
157: /**
158: * A class with fields corresponding to all the data that can be bundled
159: * with the vertices of generalized strips.
160: */
161: class Vertex {
162: int flag;
163: Point3f coord;
164: Color3f color3;
165: Color4f color4;
166: Vector3f normal;
167:
168: Vertex(Point3f p, Vector3f n, Color4f c, int flag) {
169: this .flag = flag;
170: coord = new Point3f(p);
171:
172: if (hasNormals)
173: normal = new Vector3f(n);
174:
175: if (hasColor3)
176: color3 = new Color3f(c.x, c.y, c.z);
177:
178: else if (hasColor4)
179: color4 = new Color4f(c);
180: }
181: }
182:
183: /**
184: * Copy vertex data to a new Vertex object and add it to this list.
185: */
186: void addVertex(Point3f pos, Vector3f norm, Color4f color, int flag) {
187: vertices.add(new Vertex(pos, norm, color, flag));
188: }
189:
190: /**
191: * Return the number of vertices in this list.
192: */
193: int size() {
194: return vertices.size();
195: }
196:
197: // GeneralizedStripFlags interface implementation
198: public int getFlagCount() {
199: return vertices.size();
200: }
201:
202: // GeneralizedStripFlags interface implementation
203: public int getFlag(int index) {
204: return ((Vertex) vertices.get(index)).flag;
205: }
206:
207: // Copy vertices in the given order to a fixed-length GeometryArray.
208: // Using the array versions of the GeometryArray set() methods results in
209: // a significant performance improvement despite needing to create
210: // fixed-length arrays to hold the vertex elements.
211: private void copyVertexData(GeometryArray ga,
212: GeneralizedStrip.IntList indices) {
213: Vertex v;
214: Point3f p3f[] = new Point3f[indices.count];
215:
216: if (hasNormals) {
217: Vector3f v3f[] = new Vector3f[indices.count];
218: if (hasColor3) {
219: Color3f c3f[] = new Color3f[indices.count];
220: for (int i = 0; i < indices.count; i++) {
221: v = (Vertex) vertices.get(indices.ints[i]);
222: p3f[i] = v.coord;
223: v3f[i] = v.normal;
224: c3f[i] = v.color3;
225: }
226: ga.setColors(0, c3f);
227:
228: } else if (hasColor4) {
229: Color4f c4f[] = new Color4f[indices.count];
230: for (int i = 0; i < indices.count; i++) {
231: v = (Vertex) vertices.get(indices.ints[i]);
232: p3f[i] = v.coord;
233: v3f[i] = v.normal;
234: c4f[i] = v.color4;
235: }
236: ga.setColors(0, c4f);
237:
238: } else {
239: for (int i = 0; i < indices.count; i++) {
240: v = (Vertex) vertices.get(indices.ints[i]);
241: p3f[i] = v.coord;
242: v3f[i] = v.normal;
243: }
244: }
245: ga.setNormals(0, v3f);
246:
247: } else {
248: if (hasColor3) {
249: Color3f c3f[] = new Color3f[indices.count];
250: for (int i = 0; i < indices.count; i++) {
251: v = (Vertex) vertices.get(indices.ints[i]);
252: p3f[i] = v.coord;
253: c3f[i] = v.color3;
254: }
255: ga.setColors(0, c3f);
256:
257: } else if (hasColor4) {
258: Color4f c4f[] = new Color4f[indices.count];
259: for (int i = 0; i < indices.count; i++) {
260: v = (Vertex) vertices.get(indices.ints[i]);
261: p3f[i] = v.coord;
262: c4f[i] = v.color4;
263: }
264: ga.setColors(0, c4f);
265:
266: } else {
267: for (int i = 0; i < indices.count; i++) {
268: v = (Vertex) vertices.get(indices.ints[i]);
269: p3f[i] = v.coord;
270: }
271: }
272: }
273: ga.setCoordinates(0, p3f);
274: }
275:
276: /**
277: * Output a PointArray.
278: */
279: PointArray toPointArray() {
280: int size = vertices.size();
281:
282: if (size > 0) {
283: PointArray pa = new PointArray(size, vertexFormat);
284: GeneralizedStrip.IntList il = new GeneralizedStrip.IntList(
285: size);
286:
287: il.fillAscending();
288: copyVertexData(pa, il);
289:
290: vertexCount += size;
291: return pa;
292: } else
293: return null;
294: }
295:
296: /**
297: * Output a TriangleArray.
298: */
299: TriangleArray toTriangleArray() {
300: int vertices[] = GeneralizedStrip.toTriangles(this , frontFace);
301:
302: if (vertices != null) {
303: TriangleArray ta;
304: GeneralizedStrip.IntList il;
305:
306: ta = new TriangleArray(vertices.length, vertexFormat);
307: il = new GeneralizedStrip.IntList(vertices);
308: copyVertexData(ta, il);
309:
310: vertexCount += vertices.length;
311: triangleCount += vertices.length / 3;
312: return ta;
313: } else
314: return null;
315: }
316:
317: /**
318: * Output a LineStripArray.
319: */
320: LineStripArray toLineStripArray() {
321: GeneralizedStrip.StripArray stripArray = GeneralizedStrip
322: .toLineStrips(this );
323:
324: if (stripArray != null) {
325: LineStripArray lsa;
326: lsa = new LineStripArray(stripArray.vertices.count,
327: vertexFormat, stripArray.stripCounts.trim());
328:
329: copyVertexData(lsa, stripArray.vertices);
330:
331: vertexCount += stripArray.vertices.count;
332: stripCount += stripArray.stripCounts.count;
333: return lsa;
334: } else
335: return null;
336: }
337:
338: /**
339: * Output a TriangleStripArray.
340: */
341: TriangleStripArray toTriangleStripArray() {
342: GeneralizedStrip.StripArray stripArray = GeneralizedStrip
343: .toTriangleStrips(this , frontFace);
344:
345: if (stripArray != null) {
346: TriangleStripArray tsa;
347: tsa = new TriangleStripArray(stripArray.vertices.count,
348: vertexFormat, stripArray.stripCounts.trim());
349:
350: copyVertexData(tsa, stripArray.vertices);
351:
352: vertexCount += stripArray.vertices.count;
353: stripCount += stripArray.stripCounts.count;
354: return tsa;
355: } else
356: return null;
357: }
358:
359: /**
360: * Output triangle strip and triangle fan arrays.
361: * @return a 2-element array of GeometryStripArray; element 0 if non-null
362: * will contain a TriangleStripArray, and element 1 if non-null will
363: * contain a TriangleFanArray.
364: */
365: GeometryStripArray[] toStripAndFanArrays() {
366: GeneralizedStrip.StripArray stripArray[] = GeneralizedStrip
367: .toStripsAndFans(this , frontFace);
368:
369: GeometryStripArray gsa[] = new GeometryStripArray[2];
370:
371: if (stripArray[0] != null) {
372: gsa[0] = new TriangleStripArray(
373: stripArray[0].vertices.count, vertexFormat,
374: stripArray[0].stripCounts.trim());
375:
376: copyVertexData(gsa[0], stripArray[0].vertices);
377:
378: vertexCount += stripArray[0].vertices.count;
379: stripCount += stripArray[0].stripCounts.count;
380: }
381:
382: if (stripArray[1] != null) {
383: gsa[1] = new TriangleFanArray(stripArray[1].vertices.count,
384: vertexFormat, stripArray[1].stripCounts.trim());
385:
386: copyVertexData(gsa[1], stripArray[1].vertices);
387:
388: vertexCount += stripArray[1].vertices.count;
389: stripCount += stripArray[1].stripCounts.count;
390: }
391: return gsa;
392: }
393:
394: /**
395: * Output triangle strip and and triangle arrays.
396: * @return a 2-element array of GeometryArray; element 0 if non-null
397: * will contain a TriangleStripArray, and element 1 if non-null will
398: * contain a TriangleArray.
399: */
400: GeometryArray[] toStripAndTriangleArrays() {
401: GeneralizedStrip.StripArray stripArray[] = GeneralizedStrip
402: .toStripsAndTriangles(this , frontFace, 4, 12);
403:
404: GeometryArray ga[] = new GeometryArray[2];
405:
406: if (stripArray[0] != null) {
407: ga[0] = new TriangleStripArray(
408: stripArray[0].vertices.count, vertexFormat,
409: stripArray[0].stripCounts.trim());
410:
411: copyVertexData(ga[0], stripArray[0].vertices);
412:
413: vertexCount += stripArray[0].vertices.count;
414: stripCount += stripArray[0].stripCounts.count;
415: }
416:
417: if (stripArray[1] != null) {
418: ga[1] = new TriangleArray(stripArray[1].vertices.count,
419: vertexFormat);
420:
421: copyVertexData(ga[1], stripArray[1].vertices);
422: triangleCount += stripArray[1].vertices.count / 3;
423: }
424: return ga;
425: }
426: }
|