summaryrefslogtreecommitdiffstats
path: root/src/demos/dualDepthPeeling/Model.java
diff options
context:
space:
mode:
authorAlexandra Bokinsky <[email protected]>2011-03-15 11:45:09 -0400
committerAlexandra Bokinsky <[email protected]>2011-03-15 11:45:09 -0400
commit2db5af1e1a64d7048ce2f0db4b83d8b10c7f734d (patch)
treef0700a1dc4fc08315cf0a2c36c209c96c0260965 /src/demos/dualDepthPeeling/Model.java
parent05e3d96ff9586b2f6cd5c2841337f9be7d07c313 (diff)
Port of NVIDIA OpenGL Dual Depth Peeling demo.
http://developer.download.nvidia.com/SDK/10.5/opengl/samples.html
Diffstat (limited to 'src/demos/dualDepthPeeling/Model.java')
-rw-r--r--src/demos/dualDepthPeeling/Model.java424
1 files changed, 424 insertions, 0 deletions
diff --git a/src/demos/dualDepthPeeling/Model.java b/src/demos/dualDepthPeeling/Model.java
new file mode 100644
index 0000000..439b016
--- /dev/null
+++ b/src/demos/dualDepthPeeling/Model.java
@@ -0,0 +1,424 @@
+
+// Translated from C++ Version:
+// nvModel.h - Model support class
+//
+// The nvModel class implements an interface for a multipurpose model
+// object. This class is useful for loading and formatting meshes
+// for use by OpenGL. It can compute face normals, tangents, and
+// adjacency information. The class supports the obj file format.
+//
+// Author: Evan Hart
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.util.HashMap;
+import java.util.Vector;
+
+
+public class Model {
+ //
+ // Enumeration of primitive types
+ //
+ //////////////////////////////////////////////////////////////
+ public enum PrimType {
+ eptNone(0x0),
+ eptPoints(0x1),
+ eptEdges(0x2),
+ eptTriangles(0x4),
+ eptTrianglesWithAdjacency(0x8),
+ eptAll(0xf);
+
+ PrimType( int val )
+ {
+ m_iVal = val;
+ }
+ int m_iVal = 0;
+ };
+
+ public static final int NumPrimTypes = 4;
+
+ public Model CreateModel()
+ {
+ return new Model();
+ }
+
+ public Model()
+ {
+ posSize_ = 0;
+ pOffset_ = -1;
+ nOffset_ = -1;
+ vtxSize_ = 0;
+ openEdges_ = 0;
+ }
+
+
+ public class IdxSet {
+ Integer pIndex = 0;
+ Integer nIndex = 0;
+
+ boolean lessThan ( IdxSet rhs )
+ {
+ if (pIndex < rhs.pIndex)
+ return true;
+ else if (pIndex == rhs.pIndex) {
+ if (nIndex < rhs.nIndex)
+ return true;
+ }
+ return false;
+ }
+ };
+
+
+ //
+ // loadModelFromFile
+ //
+ // This function attempts to determine the type of
+ // the filename passed as a parameter. If it understands
+ // that file type, it attempts to parse and load the file
+ // into its raw data structures. If the file type is
+ // recognized and successfully parsed, the function returns
+ // true, otherwise it returns false.
+ //
+ //////////////////////////////////////////////////////////////
+ public boolean loadModelFromFile( String file ) {
+ URL fileURL = getClass().getClassLoader().getResource(File.separator + file);
+ if ( fileURL != null )
+ {
+ BufferedReader input = null;
+ try {
+
+ input = new BufferedReader(new InputStreamReader(fileURL.openStream()));
+ String line = null;
+ float[] val = new float[4];
+ int[][] idx = new int[3][3];
+ boolean hasNormals = false;
+
+ while ( (line = input.readLine()) != null) {
+ switch (line.charAt(0)) {
+ case '#':
+ break;
+
+ case 'v':
+ switch (line.charAt(1)) {
+
+ case ' ':
+ line = line.substring( line.indexOf( " " ) + 1 );
+ //vertex, 3 or 4 components
+ val[0] = Float.valueOf( line.substring( 0, line.indexOf( " " ) ) );
+ line = line.substring( line.indexOf( " " ) + 1 );
+ val[1] = Float.valueOf( line.substring( 0, line.indexOf( " " ) ) );
+ line = line.substring( line.indexOf( " " ) + 1 );
+ val[2] = Float.valueOf( line );
+ positions_.add( val[0]);
+ positions_.add( val[1]);
+ positions_.add( val[2]);
+ break;
+
+ case 'n':
+ //normal, 3 components
+ line = line.substring( line.indexOf( " " ) + 1 );
+ val[0] = Float.valueOf( line.substring( 0, line.indexOf( " " ) ) );
+ line = line.substring( line.indexOf( " " ) + 1 );
+ val[1] = Float.valueOf( line.substring( 0, line.indexOf( " " ) ) );
+ line = line.substring( line.indexOf( " " ) + 1 );
+ val[2] = Float.valueOf( line );
+ normals_.add( val[0]);
+ normals_.add( val[1]);
+ normals_.add( val[2]);
+ break;
+ }
+ break;
+
+ case 'f':
+ //face
+ line = line.substring( line.indexOf( " " ) + 2 );
+
+ idx[0][0] = Integer.valueOf( line.substring( 0, line.indexOf("//") ) ).intValue();
+ line = line.substring( line.indexOf( "//" ) + 2 );
+ idx[0][1] = Integer.valueOf( line.substring( 0, line.indexOf(" ") ) ).intValue();
+
+ {
+ //This face has vertex and normal indices
+
+ // in .obj, f v1 .... the vertex index used start from 1, so -1 here
+ //remap them to the right spot
+ idx[0][0] = (idx[0][0] > 0) ? (idx[0][0] - 1) : ((int)positions_.size() - idx[0][0]);
+ idx[0][1] = (idx[0][1] > 0) ? (idx[0][1] - 1) : ((int)normals_.size() - idx[0][1]);
+
+ //grab the second vertex to prime
+ line = line.substring( line.indexOf( " " ) + 1 );
+ idx[1][0] = Integer.valueOf( line.substring( 0, line.indexOf("//") ) );
+ line = line.substring( line.indexOf( "//" ) + 2 );
+ idx[1][1] = Integer.valueOf( line.substring( 0, line.indexOf(" ") ) );
+
+ //remap them to the right spot
+ idx[1][0] = (idx[1][0] > 0) ? (idx[1][0] - 1) : ((int)positions_.size() - idx[1][0]);
+ idx[1][1] = (idx[1][1] > 0) ? (idx[1][1] - 1) : ((int)normals_.size() - idx[1][1]);
+
+ //grab the third vertex to prime
+ line = line.substring( line.indexOf( " " ) + 1 );
+ idx[2][0] = Integer.valueOf( line.substring( 0, line.indexOf("//") ) );
+ line = line.substring( line.indexOf( "//" ) + 2 );
+ idx[2][1] = Integer.valueOf( line );
+ {
+ //remap them to the right spot
+ idx[2][0] = (idx[2][0] > 0) ? (idx[2][0] - 1) : ((int)positions_.size() - idx[2][0]);
+ idx[2][1] = (idx[2][1] > 0) ? (idx[2][1] - 1) : ((int)normals_.size() - idx[2][1]);
+
+ //add the indices
+ for (int ii = 0; ii < 3; ii++) {
+ pIndex_.add( idx[ii][0]);
+ nIndex_.add( idx[ii][1]);
+ }
+
+ //prepare for the next iteration, the num 0 does not change.
+ idx[1][0] = idx[2][0];
+ idx[1][1] = idx[2][1];
+ }
+ hasNormals = true;
+ }
+ break;
+
+ default:
+ break;
+ };
+ }
+ //post-process data
+ //free anything that ended up being unused
+ if (!hasNormals) {
+ normals_.clear();
+ nIndex_.clear();
+ }
+
+ posSize_ = 3;
+ return true;
+
+ } catch (FileNotFoundException kFNF) {
+ System.err.println("Unable to find the shader file " + file);
+ } catch (IOException kIO) {
+ System.err.println("Problem reading the shader file " + file);
+ } catch (NumberFormatException kIO) {
+ System.err.println("Problem reading the shader file " + file);
+ } finally {
+ try {
+ if (input != null) {
+ input.close();
+ }
+ } catch (IOException closee) {}
+ }
+ }
+ return false;
+ }
+
+ //
+ // compileModel
+ //
+ // This function takes the raw model data in the internal
+ // structures, and attempts to bring it to a format directly
+ // accepted for vertex array style rendering. This means that
+ // a unique compiled vertex will exist for each unique
+ // combination of position, normal, tex coords, etc that are
+ // used in the model. The prim parameter, tells the model
+ // what type of index list to compile. By default it compiles
+ // a simple triangle mesh with no connectivity.
+ //
+ public void compileModel( )
+ {
+ boolean needsTriangles = true;
+
+ HashMap<IdxSet, Integer> pts = new HashMap<IdxSet, Integer>();
+ vertices_ = FloatBuffer.allocate( (pIndex_.size() + nIndex_.size()) * 3 );
+ indices_ = IntBuffer.allocate( pIndex_.size() );
+ for ( int i = 0; i < pIndex_.size(); i++ ) {
+ IdxSet idx = new IdxSet();
+ idx.pIndex = pIndex_.elementAt(i);
+
+ if ( normals_.size() > 0)
+ idx.nIndex = nIndex_.elementAt(i);
+ else
+ idx.nIndex = 0;
+
+ if ( !pts.containsKey(idx) ) {
+ if (needsTriangles)
+ indices_.put( pts.size());
+
+ pts.put( idx, pts.size() );
+
+ //position,
+ vertices_.put( positions_.elementAt(idx.pIndex*posSize_));
+ vertices_.put( positions_.elementAt(idx.pIndex*posSize_ + 1));
+ vertices_.put( positions_.elementAt(idx.pIndex*posSize_ + 2));
+
+ //normal
+ if (normals_.size() > 0) {
+ vertices_.put( normals_.elementAt(idx.nIndex*3));
+ vertices_.put( normals_.elementAt(idx.nIndex*3 + 1));
+ vertices_.put( normals_.elementAt(idx.nIndex*3 + 2));
+ }
+
+ }
+ else {
+ if (needsTriangles)
+ indices_.put( pts.get(idx) );
+ }
+ }
+
+ //create selected prim
+
+ //set the offsets and vertex size
+ pOffset_ = 0; //always first
+ vtxSize_ = posSize_;
+ if ( hasNormals()) {
+ nOffset_ = vtxSize_;
+ vtxSize_ += 3;
+ }
+ else {
+ nOffset_ = -1;
+ }
+ vertices_.rewind();
+ indices_.rewind();
+ }
+
+ //
+ // computeBoundingBox
+ //
+ // This function returns the points defining the axis-
+ // aligned bounding box containing the model.
+ //
+ //////////////////////////////////////////////////////////////
+ public void computeBoundingBox( float[] minVal, float[] maxVal)
+ {
+ if ( positions_.isEmpty())
+ return;
+
+ for ( int i = 0; i < 3; i++ )
+ {
+ minVal[i] = 1e10f;
+ maxVal[i] = -1e10f;
+ }
+
+
+ for ( int i = 0; i < positions_.size(); i+= 3 ) {
+ float x = positions_.elementAt(i);
+ float y = positions_.elementAt(i+1);
+ float z = positions_.elementAt(i+2);
+ minVal[0] = Math.min( minVal[0], x );
+ minVal[1] = Math.min( minVal[1], y );
+ minVal[2] = Math.min( minVal[2], z );
+ maxVal[0] = Math.max( maxVal[0], x );
+ maxVal[1] = Math.max( maxVal[1], y );
+ maxVal[2] = Math.max( maxVal[2], z );
+ }
+ }
+
+
+ public void clearNormals()
+ {
+ normals_.clear();
+ nIndex_.clear();
+ }
+
+
+ public boolean hasNormals() {
+ return normals_.size() > 0;
+ }
+
+
+ public int getPositionSize() {
+ return posSize_;
+ }
+
+ public int getNormalSize() {
+ return 3;
+ }
+
+ public Vector<Float> getPositions() {
+ return ( positions_.size() > 0) ? positions_ : null;
+ }
+
+ public Vector<Float> getNormals() {
+ return ( normals_.size() > 0) ? normals_ : null;
+ }
+
+ public Vector<Integer> getPositionIndices() {
+ return ( pIndex_.size() > 0) ? pIndex_: null;
+ }
+
+ public Vector<Integer> getNormalIndices() {
+ return ( nIndex_.size() > 0) ? nIndex_ : null;
+ }
+
+ public int getPositionCount() {
+ return (posSize_ > 0) ? (int)positions_.size() / posSize_ : 0;
+ }
+
+ public int getNormalCount() {
+ return (int)normals_.size() / 3;
+ }
+
+ public int getIndexCount() {
+ return (int)pIndex_.size();
+ }
+
+ public FloatBuffer getCompiledVertices() {
+ return vertices_;
+ }
+
+ public IntBuffer getCompiledIndices( ) {
+ return indices_;
+ }
+
+ public int getCompiledPositionOffset() {
+ return pOffset_;
+ }
+
+ public int getCompiledNormalOffset() {
+ return nOffset_;
+ }
+
+
+ public int getCompiledVertexSize() {
+ return vtxSize_;
+ }
+
+ public int getCompiledVertexCount() {
+ return ((pIndex_.size() + nIndex_.size()) * 3);
+ }
+
+ public int getCompiledIndexCount( ) {
+ return pIndex_.size();
+ }
+
+ public int getOpenEdgeCount() {
+ return openEdges_;
+ }
+
+
+
+ Vector<Float> positions_ = new Vector<Float>();
+ Vector<Float> normals_ = new Vector<Float>();
+ int posSize_;
+
+ Vector<Integer> pIndex_ = new Vector<Integer>();
+ Vector<Integer> nIndex_ = new Vector<Integer>();
+
+ //data structures optimized for rendering, compiled model
+ IntBuffer indices_ = null;
+ FloatBuffer vertices_ = null;
+ int pOffset_;
+ int nOffset_;
+ int vtxSize_ = 0;
+
+ int openEdges_;
+};