@Override public LoaderOBJ parse() throws ParsingException { super.parse(); BufferedReader buffer = null; if (mFile == null) { InputStream fileIn = mResources.openRawResource(mResourceId); buffer = new BufferedReader(new InputStreamReader(fileIn)); } else { try { buffer = new BufferedReader(new FileReader(mFile)); } catch (FileNotFoundException e) { RajLog.e("[" + getClass().getCanonicalName() + "] Could not find file."); e.printStackTrace(); } } String line; ObjIndexData currObjIndexData = new ObjIndexData(new Object3D()); ArrayList<ObjIndexData> objIndices = new ArrayList<ObjIndexData>(); ArrayList<Float> vertices = new ArrayList<Float>(); ArrayList<Float> texCoords = new ArrayList<Float>(); ArrayList<Float> normals = new ArrayList<Float>(); MaterialLib matLib = new MaterialLib(); try { while ((line = buffer.readLine()) != null) { // Skip comments and empty lines. if (line.length() == 0 || line.charAt(0) == '#') continue; StringTokenizer parts = new StringTokenizer(line, " "); int numTokens = parts.countTokens(); if (numTokens == 0) continue; String type = parts.nextToken(); if (type.equals(VERTEX)) { vertices.add(Float.parseFloat(parts.nextToken())); vertices.add(Float.parseFloat(parts.nextToken())); vertices.add(Float.parseFloat(parts.nextToken())); } else if (type.equals(FACE)) { boolean isQuad = numTokens == 5; int[] quadvids = new int[4]; int[] quadtids = new int[4]; int[] quadnids = new int[4]; boolean emptyVt = line.indexOf("//") > -1; if (emptyVt) line = line.replace("//", "/"); parts = new StringTokenizer(line); parts.nextToken(); StringTokenizer subParts = new StringTokenizer(parts.nextToken(), "/"); int partLength = subParts.countTokens(); boolean hasuv = partLength >= 2 && !emptyVt; boolean hasn = partLength == 3 || (partLength == 2 && emptyVt); int idx; for (int i = 1; i < numTokens; i++) { if (i > 1) subParts = new StringTokenizer(parts.nextToken(), "/"); idx = Integer.parseInt(subParts.nextToken()); if (idx < 0) idx = (vertices.size() / 3) + idx; else idx -= 1; if (!isQuad) currObjIndexData.vertexIndices.add(idx); else quadvids[i - 1] = idx; if (hasuv) { idx = Integer.parseInt(subParts.nextToken()); if (idx < 0) idx = (texCoords.size() / 2) + idx; else idx -= 1; if (!isQuad) currObjIndexData.texCoordIndices.add(idx); else quadtids[i - 1] = idx; } if (hasn) { idx = Integer.parseInt(subParts.nextToken()); if (idx < 0) idx = (normals.size() / 3) + idx; else idx -= 1; if (!isQuad) currObjIndexData.normalIndices.add(idx); else quadnids[i - 1] = idx; } } if (isQuad) { int[] indices = new int[] {0, 1, 2, 0, 2, 3}; for (int i = 0; i < 6; ++i) { int index = indices[i]; currObjIndexData.vertexIndices.add(quadvids[index]); currObjIndexData.texCoordIndices.add(quadtids[index]); currObjIndexData.normalIndices.add(quadnids[index]); } } } else if (type.equals(TEXCOORD)) { texCoords.add(Float.parseFloat(parts.nextToken())); texCoords.add(1f - Float.parseFloat(parts.nextToken())); } else if (type.equals(NORMAL)) { normals.add(Float.parseFloat(parts.nextToken())); normals.add(Float.parseFloat(parts.nextToken())); normals.add(Float.parseFloat(parts.nextToken())); } else if (type.equals(OBJECT) || type.equals(GROUP)) { String objName = parts.hasMoreTokens() ? parts.nextToken() : "Object" + (int) (Math.random() * 10000); if (type.equals(OBJECT)) { RajLog.i("Parsing object: " + objName); if (currObjIndexData.targetObj.getName() != null) currObjIndexData = new ObjIndexData(new Object3D(objName)); else currObjIndexData.targetObj.setName(objName); objIndices.add(currObjIndexData); } else if (type.equals(GROUP)) { RajLog.i("Parsing group: " + objName); Object3D group = mRootObject.getChildByName(objName); if (group == null) { group = new Object3D(objName); mRootObject.addChild(group); } group.addChild(currObjIndexData.targetObj); } } else if (type.equals(MATERIAL_LIB)) { if (!parts.hasMoreTokens()) continue; String materialLibPath = parts.nextToken().replace(".", "_"); Log.d(Wallpaper.TAG, "Found Material Lib: " + materialLibPath); if (mFile != null) matLib.parse(materialLibPath, null, null); else matLib.parse( materialLibPath, mResources.getResourceTypeName(mResourceId), mResources.getResourcePackageName(mResourceId)); } else if (type.equals(USE_MATERIAL)) { currObjIndexData.materialName = parts.nextToken(); } } buffer.close(); if (objIndices.size() == 0) { objIndices.add(currObjIndexData); } } catch (IOException e) { throw new ParsingException(e); } int numObjects = objIndices.size(); for (int j = 0; j < numObjects; ++j) { ObjIndexData oid = objIndices.get(j); int i; float[] aVertices = new float[oid.vertexIndices.size() * 3]; float[] aTexCoords = new float[oid.texCoordIndices.size() * 2]; float[] aNormals = new float[oid.normalIndices.size() * 3]; float[] aColors = new float[oid.colorIndices.size() * 4]; int[] aIndices = new int[oid.vertexIndices.size()]; for (i = 0; i < oid.vertexIndices.size(); ++i) { int faceIndex = oid.vertexIndices.get(i) * 3; int vertexIndex = i * 3; try { aVertices[vertexIndex] = vertices.get(faceIndex); aVertices[vertexIndex + 1] = vertices.get(faceIndex + 1); aVertices[vertexIndex + 2] = vertices.get(faceIndex + 2); aIndices[i] = i; } catch (ArrayIndexOutOfBoundsException e) { Log.d("Rajawali", "ERREUR!! " + vertexIndex + ", " + faceIndex); } } if (texCoords != null && texCoords.size() > 0) { for (i = 0; i < oid.texCoordIndices.size(); ++i) { int texCoordIndex = oid.texCoordIndices.get(i) * 2; int ti = i * 2; aTexCoords[ti] = texCoords.get(texCoordIndex); aTexCoords[ti + 1] = texCoords.get(texCoordIndex + 1); } } for (i = 0; i < oid.colorIndices.size(); ++i) { int colorIndex = oid.colorIndices.get(i) * 4; int ti = i * 4; aTexCoords[ti] = texCoords.get(colorIndex); aTexCoords[ti + 1] = texCoords.get(colorIndex + 1); aTexCoords[ti + 2] = texCoords.get(colorIndex + 2); aTexCoords[ti + 3] = texCoords.get(colorIndex + 3); } for (i = 0; i < oid.normalIndices.size(); ++i) { int normalIndex = oid.normalIndices.get(i) * 3; int ni = i * 3; if (normals.size() == 0) { RajLog.e( "[" + getClass().getName() + "] There are no normals specified for this model. Please re-export with normals."); throw new ParsingException( "[" + getClass().getName() + "] There are no normals specified for this model. Please re-export with normals."); } aNormals[ni] = normals.get(normalIndex); aNormals[ni + 1] = normals.get(normalIndex + 1); aNormals[ni + 2] = normals.get(normalIndex + 2); } oid.targetObj.setData(aVertices, aNormals, aTexCoords, aColors, aIndices); try { matLib.setMaterial(oid.targetObj, oid.materialName); } catch (TextureException tme) { throw new ParsingException(tme); } if (oid.targetObj.getParent() == null) mRootObject.addChild(oid.targetObj); } if (mRootObject.getNumChildren() == 1 && !mRootObject.getChildAt(0).isContainer()) mRootObject = mRootObject.getChildAt(0); return this; }
protected void initScene() { DirectionalLight light = new DirectionalLight(0, -.6f, .4f); light.setPower(1); getCurrentScene().addLight(light); // -- create sky sphere mSphere = new Sphere(400, 8, 8); Material sphereMaterial = new Material(); try { sphereMaterial.addTexture(new Texture("skySphere", R.drawable.skysphere)); } catch (TextureException e1) { e1.printStackTrace(); } mSphere.setMaterial(sphereMaterial); mSphere.setDoubleSided(true); addChild(mSphere); try { // -- load gzipped serialized object ObjectInputStream ois; GZIPInputStream zis = new GZIPInputStream(mContext.getResources().openRawResource(R.raw.raptor)); ois = new ObjectInputStream(zis); mRaptor = new Object3D((SerializedObject3D) ois.readObject()); Material raptorMaterial = new Material(); raptorMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); raptorMaterial.enableLighting(true); raptorMaterial.addTexture(new Texture("raptorTex", R.drawable.raptor_texture)); mRaptor.setMaterial(raptorMaterial); mRaptor.setScale(.5f); addChild(mRaptor); } catch (Exception e) { e.printStackTrace(); } // -- create a bunch of cubes that will serve as orientation helpers mCubes = new Object3D[30]; mRootCube = new Cube(1); Material rootCubeMaterial = new Material(); rootCubeMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); rootCubeMaterial.enableLighting(true); try { rootCubeMaterial.addTexture(new Texture("camouflage", R.drawable.camouflage)); } catch (TextureException e) { e.printStackTrace(); } mRootCube.setMaterial(rootCubeMaterial); mRootCube.setY(-1f); // -- similar objects with the same material, optimize mRootCube.setRenderChildrenAsBatch(true); addChild(mRootCube); mCubes[0] = mRootCube; for (int i = 1; i < mCubes.length; ++i) { Object3D cube = mRootCube.clone(true); cube.setY(-1f); cube.setZ(i * 30); mRootCube.addChild(cube); mCubes[i] = cube; } // -- create a chase camera // the first parameter is the camera offset // the second parameter is the interpolation factor ChaseCamera chaseCamera = new ChaseCamera(new Vector3(0, 3, 16), .1f); // -- tell the camera which object to chase chaseCamera.setObjectToChase(mRaptor); // -- set the far plane to 1000 so that we actually see the sky sphere chaseCamera.setFarPlane(1000); replaceAndSwitchCamera(chaseCamera, 0); }