Package javax.media.j3d

Source Code of javax.media.j3d.GeometryDecompressorRetained

/*
* 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.Color4f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

/**
* This class implements a retained geometry backend for the abstract
* GeometryDecompressor.
*/
class GeometryDecompressorRetained extends GeometryDecompressor {
    private static final boolean debug = false ;
    private static final boolean benchmark = false ;
    private static final boolean statistics = false ;
    private static final boolean printInfo = debug || benchmark || statistics ;

    // Type of connections in the compressed data:
    // TYPE_POINT (1), TYPE_LINE (2), or TYPE_TRIANGLE (4).
    private int bufferDataType ;

    // Data bundled with each vertex: bitwise combination of
    // NORMAL_IN_BUFFER (1), COLOR_IN_BUFFER (2), ALPHA_IN_BUFFER (4).
    private int dataPresent ;

    // Size of the compressed geometry in bytes.
    private int size ;

    // Decompressor output state variables.
    private Color4f curColor ;
    private Vector3f curNormal ;

    // List for accumulating the output of the decompressor and converting to
    // GeometryArray representations.
    private GeneralizedVertexList vlist ;

    // Geometric bounds.
    private Point3d lbounds = new Point3d() ;
    private Point3d ubounds = new Point3d() ;

    // Decompression output constraints.  The decompressor will still process
    // all data contained in the compressed buffer, but will only retain data
    // for output subject to these booleans.
    private boolean boundsOnly = false ;
    private boolean positionsOnly = false ;

    // A very rough gauge used to initialize the size of vlist, based on
    // normal-per-vertex data collected from the HelloUniverse.cg file
    // (seagull, '57 Chevy, dinosaur).
    //
    // XXXX: get fudge values for other vertex combinations
    private static final float bytesPerVertexFudge = 5.3f ;

    // Used for benchmarking if so configured.
    private long startTime ;
    private long endTime ;

    // Private convenience copies of various constants.
    private static final int TYPE_POINT =
  CompressedGeometryRetained.TYPE_POINT ;
    private static final int TYPE_LINE =
  CompressedGeometryRetained.TYPE_LINE ;
    private static final int TYPE_TRIANGLE =
  CompressedGeometryRetained.TYPE_TRIANGLE ;
    private static final int FRONTFACE_CCW =
  GeneralizedStripFlags.FRONTFACE_CCW ;

    /**
     * If the given argument is true, sets the decompressor to output only the
     * bounding box of the decompressed geometry.
     * @param boundsOnly set to true if the decompressor should output only the
     * geometric bounding box.
     */
    void setDecompressBoundsOnly(boolean boundsOnly) {
  this.boundsOnly = boundsOnly ;
  if (boundsOnly) this.positionsOnly = false ;
    }

    /**
     * If the given argument is true, sets the decompressor to output only the
     * decompressed positions, their connections, and the bounding box.
     * @param positionsOnly set to true if the decompressor should output only
     * position, connection, and bounding box data.
     */
    void setDecompressPositionsOnly(boolean positionsOnly) {
  this.positionsOnly = positionsOnly ;
  if (positionsOnly) this.boundsOnly = false ;
    }

    /**
     * Decompress the geometry data in a CompressedGeometryRetained.  The
     * GeometryArray output is intended to be cached as retained data for
     * efficient rendering.  Global color and normal changes output by the
     * decompressor are stored as redundant per-vertex data so that a single
     * GeometryArray can be used.
     *
     * Since only one GeometryArray is created, if the bundling attributes
     * change while building the vertex list then the decompression is
     * aborted.  There should be only one SetState bundling attribute command
     * per CompressedGeometry.
     *
     * @param cgr CompressedGeometryRetained containing compressed geometry
     * @return GeometryArrayRetained containing the results of the
     * decompression, or null if only the bounds are computed.
     */
    GeometryRetained decompress(CompressedGeometryRetained cgr) {

  if (! checkVersion(cgr.majorVersionNumber, cgr.minorVersionNumber)) {
      return null ;
  }

  vlist = null ;
  curColor = null ;
  curNormal = null ;
  lbounds.set( 1.0, 1.0, 1.0) ;
  ubounds.set(-1.0,-1.0,-1.0) ;

  // Get the descriptors for the compressed data.
  bufferDataType = cgr.bufferType ;
  dataPresent = cgr.bufferContents ;
  if (printInfo) beginPrint() ;

  // Call the superclass decompress() method which calls the output
  // methods of this subclass.  The results are stored in vlist.
  size = cgr.size ;
  super.decompress(cgr.offset, size, cgr.compressedGeometry) ;

  if (boundsOnly) {
      if (printInfo) endPrint() ;
      return null ;
  }

  // Convert the output to a GeometryRetained.
  GeometryArray ga ;
  switch(bufferDataType) {
    case TYPE_TRIANGLE:
      ga = vlist.toTriangleStripArray() ;
      break ;
    case TYPE_LINE:
      ga = vlist.toLineStripArray() ;
      break ;
    case TYPE_POINT:
      ga = vlist.toPointArray() ;
      break ;
    default:
      throw new IllegalArgumentException
    (J3dI18N.getString("GeometryDecompressorRetained0")) ;
  }

  // Release the reference to the non-retained data.
  ga.retained.setSource(null) ;

  if (printInfo) endPrint() ;
  return (GeometryRetained)ga.retained ;
    }

