compressedgeometryretained.java

来自「JAVA3D矩陈的相关类」· Java 代码 · 共 448 行

JAVA
448
字号
/* * $RCSfile: CompressedGeometryRetained.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.7 $ * $Date: 2007/02/09 17:17:56 $ * $State: Exp $ */package javax.media.j3d ;import javax.vecmath.* ;/** * 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.     */    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.     */    void computeBoundingBox() {    }      /**     * Update this object.  Compressed geometry is immutable so there's     * nothing to do.     */    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) ;	this.centroid.set(geoBounds.getCenter());	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 (GeometryRetained)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 (GeometryRetained)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.    //    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);    }        boolean intersect(Bounds targetBound) {	GeometryRetained geom = getPickGeometry() ;	return (geom != null ? geom.intersect(targetBound) : false);    }    boolean intersect(Transform3D thisToOtherVworld,  GeometryRetained g) {	GeometryRetained geom = getPickGeometry() ;	return (geom != null ? 		geom.intersect(thisToOtherVworld, g) : false);    }    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.     */    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 ;	}    }    int getClassType() {	return COMPRESS_TYPE;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?