package glmodel; import java.io.*; import java.util.ArrayList; /** * Import a 3DS file into a GL_Model object. */ public class GL_3DS_Importer { // Reads the 3DS files into vertex and face lists private GL_3DS_Reader reader = new GL_3DS_Reader(); // Mesh object will hold the data in a renderable form private GL_Mesh mesh = new GL_Mesh(); public GL_3DS_Importer() { } public GL_Mesh load(String filename) { System.out.println("GL_3DS_Importer.import(): Load object from " + filename); reader = new GL_3DS_Reader(filename); System.out.println("GL_3DS_Importer.importFromStream(): model has " + reader.faces.size() + " faces and " + reader.vertices.size() + " vertices. "); return makeMeshObject(reader.vertices, reader.textureCoords, reader.normals, reader.faces ); } /** * Load the 3DS file and store into a mesh. */ public GL_Mesh importFromStream(InputStream inStream) { System.out.println("importFromStream(): Load object from stream..."); reader.load3DSFromStream(inStream); System.out.println("importFromStream(): model has " + reader.faces.size() + " faces and " + reader.vertices.size() + " vertices and " + reader.textureCoords.size() + " txtrcoords." ); return makeMeshObject(reader.vertices, reader.textureCoords, reader.normals, reader.faces ); } /** * create a GL_Object (mesh object) from the data read by a 3DS_Reader * @param verts ArrayList of vertices * @param txtrs ArrayList of texture coordinates * @param norms ArrayList of normal * @param faces ArrayList of Face objects (triangles) * @return */ public GL_Mesh makeMeshObject(ArrayList verts, ArrayList txtrs, ArrayList norms, ArrayList faces ) { mesh = new GL_Mesh(); // mesh object mesh.name = "3DS"; // add verts to GL_object for (int i = 0; i < verts.size(); i++) { float[] coords = (float[]) verts.get(i); mesh.addVertex(coords[0], coords[1], coords[2]); } // add triangles to GL_object. 3DS "face" is always a triangle. for (int i = 0; i < faces.size(); i++) { Face face = (Face) faces.get(i); // put verts, normals, texture coords into triangle addTriangle(mesh, face, txtrs, norms); } // optimize the GL_Object and generate normals mesh.rebuild(); // if no normals were loaded, generate some if (norms.size() == 0) { mesh.regenerateNormals(); } return mesh; } /** * Add a new triangle to the GL_Object. This assumes that the * vertices have already been added to the GL_Object, in the same * order that they were in the 3DS. * @param obj GL_Object * @param face a face from the OBJ file * @param txtrs ArrayList of texture coords from the OBJ file * @param norms ArrayList of normals from the OBJ file * @param v1 vertices to use for the triangle (face may have >3 verts) * @param v2 * @param v3 * @return */ public GL_Triangle addTriangle( GL_Mesh obj, Face face, ArrayList txtrs, ArrayList norms) { // An OBJ face may have many vertices (can be a polygon). // Make a new triangle with the specified three verts. GL_Triangle t = new GL_Triangle( obj.vertex(face.vertexIDs[0]), obj.vertex(face.vertexIDs[1]), obj.vertex(face.vertexIDs[2])); // put texture coords into triangle if (txtrs.size() > 0) { // if texture coords were loaded float[] uvw; uvw = (float[]) txtrs.get(face.textureIDs[0]); // txtr coord for vert 1 t.uvw1 = new GL_Vector(uvw[0], uvw[1], uvw[2]); uvw = (float[]) txtrs.get(face.textureIDs[1]); // txtr coord for vert 2 t.uvw2 = new GL_Vector(uvw[0], uvw[1], uvw[2]); uvw = (float[]) txtrs.get(face.textureIDs[2]); // txtr coord for vert 3 t.uvw3 = new GL_Vector(uvw[0], uvw[1], uvw[2]); } // put normals into triangle (NOTE: normalID can be -1!!! could barf here!!!) if (norms.size() > 0) { // if normals were loaded float[] norm; norm = (float[]) norms.get(face.normalIDs[0]); // normal for vert 1 t.norm1 = new GL_Vector(norm[0], norm[1], norm[2]); norm = (float[]) norms.get(face.normalIDs[1]); // normal for vert 2 t.norm2 = new GL_Vector(norm[0], norm[1], norm[2]); norm = (float[]) norms.get(face.normalIDs[2]); // normal for vert 3 t.norm3 = new GL_Vector(norm[0], norm[1], norm[2]); } // add triangle to GL_object mesh.addTriangle(t); return t; } }