obj文件读取
public List<Triangle> readObjFile(String path) {
FileInputStream fis = null;
BufferedReader br = null;
Pattern pattern = Pattern.compile("[ ]+");
try {
fis = new FileInputStream(new File(path));
br = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = br.readLine()) != null) {
//用空格分割行中的各个组成部分
String[] tempsa = pattern.split(line);
if (tempsa[0].trim().equals("usemtl")){
//读取到usemtl则代表从这一行一下直到遇到下一个usemtl为之都是使用同一材质的面,将这些面归为一组数据并加载。
mtlInfo = map.get(tempsa[1]);
triangle = new Triangle();
triangle.mtlInfo = mtlInfo;
triangles.add(triangle);
}else if (tempsa[0].trim().equals("v")) {//读取顶点坐标
//读取顶点数据时,顺便计算出所有顶点 x,y,z 坐标的最值 ,计算出中心点
xMin = Math.min(xMin, Float.parseFloat(tempsa[1]));
xMax = Math.max(xMax, Float.parseFloat(tempsa[1]));
yMin = Math.min(yMin, Float.parseFloat(tempsa[2]));
yMax = Math.max(yMax, Float.parseFloat(tempsa[2]));
zMin = Math.min(zMin, Float.parseFloat(tempsa[3]));
zMax = Math.max(zMax, Float.parseFloat(tempsa[3]));
read(tempsa,vertexList);
}else if(tempsa[0].trim().equals("vn")){
read(tempsa,normalList);
}else if (tempsa[0].trim().equals("f")) {
//暂时不取模型的vt数据
for (int i = 1; i < tempsa.length; i++) {
int vIndex = Integer.parseInt(tempsa[i].split("/")[0]) - 1;
float x = vertexList.get(3 * vIndex );
float y = vertexList.get(3 * vIndex + 1);
float z = vertexList.get(3 * vIndex + 2);
triangle.vertexList.add(x);
triangle.vertexList.add(y);
triangle.vertexList.add(z);
int normalIndex = Integer.parseInt(tempsa[i].split("/")[2]) - 1;
float a = normalList.get(3 * normalIndex);
float b = normalList.get(3 * normalIndex + 1);
float c = normalList.get(3 * normalIndex + 2);
triangle.normalList.add(a);
triangle.normalList.add(b);
triangle.normalList.add(c);
}
}
}
//有些模型生成的时候模型的中心点并不是(0,0,0)计算出中心点可以将模型平移到中心点
cx = xMin + (xMax - xMin) / 2;
cy = yMin + (yMax - yMin) / 2;
cz = zMin + (zMax - zMin) / 2;
vertexList.clear();
vertexList=null;
normalList.clear();
normalList = null;
if (br != null) {
br.close();
}
if (fis != null) {
fis.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return triangles;
}
private void read(String[] value, List<Float> list){
for (int i=1;i<value.length;i++){
list.add(Float.parseFloat(value[i]));
}
}
在开发中这种读取数据的方式只适用加载顶点数比较少的模型,比较大的模型还是使用jni进行读取。split方法,parseInt/Float 等方法有速度慢 占用内存大的缺点,对顶点数比较多的模型而言,很不友好。
2.mtl文件读取
Map<String, MtlInfo> map = new HashMap<>();
public void readMtlFile(String mtlPath) {
FileInputStream fis = null;
BufferedReader br = null;
MtlInfo mtlInfo = null;
try {
fis = new FileInputStream(new File(mtlPath));
br = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = br.readLine()) != null) {
String[] tempsa = line.split("[ ]+");
if (tempsa[0].trim().equals("newmtl")){
mtlInfo = new MtlInfo();
mtlInfo.newmtl = tempsa[1];
map.put(tempsa[1], mtlInfo);
}else if (tempsa[0].trim().equals("illum")){
mtlInfo.illum = Integer.parseInt(tempsa[1]);
}else if (tempsa[0].trim().equals("Kd")){
read(tempsa,mtlInfo.Kd);
}else if (tempsa[0].trim().equals("Ka")){
read(tempsa,mtlInfo.Ka);
}else if (tempsa[0].trim().equals("Ke")){
read(tempsa,mtlInfo.Ke);
}else if (tempsa[0].trim().equals("Ks")){
read(tempsa,mtlInfo.Ks);
}else if (tempsa[0].trim().equals("Ns")){
mtlInfo.Ns= Float.parseFloat(tempsa[1]);
}else if (tempsa[0].trim().equals("map_Kd")){
mtlInfo.map_Kd = tempsa[1];
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void read(String[] value, float[] array){
for (int i = 1; i < value.length; i++) {
array[i-1] = Float.parseFloat(value[i]);
}
}
网友评论