今回はMQOファイルをパースする。まずはObject要素のvertex要素から。単純にtrimでタブとって、空白を区切り文字としてsplitして文字列をfloatにするだけ。}が来たら終了
package net.d_kami.mqo.parser; import net.d_kami.mqo.MQOObject; import net.d_kami.mqo.MQOLines; import net.d_kami.mqo.MQOVertex; public class VertexParser{ public static void parse(MQOObject object, MQOLines lines){ while(true){ String line = lines.next(); if(line == null){ throw new ParseException("Vertex要素解析中にファイルが終了しました"); } line = line.trim(); if(line.equals("}")){ break; } String[] elements = line.split(" "); if(elements.length != 3){ throw new ParseException("Vertexの要素数が異常です: " + lines.current() + "行目"); } float x = Float.parseFloat(elements[0]); float y = Float.parseFloat(elements[1]); float z = Float.parseFloat(elements[2]); object.addVertex(x, y, z); } } }
次にface要素の取出し。手抜きで()の中の数字を取り出してるだけ。UVは無視。マテリアルも無視、最初のインデックス数も無視。酷い
package net.d_kami.mqo.parser; import net.d_kami.mqo.MQOObject; import net.d_kami.mqo.MQOLines; import net.d_kami.mqo.MQOFace; public class FaceParser{ public static void parse(MQOObject object, MQOLines lines){ while(true){ String line = lines.next(); if(line == null){ throw new ParseException("Vertex要素解析中にファイルが終了しました"); } line = line.trim(); if(line.equals("}")){ break; } int start = line.indexOf("("); int end = line.indexOf(")"); String element = line.substring(start + 1, end); String[] elements = element.split(" "); object.addFace(elements); } } }
次にObject要素のパース。vertexが来たらVertexParser、faceが来たらFaceParserに任せる。
package net.d_kami.mqo.parser; import net.d_kami.mqo.MQOContainer; import net.d_kami.mqo.MQOObject; import net.d_kami.mqo.MQOLines; public class ObjectParser{ public static void parse(MQOContainer container, MQOLines lines){ MQOObject object = new MQOObject(); container.addObject(object); while(true){ String line = lines.next(); if(line == null){ throw new ParseException("Object要素解析中にファイルが終了しました"); } line = line.trim(); if(line.equals("}")){ break; } if(line.startsWith("vertex ")){ VertexParser.parse(object, lines); }else if(line.startsWith("face ")){ FaceParser.parse(object, lines); } } } }
最後にMQO全体のパース。とは言ってもObject要素が来たらObjectParserに任せるのみ。他の要素は無視。手抜き!
package net.d_kami.mqo.parser; import net.d_kami.mqo.MQOContainer; import net.d_kami.mqo.MQOLines; public class MQOParser{ public static MQOContainer parse(MQOLines lines){ String line; MQOContainer container = new MQOContainer(); while((line = lines.next()) != null){ line = line.trim(); if(line.startsWith("Object")){ ObjectParser.parse(container, lines); } } return container; } }
ついでにサンプル
import java.io.FileReader; import java.io.BufferedReader; import java.io.IOException; import java.util.List; import java.util.ArrayList; import net.d_kami.mqo.MQOLines; import net.d_kami.mqo.MQOFace; import net.d_kami.mqo.MQOVertex; import net.d_kami.mqo.MQOObject; import net.d_kami.mqo.MQOContainer; import net.d_kami.mqo.parser.MQOParser; public class MQO{ public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new FileReader(args[0])); String line; List<String> list = new ArrayList<String>(); while((line = br.readLine()) != null){ list.add(line); } br.close(); MQOLines lines = new MQOLines(list.toArray(new String[0])); MQOContainer container = MQOParser.parse(lines); for(MQOObject object : container){ System.out.println("Vertices"); for(MQOVertex vertex : object.getVertices()){ System.out.printf("%f %f %f\n", vertex.x, vertex.y, vertex.z); } System.out.println("Faces"); for(MQOFace face : object.getFaces()){ for(int i = 0; i < face.getSize(); i++){ System.out.printf("%d ", face.getIndex(i)); } System.out.println(); } } } }