Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package javax.media.j3d ;
import javax.vecmath.Point3d;
/**
* The compressed geometry object is used to store geometry in a
* compressed format. Using compressed geometry reduces the amount
* of memory needed by a Java 3D application and increases the speed
* objects can be sent over the network. Once geometry decompression
* hardware support becomes available, increased rendering performance
* will also result from the use of compressed geometry.
*/
class CompressedGeometryRetained extends GeometryRetained {
// If not in by-reference mode, a 48-byte header as defined by the
// GL_SUNX_geometry_compression OpenGL extension is always concatenated to
// the beginning of the compressed geometry data and copied along with the
// it into a contiguous array. This allows hardware decompression using
// the obsolete experimental GL_SUNX_geometry_compression extension if
// that is all that is available.
//
// This is completely distinct and not to be confused with the cgHeader
// field on the non-retained side, although much of the data is
// essentially the same.
private static final int HEADER_LENGTH = 48 ;
// These are the header locations examined.
private static final int HEADER_MAJOR_VERSION_OFFSET = 0 ;
private static final int HEADER_MINOR_VERSION_OFFSET = 1 ;
private static final int HEADER_MINOR_MINOR_VERSION_OFFSET = 2 ;
private static final int HEADER_BUFFER_TYPE_OFFSET = 3 ;
private static final int HEADER_BUFFER_DATA_OFFSET = 4 ;
// The OpenGL compressed geometry extensions use bits instead of
// enumerations to represent the type of compressed geometry.
static final byte TYPE_POINT = 1 ;
static final byte TYPE_LINE = 2 ;
static final byte TYPE_TRIANGLE = 4 ;
// Version number of this compressed geometry object.
int majorVersionNumber ;
int minorVersionNumber ;
int minorMinorVersionNumber ;
// These fields are used by the native execute() method.
int packedVersion ;
int bufferType ;
int bufferContents ;
int renderFlags ;
int offset ;
int size ;
byte[] compressedGeometry ;
// True if by-reference data access mode is in effect.
private boolean byReference = false ;
// A reference to the original byte array with which this object was
// created. If hardware decompression is available but it doesn't support
// by-reference semantics, then an internal copy of the original byte array
// is made even when by-reference semantics have been requested.
private byte[] originalCompressedGeometry = null ;
// True if the platform supports hardware decompression.
private static boolean hardwareDecompression = false ;
// This field retains a reference to the GeometryRetained object used for
// geometry-based picking. It is normally the same reference as the
// mirror geometry used for rendering unless hardware decompression is
// supported.
private GeometryRetained pickGeometry = null ;
/**
* Formerly native method that returns availability of a native by-reference
* rendering API for compressed geometry.
*/
private boolean decompressByRef(Context ctx) {
return false;
}
/**
* Formerly native method that returns availability of hardware
* rendering (and acceleration) for compressed geometry of the
* given version.
*/
private boolean decompressHW(Context ctx, int majorVersion, int minorVersion) {
return false;
}
/**
* Formerly native method that does HW compressed geometry rendering
*/
private void execute(Context ctx, int version, int bufferType,
int bufferContents, int renderFlags,
int offset, int size, byte[] geometry) {
assert false : "This method should never be called!";
}
/**
* Method for calling native execute() method on behalf of the J3D renderer.
*/
@Override
void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale,
boolean updateAlpha, float alpha,
int screen, boolean ignoreVertexColors) {
// XXXX: alpha udpate
execute(cv.ctx, packedVersion, bufferType, bufferContents,
renderFlags, offset, size, compressedGeometry) ;
}
/**
* The package-scoped constructor.
*/
CompressedGeometryRetained() {
this.geoType = GEO_TYPE_COMPRESSED ;
// Compressed geometry is always bounded by [-1..1] on each axis, so
// set that as the initial bounding box.
geoBounds.setUpper( 1.0, 1.0, 1.0) ;
geoBounds.setLower(-1.0,-1.0,-1.0) ;
}
/**
* Compressed geometry is immutable so this method does nothing.
*/
@Override
void computeBoundingBox() {
}
/**
* Update this object. Compressed geometry is immutable so there's
* nothing to do.
*/
@Override
void update() {
isDirty = 0 ;
}
/**
* Return true if the data access mode is by-reference.
*/
boolean isByReference() {
return this.byReference ;
}
private void createByCopy(byte[] geometry) {
// Always copy a header along with the compressed geometry into a
// contiguous array in order to support hardware acceleration with the
// GL_SUNX_geometry_compression extension. The header is unnecessary
// if only the newer GL_SUN_geometry_compression API needs support.
compressedGeometry = new byte[HEADER_LENGTH + this.size] ;
compressedGeometry[HEADER_MAJOR_VERSION_OFFSET] =
(byte)this.majorVersionNumber ;
compressedGeometry[HEADER_MINOR_VERSION_OFFSET] =
(byte)this.minorVersionNumber ;
compressedGeometry[HEADER_MINOR_MINOR_VERSION_OFFSET] =
(byte)this.minorMinorVersionNumber ;
compressedGeometry[HEADER_BUFFER_TYPE_OFFSET] =
(byte)this.bufferType ;
compressedGeometry[HEADER_BUFFER_DATA_OFFSET] =
(byte)this.bufferContents ;
System.arraycopy(geometry, this.offset,
compressedGeometry, HEADER_LENGTH, this.size) ;
this.offset = HEADER_LENGTH ;
}
/**
* Creates the retained compressed geometry data. Data from the header is
* always copied; the compressed geometry is copied as well if the data
* access mode is not by-reference.
*
* @param hdr the compressed geometry header
* @param geometry the compressed geometry
* @param byReference if true then by-reference semantics requested
*/
void createCompressedGeometry(CompressedGeometryHeader hdr,
byte[] geometry, boolean byReference) {
this.byReference = byReference ;
if (hdr.lowerBound != null)
this.geoBounds.setLower(hdr.lowerBound) ;
if (hdr.upperBound != null)
this.geoBounds.setUpper(hdr.upperBound) ;
geoBounds.getCenter(this.centroid);
recompCentroid = false;
this.majorVersionNumber = hdr.majorVersionNumber ;
this.minorVersionNumber = hdr.minorVersionNumber ;
this.minorMinorVersionNumber = hdr.minorMinorVersionNumber ;
this.packedVersion =
(hdr.majorVersionNumber << 24) |
(hdr.minorVersionNumber << 16) |
(hdr.minorMinorVersionNumber << 8) ;
switch(hdr.bufferType) {
case CompressedGeometryHeader.POINT_BUFFER:
this.bufferType = TYPE_POINT ;
break ;
case CompressedGeometryHeader.LINE_BUFFER:
this.bufferType = TYPE_LINE ;
break ;
case CompressedGeometryHeader.TRIANGLE_BUFFER:
this.bufferType = TYPE_TRIANGLE ;
break ;
}
this.bufferContents = hdr.bufferDataPresent ;
this.renderFlags = 0 ;
this.size = hdr.size ;
this.offset = hdr.start ;
if (byReference) {
// Assume we can use the given reference, but maintain a second
// reference in case a copy is later needed.
this.compressedGeometry = geometry ;
this.originalCompressedGeometry = geometry ;
} else {
// Copy the original data into a format that can be used by both
// the software and native hardware decompressors.
createByCopy(geometry) ;
this.originalCompressedGeometry = null ;
}
}
/**
* Decompress this object into a GeometryArrayRetained if hardware
* decompression is not available. Once decompressed the resulting
* geometry replaces the geometry reference in the associated RenderAtom
* as well as the mirror geometry reference in this object.
*/
GeometryRetained getGeometry(boolean forceDecompression, Canvas3D cv ) {
if (forceDecompression) {
// forceDecompression is set to true if lighting is disabled and
// ignoreVertexColors is true, since there is no way for openGL to
// ignore vertexColors in this case.
GeometryDecompressorRetained gdr =
new GeometryDecompressorRetained() ;
mirrorGeometry = gdr.decompress(this) ;
gdr.getBoundingBox(geoBounds) ;
pickGeometry = mirrorGeometry ;
}
else {
// Return this object if hardware decompression is available.
if (hardwareDecompression)
return this;
// Check to see if hardware decompression is available.
if (decompressHW(cv.ctx, majorVersionNumber, minorVersionNumber)) {
hardwareDecompression = true ;
// If hardware can't handle by-reference, punt to by-copy.
if (isByReference() && !decompressByRef(cv.ctx)) {
createByCopy(compressedGeometry) ;
}
return this;
}
// Decompress the data into a GeometryArrayRetained representation
// for the mirror geometry reference.
GeometryDecompressorRetained gdr =
new GeometryDecompressorRetained() ;
mirrorGeometry = gdr.decompress(this) ;
gdr.getBoundingBox(geoBounds) ;
// The mirror geometry contains a superset of the pick geometry
// data. Since hardware decompression isn't available, there's no
// need to retain separate pick geometry.
pickGeometry = mirrorGeometry ;
}
return mirrorGeometry ;
}
/**
* This method always decompresses the geometry and retains the result in
* order to support geometry-based picking and collision detection. The
* returned GeometryRetained object will contain only positions and
* connections.
*/
GeometryRetained getPickGeometry() {
// Return the pick geometry if available.
if (pickGeometry != null)
return pickGeometry ;
// Decompress the data into a GeometryArrayRetained representation for
// the pick geometry reference. Retain it and its bounding box.
GeometryDecompressorRetained gdr = new GeometryDecompressorRetained() ;
gdr.setDecompressPositionsOnly(true) ;
pickGeometry = gdr.decompress(this) ;
gdr.getBoundingBox(geoBounds) ;
return pickGeometry ;
}
//
// The following intersect() methods are used to implement geometry-based
// picking and collision.
//
@Override
boolean intersect(PickShape pickShape, PickInfo pickInfo, int flags, Point3d iPnt,
GeometryRetained geom, int geomIndex) {
GeometryRetained geomR = getPickGeometry() ;
return (geomR != null ?
geomR.intersect(pickShape, pickInfo, flags, iPnt, geom, geomIndex) : false);
}
@Override
boolean intersect(Bounds targetBound) {
GeometryRetained geom = getPickGeometry() ;
return (geom != null ? geom.intersect(targetBound) : false);
}
@Override
boolean intersect(Transform3D thisToOtherVworld, GeometryRetained g) {
GeometryRetained geom = getPickGeometry() ;
return (geom != null ?
geom.intersect(thisToOtherVworld, g) : false);
}
@Override
boolean intersect(Point3d[] pnts) {
GeometryRetained geom = getPickGeometry() ;
return (geom != null ? geom.intersect(pnts) : false);
}
/**
* Return a vertex format mask that's compatible with GeometryArray
* objects.
*/
@Override
int getVertexFormat() {
int vertexFormat = GeometryArray.COORDINATES ;
if ((this.bufferContents &
CompressedGeometryHeader.NORMAL_IN_BUFFER) != 0)
vertexFormat |= GeometryArray.NORMALS ;
if ((this.bufferContents &
CompressedGeometryHeader.COLOR_IN_BUFFER) != 0)
vertexFormat |= GeometryArray.COLOR ;
if ((this.bufferContents &
CompressedGeometryHeader.ALPHA_IN_BUFFER) != 0)
vertexFormat |= GeometryArray.WITH_ALPHA ;
return vertexFormat ;
}
/**
* Return a buffer type that's compatible with CompressedGeometryHeader.
*/
int getBufferType() {
switch(this.bufferType) {
case TYPE_POINT:
return CompressedGeometryHeader.POINT_BUFFER ;
case TYPE_LINE:
return CompressedGeometryHeader.LINE_BUFFER ;
default:
case TYPE_TRIANGLE:
return CompressedGeometryHeader.TRIANGLE_BUFFER ;
}
}
/**
* Copies compressed geometry data into the given array of bytes.
* The internal header information is not copied.
*
* @param buff array of bytes into which to copy compressed geometry
*/
void copy(byte[] buff) {
System.arraycopy(compressedGeometry, offset, buff, 0, size) ;
}
/**
* Returns a reference to the original compressed geometry byte array,
* which may have been copied even if by-reference semantics have been
* requested. It will be null if byCopy is in effect.
*
* @return reference to array of bytes containing the compressed geometry.
*/
byte[] getReference() {
return originalCompressedGeometry ;
}
/**
* Copies all retained data for cloneNodeComponent() on the non-retained
* side. This is unlike GeometryArray subclasses which just call the
* public API constructors and then duplicateNodeComponent() to invoke the
* GeometryArray implementation of duplicateAttributes(), since the
* CompressedGeometry class directly subclasses Geometry and calling the
* public constructors would cause a lot of redundant data copying.
*/
void duplicate(CompressedGeometryRetained cgr) {
cgr.majorVersionNumber = this.majorVersionNumber ;
cgr.minorVersionNumber = this.minorVersionNumber ;
cgr.minorMinorVersionNumber = this.minorMinorVersionNumber ;
cgr.packedVersion = this.packedVersion ;
cgr.bufferType = this.bufferType ;
cgr.bufferContents = this.bufferContents ;
cgr.renderFlags = this.renderFlags ;
cgr.offset = this.offset ;
cgr.size= this.size ;
cgr.geoBounds.setLower(this.geoBounds.lower) ;
cgr.geoBounds.setUpper(this.geoBounds.upper) ;
cgr.pickGeometry = this.pickGeometry ;
cgr.byReference = this.byReference ;
if (this.byReference) {
// Copy references only.
cgr.compressedGeometry = this.compressedGeometry ;
cgr.originalCompressedGeometry = this.originalCompressedGeometry ;
} else {
// Copy entire byte array including 48-byte native OpenGL header.
cgr.compressedGeometry = new byte[this.compressedGeometry.length] ;
System.arraycopy(this.compressedGeometry, 0,
cgr.compressedGeometry, 0,
this.compressedGeometry.length) ;
cgr.originalCompressedGeometry = null ;
}
}
@Override
int getClassType() {
return COMPRESS_TYPE;
}
}