001: /*
002: * $RCSfile: CompressedGeometry.java,v $
003: *
004: * Copyright 1996-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.6 $
028: * $Date: 2008/02/28 20:17:20 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: /**
035: * The compressed geometry object is used to store geometry in a
036: * compressed format. Using compressed geometry may increase the speed
037: * objects can be sent over the network. Note that the geometry will
038: * be decompressed in memory, so the application will not see any
039: * memory savings.
040: * <p>
041: * Compressed geometry may be passed to this CompressedGeometry object
042: * in one of two ways: by copying the data into this object using the
043: * existing constructor, or by passing a reference to the data.
044: * <p>
045: * <ul>
046: * <li>
047: * <b>By Copying:</b>
048: * The existing CompressedGeometry constructor copies the buffer of
049: * compressed geometry data into this CompressedGeometry object. This
050: * is appropriate for many applications, and allows Java 3D to verify
051: * the data once and then not worry about it again.
052: * </li>
053: * <li><b>By Reference:</b>
054: * A new constructor and set of methods in Java 3D version 1.2 allows
055: * compressed geometry data to be accessed by reference, directly from
056: * the user's array. To use this feature, you need to construct a
057: * CompressedGeometry object with the <code>byReference</code> flag
058: * set to <code>true</code>. In this mode, a reference to the input
059: * data is saved, but the data itself is not necessarily copied. Note
060: * that the compressed geometry header is still copied into this
061: * compressed geometry object. Data referenced by a
062: * CompressedGeometry object must not be modified after the
063: * CompressedGeometry object is constructed.
064: * Applications
065: * must exercise care not to violate this rule. If any referenced
066: * compressed geometry data is modified after construction,
067: * the results are undefined.
068: * </li>
069: * </ul>
070: *
071: * @deprecated As of Java 3D version 1.4.
072: */
073: public class CompressedGeometry extends Geometry {
074:
075: CompressedGeometryHeader cgHeader;
076:
077: /**
078: * Specifies that this CompressedGeometry object allows reading its
079: * byte count information.
080: */
081: public static final int ALLOW_COUNT_READ = CapabilityBits.COMPRESSED_GEOMETRY_ALLOW_COUNT_READ;
082:
083: /**
084: * Specifies that this CompressedGeometry object allows reading its
085: * header information.
086: */
087: public static final int ALLOW_HEADER_READ = CapabilityBits.COMPRESSED_GEOMETRY_ALLOW_HEADER_READ;
088:
089: /**
090: * Specifies that this CompressedGeometry object allows reading its
091: * geometry data component information.
092: */
093: public static final int ALLOW_GEOMETRY_READ = CapabilityBits.COMPRESSED_GEOMETRY_ALLOW_GEOMETRY_READ;
094:
095: /**
096: * Specifies that this CompressedGeometry allows reading the geometry
097: * data reference information for this object. This is only used in
098: * by-reference geometry mode.
099: *
100: * @since Java 3D 1.2
101: */
102: public static final int ALLOW_REF_DATA_READ = CapabilityBits.COMPRESSED_GEOMETRY_ALLOW_REF_DATA_READ;
103:
104: // Array for setting default read capabilities
105: private static final int[] readCapabilities = { ALLOW_COUNT_READ,
106: ALLOW_HEADER_READ, ALLOW_GEOMETRY_READ, ALLOW_REF_DATA_READ };
107:
108: /**
109: * Package scoped default constructor for use by cloneNodeComponent.
110: */
111: CompressedGeometry() {
112: // set default read capabilities
113: setDefaultReadCapabilities(readCapabilities);
114: }
115:
116: /**
117: * Creates a new CompressedGeometry NodeComponent by copying
118: * the specified compressed geometry data into this object.
119: * If the version number of compressed geometry, as specified by
120: * the CompressedGeometryHeader, is incompatible with the
121: * supported version of compressed geometry in the current version
122: * of Java 3D, then the compressed geometry object will not be
123: * rendered.
124: *
125: * @param hdr the compressed geometry header. This is copied
126: * into the CompressedGeometry NodeComponent.
127: *
128: * @param compressedGeometry the compressed geometry data. The
129: * geometry must conform to the format described in Appendix B of
130: * the <i>Java 3D API Specification</i>.
131: *
132: * @exception IllegalArgumentException if a problem is detected with the
133: * header
134: *
135: * @see CompressedGeometryHeader
136: * @see Canvas3D#queryProperties
137: */
138: public CompressedGeometry(CompressedGeometryHeader hdr,
139: byte[] compressedGeometry) {
140: this (hdr, compressedGeometry, false);
141: }
142:
143: /**
144: * Creates a new CompressedGeometry NodeComponent. The
145: * specified compressed geometry data is either copied into this
146: * object or is accessed by reference.
147: * If the version number of compressed geometry, as specified by
148: * the CompressedGeometryHeader, is incompatible with the
149: * supported version of compressed geometry in the current version
150: * of Java 3D, the compressed geometry object will not be
151: * rendered.
152: *
153: * @param hdr the compressed geometry header. This is copied
154: * into the CompressedGeometry NodeComponent.
155: *
156: * @param compressedGeometry the compressed geometry data. The
157: * geometry must conform to the format described in Appendix B of
158: * the <i>Java 3D API Specification</i>.
159: *
160: * @param byReference a flag that indicates whether the data is copied
161: * into this compressed geometry object or is accessed by reference.
162: *
163: * @exception IllegalArgumentException if a problem is detected with the
164: * header
165: *
166: * @see CompressedGeometryHeader
167: * @see Canvas3D#queryProperties
168: *
169: * @since Java 3D 1.2
170: */
171: public CompressedGeometry(CompressedGeometryHeader hdr,
172: byte[] compressedGeometry, boolean byReference) {
173:
174: if ((hdr.size + hdr.start) > compressedGeometry.length)
175: throw new IllegalArgumentException(J3dI18N
176: .getString("CompressedGeometry0"));
177:
178: // set default read capabilities
179: setDefaultReadCapabilities(readCapabilities);
180:
181: // Create a separate copy of the given header.
182: cgHeader = new CompressedGeometryHeader();
183: hdr.copy(cgHeader);
184:
185: // Create the retained object.
186: ((CompressedGeometryRetained) this .retained)
187: .createCompressedGeometry(cgHeader, compressedGeometry,
188: byReference);
189:
190: // This constructor is designed to accept byte arrays that may contain
191: // possibly many large compressed geometry blocks interspersed with
192: // non-J3D-specific metadata. Only one of these blocks is used per
193: // CompressedGeometry object, so set the geometry offset to zero in
194: // the header if the data itself is copied.
195: if (!byReference)
196: cgHeader.start = 0;
197: }
198:
199: /**
200: * This constructor is not implemented.
201: *
202: * @exception UnsupportedOperationException this constructor is not
203: * implemented
204: *
205: * @since Java 3D 1.3
206: */
207: public CompressedGeometry(CompressedGeometryHeader hdr,
208: J3DBuffer compressedGeometry) {
209: throw new UnsupportedOperationException(J3dI18N
210: .getString("CompressedGeometry9"));
211: }
212:
213: /**
214: * Returns the size, in bytes, of the compressed geometry buffer.
215: * The size of the compressed geometry header is not included.
216: *
217: * @return the size, in bytes, of the compressed geometry buffer.
218: *
219: * @exception CapabilityNotSetException if appropriate capability is
220: * not set and this object is part of live or compiled scene graph
221: */
222: public int getByteCount() {
223: if (isLiveOrCompiled())
224: if (!this .getCapability(ALLOW_COUNT_READ))
225: throw new CapabilityNotSetException(J3dI18N
226: .getString("CompressedGeometry1"));
227:
228: return cgHeader.size;
229: }
230:
231: /**
232: * Copies the compressed geometry header from the CompressedGeometry
233: * NodeComponent into the passed in parameter.
234: *
235: * @param hdr the CompressedGeometryHeader object into which to copy the
236: * CompressedGeometry NodeComponent's header; the offset field may differ
237: * from that which was originally specified if a copy of the original
238: * compressed geometry byte array was created.
239: *
240: * @exception CapabilityNotSetException if appropriate capability is
241: * not set and this object is part of live or compiled scene graph
242: *
243: * @see CompressedGeometryHeader
244: */
245: public void getCompressedGeometryHeader(CompressedGeometryHeader hdr) {
246: if (isLiveOrCompiled())
247: if (!this .getCapability(ALLOW_HEADER_READ))
248: throw new CapabilityNotSetException(J3dI18N
249: .getString("CompressedGeometry2"));
250:
251: cgHeader.copy(hdr);
252: }
253:
254: /**
255: * Retrieves the compressed geometry associated with the
256: * CompressedGeometry NodeComponent object. Copies the compressed
257: * geometry from the CompressedGeometry node into the given array.
258: * The array must be large enough to hold all of the bytes.
259: * The individual array elements must be allocated by the caller.
260: *
261: * @param compressedGeometry the array into which to copy the compressed
262: * geometry.
263: *
264: * @exception CapabilityNotSetException if appropriate capability is
265: * not set and this object is part of live or compiled scene graph
266: *
267: * @exception IllegalStateException if the data access mode for this
268: * object is by-reference.
269: *
270: * @exception ArrayIndexOutOfBoundsException if compressedGeometry byte
271: * array is not large enough to receive the compressed geometry
272: */
273: public void getCompressedGeometry(byte[] compressedGeometry) {
274: if (isLiveOrCompiled())
275: if (!this .getCapability(ALLOW_GEOMETRY_READ))
276: throw new CapabilityNotSetException(J3dI18N
277: .getString("CompressedGeometry3"));
278:
279: if (isByReference())
280: throw new IllegalStateException(J3dI18N
281: .getString("CompressedGeometry7"));
282:
283: if (cgHeader.size > compressedGeometry.length)
284: throw new ArrayIndexOutOfBoundsException(J3dI18N
285: .getString("CompressedGeometry4"));
286:
287: ((CompressedGeometryRetained) this .retained)
288: .copy(compressedGeometry);
289: }
290:
291: /**
292: * Decompresses the compressed geometry. Returns an array of Shape nodes
293: * containing the decompressed geometry objects, or null if the version
294: * number of the compressed geometry is incompatible with the decompressor
295: * in the current version of Java 3D.
296: *
297: * @return an array of Shape nodes containing the
298: * geometry decompressed from this CompressedGeometry NodeComponent
299: * object, or null if its version is incompatible
300: *
301: * @exception CapabilityNotSetException if appropriate capability is
302: * not set and this object is part of live or compiled scene graph
303: */
304: public Shape3D[] decompress() {
305: if (isLiveOrCompiled())
306: if (!this .getCapability(ALLOW_GEOMETRY_READ))
307: throw new CapabilityNotSetException(J3dI18N
308: .getString("CompressedGeometry5"));
309:
310: CompressedGeometryRetained cgr = (CompressedGeometryRetained) this .retained;
311:
312: GeometryDecompressorShape3D decompressor = new GeometryDecompressorShape3D();
313:
314: // Decompress the geometry as TriangleStripArrays. A combination of
315: // TriangleStripArrays and TrianglesFanArrays is more compact but
316: // requires twice as many Shape3D objects, resulting in slower
317: // rendering performance.
318: //
319: // Using TriangleArray output is currently the fastest, given the
320: // strip sizes observed from various compressed geometry objects, but
321: // produces about twice as many vertices. TriangleStripArray produces
322: // the same number of Shape3D objects as TriangleArray using 1/2
323: // to 2/3 of the vertices, with only a marginal performance penalty.
324: //
325: return decompressor.toTriangleStripArrays(cgr);
326: }
327:
328: /**
329: * Retrieves the data access mode for this CompressedGeometry object.
330: *
331: * @return <code>true</code> if the data access mode for this
332: * CompressedGeometry object is by-reference;
333: * <code>false</code> if the data access mode is by-copying.
334: *
335: * @since Java 3D 1.2
336: */
337: public boolean isByReference() {
338: return ((CompressedGeometryRetained) this .retained)
339: .isByReference();
340: }
341:
342: /**
343: * Gets the compressed geometry data reference.
344: *
345: * @return the current compressed geometry data reference.
346: *
347: * @exception IllegalStateException if the data access mode for this
348: * object is not by-reference.
349: *
350: * @exception CapabilityNotSetException if appropriate capability is
351: * not set and this object is part of live or compiled scene graph
352: *
353: * @since Java 3D 1.2
354: */
355: public byte[] getCompressedGeometryRef() {
356: if (isLiveOrCompiled())
357: if (!this .getCapability(ALLOW_REF_DATA_READ))
358: throw new CapabilityNotSetException(J3dI18N
359: .getString("CompressedGeometry6"));
360:
361: if (!isByReference())
362: throw new IllegalStateException(J3dI18N
363: .getString("CompressedGeometry8"));
364:
365: return ((CompressedGeometryRetained) this .retained)
366: .getReference();
367: }
368:
369: /**
370: * Gets the compressed geometry data buffer reference, which is
371: * always null since NIO buffers are not supported for
372: * CompressedGeometry objects.
373: *
374: * @return null
375: *
376: * @exception CapabilityNotSetException if appropriate capability is
377: * not set and this object is part of live or compiled scene graph
378: *
379: * @since Java 3D 1.3
380: */
381: public J3DBuffer getCompressedGeometryBuffer() {
382: if (isLiveOrCompiled())
383: if (!this .getCapability(ALLOW_REF_DATA_READ))
384: throw new CapabilityNotSetException(J3dI18N
385: .getString("CompressedGeometry6"));
386:
387: return null;
388: }
389:
390: /**
391: * Creates the retained mode CompressedGeometryRetained object that this
392: * CompressedGeometry object will point to.
393: */
394: void createRetained() {
395: this .retained = new CompressedGeometryRetained();
396: this .retained.setSource(this );
397: }
398:
399: /**
400: * @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
401: */
402: public NodeComponent cloneNodeComponent() {
403: CompressedGeometry cg = new CompressedGeometry();
404:
405: // Duplicate data specific to this class.
406: cg.cgHeader = new CompressedGeometryHeader();
407: cgHeader.copy(cg.cgHeader);
408:
409: // Duplicate the retained side.
410: CompressedGeometryRetained cgr = (CompressedGeometryRetained) retained;
411: cgr.duplicate((CompressedGeometryRetained) cg.retained);
412:
413: // Duplicate superclass data and return.
414: cg.duplicateNodeComponent(this);
415: return cg;
416: }
417: }
|