/** * BVertexチャンクの読み込み * * @param br 読み込みストリーム * @return 頂点配列 * @param scale モデルの倍率 * @throws Exception */ private KGLPoint[] readBvertex(multiInput br, float scale) throws Exception { KGLPoint[] ret = null; String line = null; String[] s; int p; int pe; int datasize = 0; try { while ((line = br.readLine().trim()) != null) { if (line.length() <= 0) continue; s = line.split(" "); if (s[0].equals("Vector")) { if (s.length != 3) { line = null; break; } p = s[2].indexOf("["); pe = s[2].indexOf("]"); datasize = Integer.parseInt(s[2].substring(p + 1, pe)); break; } } } catch (Exception e) { Log.e("KGLMetaseq", "MQOファイル フォーマットエラー(Object>Bvertex)[" + line + "]"); throw new KGLException(e); } if (line == null) { return null; } if (datasize == 0) return null; byte[] bbuf = new byte[datasize]; if (datasize != br.read(bbuf)) return null; ByteBuffer bb; bb = ByteBuffer.wrap(bbuf); bb.order(ByteOrder.LITTLE_ENDIAN); // MQOファイルのエンディアンはIntel形式 FloatBuffer fb = bb.asFloatBuffer(); ret = new KGLPoint[fb.limit() / 3]; fb.position(0); float[] wf = new float[3]; for (int i = 0; i < ret.length; i++) { fb.get(wf); ret[i] = KGLPoint.create(wf).scale(scale); } while ((line = br.readLine().trim()) != null) { if (line.equals("}")) break; } return ret; }
/** * チャンクサーチ * * @param br 読み込みストリーム * @param isInner true:チャンク内部のチャンクサーチ false:一番外のチャンクサーチ * @return チャンク文字列 * @throws IOException */ private String[] Chank(multiInput br, boolean isInner) throws IOException { String ret[] = null; String ws[] = null; String read = null; char c; while ((read = br.readLine()) != null) { if (read.length() <= 0) continue; c = read.charAt(read.length() - 1); if (c == '{') { ws = read.split(" "); if (ws.length == 2) { ret = new String[2]; ret[0] = ws[0].trim(); ret[1] = "{"; break; } ret = new String[3]; ret[0] = ws[0].trim(); ret[1] = read.substring(ws[0].length(), read.length() - 2).trim(); ret[2] = "{"; break; } if (isInner) { ws = read.split(" ", 2); ret = new String[ws.length]; for (int i = 0; i < ws.length; i++) ret[i] = ws[i].trim(); break; } } return ret; }
private void set(String in_name, multiInput br, float scale) throws Exception { String line[]; name = getDoubleQuoatString(in_name); while ((line = Chank(br, true)) != null) { if (line[0].equals("}")) break; if (line[line.length - 1].equals("{")) { // 内部チャンク if (line[0].equals("vertex")) { vertex = readVertex(Integer.parseInt(line[1]), br, scale); continue; } if (line[0].equals("BVertex")) { vertex = readBvertex(br, scale); continue; } if (line[0].equals("face")) { face = readFace(br); continue; } String single = null; while ((single = br.readLine()) != null) { if (single.trim().equals("}")) break; } continue; } for (int i = 0; i < fls_names.length; i++) { if (fls_names[i].equals(line[0])) { dataSetter(data, fls[i], tys[i], line[1]); } } } }
/** * vertexチャンクの読み込み * * @param num チャンクにあるデータ数 * @param br 読み込みストリーム * @param scale モデルの倍率 * @return 頂点配列 * @throws Exception */ private KGLPoint[] readVertex(int num, multiInput br, float scale) throws Exception { KGLPoint[] ret = null; String line = null; String[] s; int cnt; ret = new KGLPoint[num]; cnt = 0; try { while ((line = br.readLine()) != null) { if (line.length() <= 0) continue; line = line.trim(); if (line.equals("}")) break; s = line.split(" ", 3); ret[cnt] = KGLPoint.createXYZ( Float.parseFloat(s[0]) * scale, Float.parseFloat(s[1]) * scale, Float.parseFloat(s[2]) * scale); cnt++; } } catch (Exception e) { Log.e("KGLMetaseq", "MQOファイル フォーマットエラー(Object>vertex)[" + line + "]"); throw e; } if (cnt != num) return null; return ret; }
/** * コンストラクタ ここでファイルからデータを読み込んでいる * * @param in_gl OpenGLコマンド群をカプセル化したクラス * @param in_texPool テクスチャ管理クラス * @param i_provider ファイルデータプロバイダ * @param mqoFile 読み込みファイル * @param scale モデルの倍率 * @param isUseVBO 頂点配列バッファを使用するかどうか */ protected KGLMetaseq( GL10 gl, KGLTextures in_texPool, AssetManager am, String msqname, float scale) { super(in_texPool, am, scale); // targetMQO = in_moq; material mats[] = null; InputStream fis = null; // InputStreamReader isr = null ; // BufferedReader br = null; multiInput br = null; String chankName[] = null; GLObject glo = null; ArrayList<GLObject> globjs = new ArrayList<GLObject>(); try { fis = am.open(msqname); // isr = new InputStreamReader(fis) ; // br = new BufferedReader(isr); br = new multiInput(fis); while ((chankName = Chank(br, false)) != null) { /* * for( int i = 0 ; i < chankName.length ; i++ ) { * System.out.print(chankName[i]+" ") ; } System.out.println() ; */ if (chankName[0].trim().toUpperCase().equals("MATERIAL")) { try { mats = new material[Integer.parseInt(chankName[1])]; for (int m = 0; m < mats.length; m++) { mats[m] = new material(); mats[m].set(br.readLine().trim()); // Log.i("KGLMetaseq", "Material(" + m+") :" + mats[m].toString()); } } catch (Exception mat_e) { Log.e("KGLMetaseq", "MQOファイル Materialチャンク読み込み例外発生 " + mat_e.getMessage()); throw new KGLException(mat_e); } } try { if (chankName[0].trim().toUpperCase().equals("OBJECT")) { objects object = new objects(); object.set(chankName[1], br, scale); // System.out.println(object.toString()) ; if (object.face == null) { continue; // 面情報のないオブジェクトは飛ばす } glo = makeObjs(gl, mats, object); if (glo != null) { globjs.add(glo); } } } catch (Exception obj_e) { Log.e( "KGLMetaseq", "MQOファイル Object[" + chankName[1] + "]チャンク読み込み例外発生 " + obj_e.toString()); throw new KGLException(obj_e); } } br.close(); // 読み込み終了 br = null; glObj = globjs.toArray(new GLObject[0]); } catch (Exception e) { e.printStackTrace(); } finally { try { if (br != null) br.close(); } catch (IOException e) { e.printStackTrace(); } } }
/** * faceチャンクの読み込み * * @param br 読み込みストリーム * @return 面配列 * @throws Exception */ private Face[] readFace(multiInput br) throws Exception { ArrayList<Face> qf; String line = null; String[] s; Integer Mn; Face[] wface = null; int p; int pe; qf = new ArrayList<Face>(); try { while ((line = br.readLine()) != null) { if (line.length() <= 0) continue; line = line.trim(); if (line.equals("}")) break; wface = null; Mn = null; p = line.indexOf("M("); if (p != -1) { pe = line.indexOf(")", p); Mn = Integer.parseInt(line.substring(p + 2, pe)); } p = line.indexOf("V("); if (p == -1) continue; pe = line.indexOf(")", p); s = line.substring(p + 2, pe).split(" "); if (s.length == 3) { wface = new Face[1]; wface[0] = new Face(); wface[0].V = new Integer[3]; wface[0].V[0] = Integer.parseInt(s[0]); wface[0].V[1] = Integer.parseInt(s[1]); wface[0].V[2] = Integer.parseInt(s[2]); wface[0].M = Mn; p = line.indexOf("UV("); if (p != -1) { pe = line.indexOf(")", p); s = line.substring(p + 3, pe).split(" "); if (s.length != 2 * 3) throw new Exception("UVの数が不正"); wface[0].UV = new Float[2 * 3]; for (int i = 0; i < s.length; i++) { wface[0].UV[i] = Float.parseFloat(s[i]); } } p = line.indexOf("COL("); if (p != -1) { pe = line.indexOf(")", p); s = line.substring(p + 4, pe).split(" "); if (s.length != 3) throw new Exception("COLの数が不正"); wface[0].COL = new Float[4 * 3]; long wl; float wf; for (int i = 0; i < s.length; i++) { wl = Long.parseLong(s[i]); wf = (wl >>> 0) & 0x000000ff; wface[0].COL[i * 4 + 0] = wf / 255f; wf = (wl >>> 8) & 0x000000ff; wface[0].COL[i * 4 + 1] = wf / 255f; wf = (wl >>> 16) & 0x000000ff; wface[0].COL[i * 4 + 2] = wf / 255f; wf = (wl >>> 24) & 0x000000ff; wface[0].COL[i * 4 + 3] = wf / 255f; } } } // 頂点配列はすべて三角にするので、四角は三角x2に分割 // 0 3 0 0 3 // □ → △ ▽ // 1 2 1 2 2 if (s.length == 4) { wface = new Face[2]; wface[0] = new Face(); wface[1] = new Face(); wface[0].V = new Integer[3]; wface[0].V[0] = Integer.parseInt(s[0]); wface[0].V[1] = Integer.parseInt(s[1]); wface[0].V[2] = Integer.parseInt(s[2]); wface[0].M = Mn; wface[1].V = new Integer[3]; wface[1].V[0] = Integer.parseInt(s[0]); wface[1].V[1] = Integer.parseInt(s[2]); wface[1].V[2] = Integer.parseInt(s[3]); wface[1].M = Mn; p = line.indexOf("UV("); if (p != -1) { int uv_p; pe = line.indexOf(")", p); s = line.substring(p + 3, pe).split(" "); if (s.length != 2 * 4) throw new Exception("UVの数が不正"); wface[0].UV = new Float[2 * 3]; wface[1].UV = new Float[2 * 3]; for (int i = 0; i < 2; i++) { uv_p = 0; for (int j = 0; j < 4; j++) { if (i == 0 && j == 3) continue; if (i == 1 && j == 1) continue; wface[i].UV[uv_p++] = Float.parseFloat(s[j * 2 + 0]); wface[i].UV[uv_p++] = Float.parseFloat(s[j * 2 + 1]); } } } p = line.indexOf("COL("); if (p != -1) { pe = line.indexOf(")", p); s = line.substring(p + 4, pe).split(" "); if (s.length != 4) throw new Exception("COLの数が不正"); wface[0].COL = new Float[4 * 3]; wface[1].COL = new Float[4 * 3]; long wl; float wf; int col_p; for (int i = 0; i < 2; i++) { col_p = 0; for (int j = 0; j < s.length; j++) { if (i == 0 && j == 3) continue; if (i == 1 && j == 1) continue; wl = Long.parseLong(s[j]); wf = (wl >>> 0) & 0x000000ff; wface[i].COL[col_p * 4 + 0] = wf / 255f; wf = (wl >>> 8) & 0x000000ff; wface[i].COL[col_p * 4 + 1] = wf / 255f; wf = (wl >>> 16) & 0x000000ff; wface[i].COL[col_p * 4 + 2] = wf / 255f; wf = (wl >>> 24) & 0x000000ff; wface[i].COL[col_p * 4 + 3] = wf / 255f; col_p++; } } } } if (wface != null) { for (int i = 0; i < wface.length; i++) { qf.add(wface[i]); } } } } catch (Exception e) { Log.e("KGLMetaseq", "MQOファイル フォーマットエラー(Object>face)" + e.getMessage() + "[" + line + "]"); throw e; } if (qf.size() == 0) return null; return qf.toArray(new Face[0]); }