001: /*
002: * $RCSfile: GeneralizedVertexList.java,v $
003: *
004: * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.5 $
028: * $Date: 2008/02/28 20:17:21 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.*;
035: import java.util.*;
036:
037: /**
038: * The GeneralizedVertexList class is a variable-size list used to
039: * collect the vertices for a generalized strip of points, lines, or
040: * triangles. This is used by the GeometryDecompressor. This class
041: * implements the GeneralizedStripFlags interface and provides methods
042: * for copying instance vertex data into various fixed-size
043: * GeometryArray representations.
044: *
045: * @see GeneralizedStrip
046: * @see GeometryDecompressor
047: */
048: class GeneralizedVertexList implements GeneralizedStripFlags {
049:
050: // The ArrayList containing the vertices.
051: private ArrayList vertices;
052:
053: // Booleans for individual vertex components.
054: private boolean hasColor3 = false;
055: private boolean hasColor4 = false;
056: private boolean hasNormals = false;
057:
058: // Indicates the vertex winding of front-facing triangles in this strip.
059: private int frontFace;
060:
061: /**
062: * Count of number of strips generated after conversion to GeometryArray.
063: */
064: int stripCount;
065:
066: /**
067: * Count of number of vertices generated after conversion to GeometryArray.
068: */
069: int vertexCount;
070:
071: /**
072: * Count of number of triangles generated after conversion to GeometryArray.
073: */
074: int triangleCount;
075:
076: /**
077: * Bits describing the data bundled with each vertex. This is specified
078: * using the GeometryArray mask components.
079: */
080: int vertexFormat;
081:
082: /**
083: * Creates a new GeneralizedVertexList for the specified vertex format.
084: * @param vertexFormat a mask indicating which components are
085: * present in each vertex, as used by GeometryArray.
086: * @param frontFace a flag, either GeneralizedStripFlags.FRONTFACE_CW or
087: * GeneralizedStripFlags.FRONTFACE_CCW, indicating front face winding
088: * @param initSize initial number of elements
089: * @see GeometryArray
090: */
091: GeneralizedVertexList(int vertexFormat, int frontFace, int initSize) {
092: this .frontFace = frontFace;
093: setVertexFormat(vertexFormat);
094:
095: if (initSize == 0)
096: vertices = new ArrayList();
097: else
098: vertices = new ArrayList(initSize);
099:
100: stripCount = 0;
101: vertexCount = 0;
102: triangleCount = 0;
103: }
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: * @see GeometryArray
112: */
113: GeneralizedVertexList(int vertexFormat, int frontFace) {
114: this (vertexFormat, frontFace, 0);
115: }
116:
117: /**
118: * Sets the vertex format for this vertex list.
119: * @param vertexFormat a mask indicating which components are
120: * present in each vertex, as used by GeometryArray.
121: */
122: void setVertexFormat(int vertexFormat) {
123: this .vertexFormat = vertexFormat;
124:
125: if ((vertexFormat & GeometryArray.NORMALS) != 0)
126: hasNormals = true;
127:
128: if ((vertexFormat & GeometryArray.COLOR) != 0)
129: if ((vertexFormat & GeometryArray.WITH_ALPHA) != 0)
130: hasColor4 = true;
131: else
132: hasColor3 = true;
133: }
134:
135: /**
136: * A class with fields corresponding to all the data that can be bundled
137: * with the vertices of generalized strips.
138: */
139: class Vertex {
140: int flag;
141: Point3f coord;
142: Color3f color3;
143: Color4f color4;
144: Vector3f normal;
145:
146: Vertex(Point3f p, Vector3f n, Color4f c, int flag) {
147: this .flag = flag;
148: coord = new Point3f(p);
149:
150: if (hasNormals)
151: normal = new Vector3f(n);
152:
153: if (hasColor3)
154: color3 = new Color3f(c.x, c.y, c.z);
155:
156: else if (hasColor4)
157: color4 = new Color4f(c);
158: }
159: }
160:
161: /**
162: * Copy vertex data to a new Vertex object and add it to this list.
163: */
164: void addVertex(Point3f pos, Vector3f norm, Color4f color, int flag) {
165: vertices.add(new Vertex(pos, norm, color, flag));
166: }
167:
168: /**
169: * Return the number of vertices in this list.
170: */
171: int size() {
172: return vertices.size();
173: }
174:
175: // GeneralizedStripFlags interface implementation
176: public int getFlagCount() {
177: return vertices.size();
178: }
179:
180: // GeneralizedStripFlags interface implementation
181: public int getFlag(int index) {
182: return ((Vertex) vertices.get(index)).flag;
183: }
184:
185: // Copy vertices in the given order to a fixed-length GeometryArray.
186: // Using the array versions of the GeometryArray set() methods results in
187: // a significant performance improvement despite needing to create
188: // fixed-length arrays to hold the vertex elements.
189: private void copyVertexData(GeometryArray ga,
190: GeneralizedStrip.IntList indices) {
191: Vertex v;
192: Point3f p3f[] = new Point3f[indices.count];
193:
194: if (hasNormals) {
195: Vector3f v3f[] = new Vector3f[indices.count];
196: if (hasColor3) {
197: Color3f c3f[] = new Color3f[indices.count];
198: for (int i = 0; i < indices.count; i++) {
199: v = (Vertex) vertices.get(indices.ints[i]);
200: p3f[i] = v.coord;
201: v3f[i] = v.normal;
202: c3f[i] = v.color3;
203: }
204: ga.setColors(0, c3f);
205:
206: } else if (hasColor4) {
207: Color4f c4f[] = new Color4f[indices.count];
208: for (int i = 0; i < indices.count; i++) {
209: v = (Vertex) vertices.get(indices.ints[i]);
210: p3f[i] = v.coord;
211: v3f[i] = v.normal;
212: c4f[i] = v.color4;
213: }
214: ga.setColors(0, c4f);
215:
216: } else {
217: for (int i = 0; i < indices.count; i++) {
218: v = (Vertex) vertices.get(indices.ints[i]);
219: p3f[i] = v.coord;
220: v3f[i] = v.normal;
221: }
222: }
223: ga.setNormals(0, v3f);
224:
225: } else {
226: if (hasColor3) {
227: Color3f c3f[] = new Color3f[indices.count];
228: for (int i = 0; i < indices.count; i++) {
229: v = (Vertex) vertices.get(indices.ints[i]);
230: p3f[i] = v.coord;
231: c3f[i] = v.color3;
232: }
233: ga.setColors(0, c3f);
234:
235: } else if (hasColor4) {
236: Color4f c4f[] = new Color4f[indices.count];
237: for (int i = 0; i < indices.count; i++) {
238: v = (Vertex) vertices.get(indices.ints[i]);
239: p3f[i] = v.coord;
240: c4f[i] = v.color4;
241: }
242: ga.setColors(0, c4f);
243:
244: } else {
245: for (int i = 0; i < indices.count; i++) {
246: v = (Vertex) vertices.get(indices.ints[i]);
247: p3f[i] = v.coord;
248: }
249: }
250: }
251: ga.setCoordinates(0, p3f);
252: }
253:
254: /**
255: * Output a PointArray.
256: */
257: PointArray toPointArray() {
258: int size = vertices.size();
259:
260: if (size > 0) {
261: PointArray pa = new PointArray(size, vertexFormat);
262: GeneralizedStrip.IntList il = new GeneralizedStrip.IntList(
263: size);
264:
265: il.fillAscending();
266: copyVertexData(pa, il);
267:
268: vertexCount += size;
269: return pa;
270: } else
271: return null;
272: }
273:
274: /**
275: * Output a TriangleArray.
276: */
277: TriangleArray toTriangleArray() {
278: int vertices[] = GeneralizedStrip.toTriangles(this , frontFace);
279:
280: if (vertices != null) {
281: TriangleArray ta;
282: GeneralizedStrip.IntList il;
283:
284: ta = new TriangleArray(vertices.length, vertexFormat);
285: il = new GeneralizedStrip.IntList(vertices);
286: copyVertexData(ta, il);
287:
288: vertexCount += vertices.length;
289: triangleCount += vertices.length / 3;
290: return ta;
291: } else
292: return null;
293: }
294:
295: /**
296: * Output a LineStripArray.
297: */
298: LineStripArray toLineStripArray() {
299: GeneralizedStrip.StripArray stripArray = GeneralizedStrip
300: .toLineStrips(this );
301:
302: if (stripArray != null) {
303: LineStripArray lsa;
304: lsa = new LineStripArray(stripArray.vertices.count,
305: vertexFormat, stripArray.stripCounts.trim());
306:
307: copyVertexData(lsa, stripArray.vertices);
308:
309: vertexCount += stripArray.vertices.count;
310: stripCount += stripArray.stripCounts.count;
311: return lsa;
312: } else
313: return null;
314: }
315:
316: /**
317: * Output a TriangleStripArray.
318: */
319: TriangleStripArray toTriangleStripArray() {
320: GeneralizedStrip.StripArray stripArray = GeneralizedStrip
321: .toTriangleStrips(this , frontFace);
322:
323: if (stripArray != null) {
324: TriangleStripArray tsa;
325: tsa = new TriangleStripArray(stripArray.vertices.count,
326: vertexFormat, stripArray.stripCounts.trim());
327:
328: copyVertexData(tsa, stripArray.vertices);
329:
330: vertexCount += stripArray.vertices.count;
331: stripCount += stripArray.stripCounts.count;
332: return tsa;
333: } else
334: return null;
335: }
336:
337: /**
338: * Output triangle strip and triangle fan arrays.
339: * @return a 2-element array of GeometryStripArray; element 0 if non-null
340: * will contain a TriangleStripArray, and element 1 if non-null will
341: * contain a TriangleFanArray.
342: */
343: GeometryStripArray[] toStripAndFanArrays() {
344: GeneralizedStrip.StripArray stripArray[] = GeneralizedStrip
345: .toStripsAndFans(this , frontFace);
346:
347: GeometryStripArray gsa[] = new GeometryStripArray[2];
348:
349: if (stripArray[0] != null) {
350: gsa[0] = new TriangleStripArray(
351: stripArray[0].vertices.count, vertexFormat,
352: stripArray[0].stripCounts.trim());
353:
354: copyVertexData(gsa[0], stripArray[0].vertices);
355:
356: vertexCount += stripArray[0].vertices.count;
357: stripCount += stripArray[0].stripCounts.count;
358: }
359:
360: if (stripArray[1] != null) {
361: gsa[1] = new TriangleFanArray(stripArray[1].vertices.count,
362: vertexFormat, stripArray[1].stripCounts.trim());
363:
364: copyVertexData(gsa[1], stripArray[1].vertices);
365:
366: vertexCount += stripArray[1].vertices.count;
367: stripCount += stripArray[1].stripCounts.count;
368: }
369: return gsa;
370: }
371:
372: /**
373: * Output triangle strip and and triangle arrays.
374: * @return a 2-element array of GeometryArray; element 0 if non-null
375: * will contain a TriangleStripArray, and element 1 if non-null will
376: * contain a TriangleArray.
377: */
378: GeometryArray[] toStripAndTriangleArrays() {
379: GeneralizedStrip.StripArray stripArray[] = GeneralizedStrip
380: .toStripsAndTriangles(this , frontFace, 4, 12);
381:
382: GeometryArray ga[] = new GeometryArray[2];
383:
384: if (stripArray[0] != null) {
385: ga[0] = new TriangleStripArray(
386: stripArray[0].vertices.count, vertexFormat,
387: stripArray[0].stripCounts.trim());
388:
389: copyVertexData(ga[0], stripArray[0].vertices);
390:
391: vertexCount += stripArray[0].vertices.count;
392: stripCount += stripArray[0].stripCounts.count;
393: }
394:
395: if (stripArray[1] != null) {
396: ga[1] = new TriangleArray(stripArray[1].vertices.count,
397: vertexFormat);
398:
399: copyVertexData(ga[1], stripArray[1].vertices);
400: triangleCount += stripArray[1].vertices.count / 3;
401: }
402: return ga;
403: }
404: }
|