diff options
author | Alexandra Bokinsky <[email protected]> | 2011-03-15 11:45:09 -0400 |
---|---|---|
committer | Alexandra Bokinsky <[email protected]> | 2011-03-15 11:45:09 -0400 |
commit | 2db5af1e1a64d7048ce2f0db4b83d8b10c7f734d (patch) | |
tree | f0700a1dc4fc08315cf0a2c36c209c96c0260965 /src/demos/dualDepthPeeling/Model.java | |
parent | 05e3d96ff9586b2f6cd5c2841337f9be7d07c313 (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.java | 424 |
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 +// Email: [email protected] +// +// 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_; +}; |