package gl.parsers; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Calendar; import java.util.HashMap; import java.util.StringTokenizer; import util.EfficientList; import util.Log; import util.Vec; import android.content.res.Resources; /* * TODO * * http://en.wikipedia.org/wiki/Obj#Vertex.2FTexture-coordinate * * http://local.wasp.uwa.edu.au/~pbourke/dataformats/obj/ */ @Deprecated public class ObjParser { private static final String LOG_TAG = "Obj-Parser"; private final String VERTEX = "v"; private final String FACE = "f"; private final String TEXCOORD = "vt"; private final String NORMAL = "vn"; private final String OBJECT = "o"; private final String MATERIAL_LIB = "mtllib"; private final String USE_MATERIAL = "usemtl"; private final String NEW_MATERIAL = "newmtl"; private final String DIFFUSE_TEX_MAP = "map_Kd"; private HashMap<String, ObjMaterial> materialMap; private Resources resources; private String resourceID; private String packageID; /** * A material key will be something like Material_XY.TGA and will be defined * in one of the importet mtl files */ private String currentMaterialKey; public ObjParser(Resources resources, String resourceID) { this.resources = resources; this.resourceID = resourceID; if (resourceID.indexOf(":") > -1) this.packageID = resourceID.split(":")[0]; } public void parse() throws Exception { long startTime = Calendar.getInstance().getTimeInMillis(); InputStream fileIn = resources.openRawResource(resources.getIdentifier( resourceID, null, null)); BufferedReader buffer = new BufferedReader( new InputStreamReader(fileIn)); // materialMap = new HashMap<String, ObjMaterial>(); Log.d(LOG_TAG, "Start parsing object " + resourceID); Log.d(LOG_TAG, "Start time " + startTime); EfficientList<Vec> vertexList = new EfficientList<Vec>(); EfficientList<TexturCoord> textureList = new EfficientList<TexturCoord>(); EfficientList<int[]> shapeList = new EfficientList<int[]>(); EfficientList<Vec> normalsList = new EfficientList<Vec>(); String line; while ((line = buffer.readLine()) != null) { StringTokenizer lineElements = new StringTokenizer(line, " "); if (lineElements.countTokens() == 0) continue; String type = lineElements.nextToken(); if (type.equals(VERTEX)) { Vec vertex = new Vec(); vertex.x = Float.parseFloat(lineElements.nextToken()); vertex.y = Float.parseFloat(lineElements.nextToken()); vertex.z = Float.parseFloat(lineElements.nextToken()); vertexList.add(vertex); } else if (type.equals(FACE)) { /* * something like "f 102 24 91 7" so its a face with 4 vertices */ int verticesCount = lineElements.countTokens() - 1; int[] indiceArray = new int[verticesCount]; for (int i = 0; i < verticesCount; i++) { indiceArray[i] = Integer.parseInt(lineElements.nextToken()); } shapeList.add(indiceArray); } else if (type.equals(TEXCOORD)) { TexturCoord texCoord = new TexturCoord( Float.parseFloat(lineElements.nextToken()), Float.parseFloat(lineElements.nextToken())); textureList.add(texCoord); } else if (type.equals(NORMAL)) { Vec normal = new Vec(); normal.x = Float.parseFloat(lineElements.nextToken()); normal.y = Float.parseFloat(lineElements.nextToken()); normal.z = Float.parseFloat(lineElements.nextToken()); normalsList.add(normal); } else if (type.equals(MATERIAL_LIB)) { loadMaterialLib(lineElements.nextToken()); } else if (type.equals(USE_MATERIAL)) { currentMaterialKey = lineElements.nextToken(); } } long endTime = Calendar.getInstance().getTimeInMillis(); Log.d(LOG_TAG, "End time " + (endTime - startTime)); } public class TexturCoord { float x; float y; public TexturCoord(float x, float y) { this.x = x; this.y = y; } } private void loadMaterialLib(String libID) { StringBuffer resourceID = new StringBuffer(packageID); StringBuffer libIDSbuf = new StringBuffer(libID); int dotIndex = libIDSbuf.lastIndexOf("."); if (dotIndex > -1) libIDSbuf = libIDSbuf.replace(dotIndex, dotIndex + 1, "_"); resourceID.append(":raw/"); resourceID.append(libIDSbuf.toString()); InputStream fileIn = resources.openRawResource(resources.getIdentifier( resourceID.toString(), null, null)); BufferedReader buffer = new BufferedReader( new InputStreamReader(fileIn)); String line; String currentMaterial = ""; try { while ((line = buffer.readLine()) != null) { String[] parts = line.split(" "); if (parts.length == 0) continue; String type = parts[0]; if (type.equals(NEW_MATERIAL)) { if (parts.length > 1) { currentMaterial = parts[1]; materialMap.put(currentMaterial, new ObjMaterial( currentMaterial)); } } else if (type.equals(DIFFUSE_TEX_MAP)) { if (parts.length > 1) { materialMap.get(currentMaterial).diffuseTextureMap = parts[1]; StringBuffer texture = new StringBuffer(packageID); texture.append(":drawable/"); StringBuffer textureName = new StringBuffer(parts[1]); dotIndex = textureName.lastIndexOf("."); if (dotIndex > -1) texture.append(textureName.substring(0, dotIndex)); else texture.append(textureName); int bmResourceID = resources.getIdentifier( texture.toString(), null, null); // Bitmap b = // Utils.makeBitmapFromResourceId(bmResourceID); // textureAtlas.addBitmapAsset(new BitmapAsset( // currentMaterial, texture.toString())); } } } } catch (IOException e) { e.printStackTrace(); } } // private class ObjFace extends ParseObjectFace { // public ObjFace(String line, String materialKey, int faceLength) { // super(); // this.materialKey = materialKey; // this.faceLength = faceLength; // boolean emptyVt = line.indexOf("//") > -1; // if (emptyVt) // line = line.replace("//", "/"); // StringTokenizer parts = new StringTokenizer(line); // parts.nextToken(); // StringTokenizer subParts = new StringTokenizer(parts.nextToken(), // "/"); // int partLength = subParts.countTokens(); // hasuv = partLength >= 2 && !emptyVt; // hasn = partLength == 3 || (partLength == 2 && emptyVt); // // v = new int[faceLength]; // if (hasuv) // uv = new int[faceLength]; // if (hasn) // n = new int[faceLength]; // // for (int i = 1; i < faceLength + 1; i++) { // if (i > 1) // subParts = new StringTokenizer(parts.nextToken(), "/"); // // int index = i - 1; // v[index] = (short) (Short.parseShort(subParts.nextToken()) - 1); // if (hasuv) // uv[index] = (short) (Short.parseShort(subParts.nextToken()) - 1); // if (hasn) // n[index] = (short) (Short.parseShort(subParts.nextToken()) - 1); // } // } // } private class ObjMaterial { public String name; public String diffuseTextureMap; public float offsetU; public float offsetV; public ObjMaterial(String name) { this.name = name; } } }