    /**
     * Get the bounds of the decompressed geometry.
     * @param bb BoundingBox to receive bounds
     */
    void getBoundingBox(BoundingBox bb) {
  bb.setLower(lbounds) ;
  bb.setUpper(ubounds) ;
    }

    /**
     * Initialize the vertex output list based on the vertex format provided
     * by the SetState decompression command.
     */
    @Override
    void outputVertexFormat(boolean bundlingNorm, boolean bundlingColor,
          boolean doingAlpha) {

  if (boundsOnly) return ;

  if (vlist != null)
      throw new IllegalStateException
    (J3dI18N.getString("GeometryDecompressorRetained1")) ;

  int vertexFormat = GeometryArray.COORDINATES ;

  if (! positionsOnly) {
      if (bundlingNormvertexFormat |= GeometryArray.NORMALS ;
      if (bundlingColor) vertexFormat |= GeometryArray.COLOR ;
      if (doingAlpha)    vertexFormat |= GeometryArray.WITH_ALPHA ;
  }

  vlist = new GeneralizedVertexList(vertexFormat, FRONTFACE_CCW,
            (int)(size/bytesPerVertexFudge)) ;
    }

    /**
     * Process a decompressed vertex.
     */
    @Override
    void outputVertex(Point3f position, Vector3f normal,
          Color4f color, int vertexReplaceCode) {

  if (position.x < lbounds.x) lbounds.x = position.x ;
  if (position.y < lbounds.y) lbounds.y = position.y ;
  if (position.z < lbounds.z) lbounds.z = position.z ;

  if (position.x > ubounds.x) ubounds.x = position.x ;
  if (position.y > ubounds.y) ubounds.y = position.y ;
  if (position.z > ubounds.z) ubounds.z = position.z ;

  if (boundsOnly) return ;
  if (curColor != null) color = curColor ;
  if (curNormal != null) normal = curNormal ;

  vlist.addVertex(position, normal, color, vertexReplaceCode) ;

  if (debug) {
      System.err.println("outputVertex: flag " + vertexReplaceCode) ;
      System.err.println(" position " + position.toString()) ;
      if (normal != null)
    System.err.println(" normal " + normal.toString()) ;
      if (color != null)
    System.err.println(" color " + color.toString()) ;
  }
    }

    /**
     * Any global colors output by the decompressor are stored as per-vertex
     * color in the retained data used internally by the renderer.  This is
     * done for performance and simplicity reasons, at the expense of
     * replicating colors.
     *
     * The next method sets the current color that will be copied to each
     * succeeding vertex.  The outputColor() method is never called if
     * colors are bundled with each vertex in the compressed buffer.
     */
    @Override
    void outputColor(Color4f color) {
  if (boundsOnly || positionsOnly) return ;
  if (debug) System.err.println("outputColor: " + color.toString()) ;

  if ((vlist.vertexFormat & GeometryArray.COLOR) == 0) {
      if (vlist.size() > 0)
    throw new IllegalStateException
        (J3dI18N.getString("GeometryDecompressorRetained2")) ;

      vlist.setVertexFormat(vlist.vertexFormat | GeometryArray.COLOR) ;
  }

  if (curColor == null) curColor = new Color4f() ;
  curColor.set(color) ;
    }

    /**
     * Set the current normal that will be copied to each succeeding vertex
     * output by the decompressor.  The per-vertex copy is always needed since
     * in Java 3D a normal is always associated with a vertex.  This is never
     * called if normals are bundled with each vertex in the compressed
     * buffer.
     */
    @Override
    void outputNormal(Vector3f normal) {
  if (boundsOnly || positionsOnly) return ;
  if (debug) System.err.println("outputNormal: " + normal.toString()) ;

  if ((vlist.vertexFormat & GeometryArray.NORMALS) == 0) {
      if (vlist.size() > 0)
    throw new IllegalStateException
        (J3dI18N.getString("GeometryDecompressorRetained3")) ;

      vlist.setVertexFormat(vlist.vertexFormat | GeometryArray.NORMALS) ;
  }

  if (curNormal == null) curNormal = new Vector3f() ;
  curNormal.set(normal) ;
    }

    private void beginPrint() {
  System.err.println("\nGeometryDecompressorRetained") ;

  switch(bufferDataType) {
    case TYPE_TRIANGLE:
      System.err.println(" buffer TYPE_TRIANGLE") ;
       break ;
    case TYPE_LINE:
      System.err.println(" buffer TYPE_LINE") ;
      break ;
    case TYPE_POINT:
      System.err.println(" buffer TYPE_POINT") ;
      break ;
    default:
      throw new IllegalArgumentException
    (J3dI18N.getString("GeometryDecompressorRetained4")) ;
  }

  System.err.print(" buffer data present: coords") ;

  if ((dataPresent & CompressedGeometryHeader.NORMAL_IN_BUFFER) != 0)
      System.err.print(" normals") ;
  if ((dataPresent & CompressedGeometryHeader.COLOR_IN_BUFFER) != 0)
      System.err.print(" colors") ;
  if ((dataPresent & CompressedGeometryHeader.ALPHA_IN_BUFFER) != 0)
      System.err.print(" alpha") ;

  System.err.println() ;
  if (boundsOnly) System.err.println(" computing bounds only") ;
  if (positionsOnly) System.err.println(" computing positions only") ;

  startTime = J3dClock.currentTimeMillis() ;
    }

    private void endPrint() {
  endTime = J3dClock.currentTimeMillis() ;

  if (benchmark || statistics)
      printBench() ;

  if (statistics)
      printStats() ;
    }

    private void printBench() {
  float t = (endTime - startTime) / 1000.0f ;

  if (boundsOnly) {
      System.err.println(" decompression took " + t + " sec.\n") ;
      return ;
  }

  System.err.println
      (" decompression + strip conversion took " + t + " sec.") ;

  switch(bufferDataType) {
      case TYPE_POINT:
      System.err.println
    (" decompressed " + (vlist.size()) +
     " points at " + (vlist.size()/t) +
     " points/sec.\n") ;
      break ;
    case TYPE_LINE:
      System.err.println
    (" decompressed " + (vlist.vertexCount - vlist.stripCount) +
     " lines at " + ((vlist.vertexCount - vlist.stripCount)/t) +
     " lines/sec.\n") ;
      break ;
    case TYPE_TRIANGLE:
        System.err.println
      (" decompressed " +
       (vlist.vertexCount - 2*vlist.stripCount) +
       " triangles at " +
       ((vlist.vertexCount - 2*vlist.stripCount)/t) +
       " triangles/sec.\n") ;
      break ;
  }
    }

    private void printStats() {
  System.err.println(" bounding box:\n  lower " + lbounds.toString() +
         "\n  upper " + ubounds.toString()) ;

  if (boundsOnly) return ;

  System.err.print
      (" number of vertices in GeometryArray output: " +
       vlist.vertexCount + "\n" +
       " GeometryArray vertex data present: coords") ;

  if ((vlist.vertexFormat & GeometryArray.NORMALS) != 0)
      System.err.print(" normals") ;

  if ((vlist.vertexFormat & GeometryArray.COLOR) != 0)
      System.err.print(" colors") ;

  if ((vlist.vertexFormat & GeometryArray.WITH_ALPHA) != 0)
      System.err.print(" alpha") ;

  System.err.println("\n number of strips: " + vlist.stripCount) ;
  if (vlist.stripCount > 0)
      System.err.println
    (" vertices/strip: " +
     ((float)vlist.vertexCount / (float)vlist.stripCount)) ;
    }
}
TOP

Related Classes of javax.media.j3d.GeometryDecompressorRetained

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.