I have put stripifier classes at
http://nwn-j3d.sourceforge.net/misc/jme-stripifier.zip
Here is an example how to use it - please also check javadocs for GeometryCreator class.
I’ll later implement method for creating GeometryInfo from already existing TriMesh.
If you want ply files, please look at
The Stanford 3D Scanning Repository
Be warned - res2 is very fast, for full resolution, stripification can take few minutes. This PlyLoader will work only for bunny - rest of ply files have a bit different format, I’ll make more compatible loader for inclusion into jME later.
package test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.StreamTokenizer;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.CompositeMesh;
import com.jme.scene.Geometry;
import com.jme.scene.TriMesh;
import com.jme.util.LoggingSystem;
import com.jme.util.geom.GeometryCreator;
import com.jme.util.geom.JmeGeometryInfo;
public class PlyLoader extends SimpleGame
{
private Quaternion rotQuat = new Quaternion();
private float angle = 0;
private Vector3f axis = new Vector3f(1, 1, 0);
private Geometry s;
/**
* Entry point for the test,
* @param args
*/
public static void main(String[] args) {
LoggingSystem.getLogger().setLevel(java.util.logging.Level.OFF);
PlyLoader app = new PlyLoader();
app.setDialogBehaviour(SimpleGame.NEVER_SHOW_PROPS_DIALOG);
app.start();
}
protected void simpleUpdate() {
if (tpf < 1) {
angle = angle + (tpf * 1);
if (angle > 360) {
angle = 0;
}
}
rotQuat.fromAngleAxis(angle, axis);
s.setLocalRotation(rotQuat);
}
/**
* builds the trimesh.
* @see com.jme.app.SimpleGame#initGame()
*/
protected void simpleInitGame() {
display.setTitle("jME");
try {
s = loadObj("e:\models\bun_zipper_res2.ply");
} catch (Exception e ) {
throw new Error(e);
}
s.setLocalTranslation(new Vector3f(0,0,-40));
s.setModelBound(new BoundingBox());
s.updateModelBound();
rootNode.attachChild(s);
}
public static Geometry loadObj(String filename) throws IOException{
BufferedReader br = new BufferedReader(new FileReader(filename));
StreamTokenizer st = new StreamTokenizer(br);
st.resetSyntax();
st.eolIsSignificant(false);
st.wordChars(0,255);
st.whitespaceChars(' ', ' ');
st.whitespaceChars('n','n');
st.whitespaceChars('r','r');
st.whitespaceChars('t','t');
String str;
int vertexCount = 0;
int facesCount = 0;
GeometryCreator create = new GeometryCreator();
while ( true ) {
int token = st.nextToken();
if ( token == StreamTokenizer.TT_EOF )
break;
if ( token != StreamTokenizer.TT_WORD)
continue;
if ( st.sval.equalsIgnoreCase("element")) {
st.nextToken();
if ( st.sval.equalsIgnoreCase("vertex") ) {
st.nextToken();
vertexCount = Integer.parseInt(st.sval);
} else if (st.sval.equalsIgnoreCase("face")) {
st.nextToken();
facesCount = Integer.parseInt(st.sval);
}
} else if (st.sval.equalsIgnoreCase("end_header") ){
break;
}
}
float scale = 200;
for ( int i =0; i < vertexCount; i++) {
st.nextToken();
float x = scale*Float.parseFloat(st.sval);
st.nextToken();
float y = scale*Float.parseFloat(st.sval);
st.nextToken();
float z = scale*Float.parseFloat(st.sval);
st.nextToken();
st.nextToken();
create.addCoordinate(x,y,z);
}
for ( int i =0; i < facesCount; i++ ) {
st.nextToken();
st.nextToken();
int f1 = Integer.parseInt(st.sval);
st.nextToken();
int f2 = Integer.parseInt(st.sval);
st.nextToken();
int f3 = Integer.parseInt(st.sval);
create.addCoordIndex(f1);
create.addCoordIndex(f2);
create.addCoordIndex(f3);
create.setFaceSmoothingGroup(1);
create.nextFace();
}
JmeGeometryInfo geom = new JmeGeometryInfo();
create.fillGeometryInfo(geom);
//geom.recalculateFlatNormals();
geom.recalculateSmoothGroupNormals();
geom.weldVertices();
TriMesh g;
//geom.optimizeTrianglesForCache();
g = geom.createTrimesh("TestMesh");
//g = geom.createMixedArray("a1",4,true);
//g = geom.createContinousStripMesh("a1");
//g = geom.createChunkedStripArray("a1");
System.out.println("Indices = "+g.getIndices().length + " vertices= "+g.getVertices().length);
if ( g instanceof CompositeMesh ) {
System.out.println("Ranges = "+((CompositeMesh)g).getIndexRanges().length);
}
return g;
}
}