001: /*
002: * $RCSfile: CompressedGeometryRetained.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:21 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.utils.geometry.compression;
046:
047: import javax.media.j3d.BoundingBox;
048: import javax.media.j3d.Bounds;
049: import javax.media.j3d.Canvas3D;
050: import javax.media.j3d.GeometryArray;
051: import javax.media.j3d.PickInfo;
052: import javax.media.j3d.PickShape;
053: import javax.media.j3d.Transform3D;
054: import javax.vecmath.Point3d;
055:
056: /**
057: * The compressed geometry object is used to store geometry in a
058: * compressed format. Using compressed geometry reduces the amount
059: * of memory needed by a Java 3D application and increases the speed
060: * objects can be sent over the network. Once geometry decompression
061: * hardware support becomes available, increased rendering performance
062: * will also result from the use of compressed geometry.
063: */
064: class CompressedGeometryRetained extends Object {
065:
066: // If not in by-reference mode, a 48-byte header as defined by the
067: // GL_SUNX_geometry_compression OpenGL extension is always concatenated to
068: // the beginning of the compressed geometry data and copied along with the
069: // it into a contiguous array. This allows hardware decompression using
070: // the obsolete experimental GL_SUNX_geometry_compression extension if
071: // that is all that is available.
072: //
073: // This is completely distinct and not to be confused with the cgHeader
074: // field on the non-retained side, although much of the data is
075: // essentially the same.
076: private static final int HEADER_LENGTH = 48;
077:
078: // These are the header locations examined.
079: private static final int HEADER_MAJOR_VERSION_OFFSET = 0;
080: private static final int HEADER_MINOR_VERSION_OFFSET = 1;
081: private static final int HEADER_MINOR_MINOR_VERSION_OFFSET = 2;
082: private static final int HEADER_BUFFER_TYPE_OFFSET = 3;
083: private static final int HEADER_BUFFER_DATA_OFFSET = 4;
084:
085: // The OpenGL compressed geometry extensions use bits instead of
086: // enumerations to represent the type of compressed geometry.
087: static final byte TYPE_POINT = 1;
088: static final byte TYPE_LINE = 2;
089: static final byte TYPE_TRIANGLE = 4;
090:
091: // Version number of this compressed geometry object.
092: int majorVersionNumber;
093: int minorVersionNumber;
094: int minorMinorVersionNumber;
095:
096: // These fields are used by the native execute() method.
097: int packedVersion;
098: int bufferType;
099: int bufferContents;
100: int renderFlags;
101: int offset;
102: int size;
103: byte[] compressedGeometry;
104:
105: // A reference to the original byte array with which this object was
106: // created. If hardware decompression is available but it doesn't support
107: // by-reference semantics, then an internal copy of the original byte array
108: // is made even when by-reference semantics have been requested.
109: private byte[] originalCompressedGeometry = null;
110:
111: // Geometric bounds
112: private BoundingBox geoBounds = new BoundingBox();
113:
114: // True if by-reference data access mode is in effect.
115: private boolean byReference = false;
116:
117: /**
118: * The package-scoped constructor.
119: */
120: CompressedGeometryRetained() {
121: // Compressed geometry is always bounded by [-1..1] on each axis, so
122: // set that as the initial bounding box.
123: geoBounds.setUpper(1.0, 1.0, 1.0);
124: geoBounds.setLower(-1.0, -1.0, -1.0);
125: }
126:
127: /**
128: * Return true if the data access mode is by-reference.
129: */
130: boolean isByReference() {
131: return this .byReference;
132: }
133:
134: private void createByCopy(byte[] geometry) {
135: // Always copy a header along with the compressed geometry into a
136: // contiguous array in order to support hardware acceleration with the
137: // GL_SUNX_geometry_compression extension. The header is unnecessary
138: // if only the newer GL_SUN_geometry_compression API needs support.
139: compressedGeometry = new byte[HEADER_LENGTH + this .size];
140:
141: compressedGeometry[HEADER_MAJOR_VERSION_OFFSET] = (byte) this .majorVersionNumber;
142:
143: compressedGeometry[HEADER_MINOR_VERSION_OFFSET] = (byte) this .minorVersionNumber;
144:
145: compressedGeometry[HEADER_MINOR_MINOR_VERSION_OFFSET] = (byte) this .minorMinorVersionNumber;
146:
147: compressedGeometry[HEADER_BUFFER_TYPE_OFFSET] = (byte) this .bufferType;
148:
149: compressedGeometry[HEADER_BUFFER_DATA_OFFSET] = (byte) this .bufferContents;
150:
151: System.arraycopy(geometry, this .offset, compressedGeometry,
152: HEADER_LENGTH, this .size);
153:
154: this .offset = HEADER_LENGTH;
155: }
156:
157: /**
158: * Creates the retained compressed geometry data. Data from the header is
159: * always copied; the compressed geometry is copied as well if the data
160: * access mode is not by-reference.
161: *
162: * @param hdr the compressed geometry header
163: * @param geometry the compressed geometry
164: * @param byReference if true then by-reference semantics requested
165: */
166: void createCompressedGeometry(CompressedGeometryData.Header hdr,
167: byte[] geometry, boolean byReference) {
168:
169: this .byReference = byReference;
170:
171: if (hdr.lowerBound != null)
172: this .geoBounds.setLower(hdr.lowerBound);
173:
174: if (hdr.upperBound != null)
175: this .geoBounds.setUpper(hdr.upperBound);
176:
177: //// this.centroid.set(geoBounds.getCenter());
178: //// recompCentroid = false;
179: this .majorVersionNumber = hdr.majorVersionNumber;
180: this .minorVersionNumber = hdr.minorVersionNumber;
181: this .minorMinorVersionNumber = hdr.minorMinorVersionNumber;
182:
183: this .packedVersion = (hdr.majorVersionNumber << 24)
184: | (hdr.minorVersionNumber << 16)
185: | (hdr.minorMinorVersionNumber << 8);
186:
187: switch (hdr.bufferType) {
188: case CompressedGeometryData.Header.POINT_BUFFER:
189: this .bufferType = TYPE_POINT;
190: break;
191: case CompressedGeometryData.Header.LINE_BUFFER:
192: this .bufferType = TYPE_LINE;
193: break;
194: case CompressedGeometryData.Header.TRIANGLE_BUFFER:
195: this .bufferType = TYPE_TRIANGLE;
196: break;
197: }
198:
199: this .bufferContents = hdr.bufferDataPresent;
200: this .renderFlags = 0;
201:
202: this .size = hdr.size;
203: this .offset = hdr.start;
204:
205: if (byReference) {
206: // Assume we can use the given reference, but maintain a second
207: // reference in case a copy is later needed.
208: this .compressedGeometry = geometry;
209: this .originalCompressedGeometry = geometry;
210: } else {
211: // Copy the original data into a format that can be used by both
212: // the software and native hardware decompressors.
213: createByCopy(geometry);
214: this .originalCompressedGeometry = null;
215: }
216: }
217:
218: /**
219: * Return a vertex format mask that's compatible with GeometryArray
220: * objects.
221: */
222: int getVertexFormat() {
223: int vertexFormat = GeometryArray.COORDINATES;
224:
225: if ((bufferContents & CompressedGeometryData.Header.NORMAL_IN_BUFFER) != 0) {
226: vertexFormat |= GeometryArray.NORMALS;
227: }
228:
229: if ((bufferContents & CompressedGeometryData.Header.COLOR_IN_BUFFER) != 0) {
230: if ((bufferContents & CompressedGeometryData.Header.ALPHA_IN_BUFFER) != 0) {
231: vertexFormat |= GeometryArray.COLOR_4;
232: } else {
233: vertexFormat |= GeometryArray.COLOR_3;
234: }
235: }
236:
237: return vertexFormat;
238: }
239:
240: /**
241: * Return a buffer type that's compatible with CompressedGeometryData.Header.
242: */
243: int getBufferType() {
244: switch (this .bufferType) {
245: case TYPE_POINT:
246: return CompressedGeometryData.Header.POINT_BUFFER;
247: case TYPE_LINE:
248: return CompressedGeometryData.Header.LINE_BUFFER;
249: default:
250: case TYPE_TRIANGLE:
251: return CompressedGeometryData.Header.TRIANGLE_BUFFER;
252: }
253: }
254:
255: /**
256: * Copies compressed geometry data into the given array of bytes.
257: * The internal header information is not copied.
258: *
259: * @param buff array of bytes into which to copy compressed geometry
260: */
261: void copy(byte[] buff) {
262: System.arraycopy(compressedGeometry, offset, buff, 0, size);
263: }
264:
265: /**
266: * Returns a reference to the original compressed geometry byte array,
267: * which may have been copied even if by-reference semantics have been
268: * requested. It will be null if byCopy is in effect.
269: *
270: * @return reference to array of bytes containing the compressed geometry.
271: */
272: byte[] getReference() {
273: return originalCompressedGeometry;
274: }
275:
276: }
|