美文网首页
(三)obj文件和mtl文件读取

(三)obj文件和mtl文件读取

作者: SunnyDay_ab5f | 来源:发表于2019-11-25 15:43 被阅读0次

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]);
        }
    }

相关文章

网友评论

      本文标题:(三)obj文件和mtl文件读取

      本文链接:https://www.haomeiwen.com/subject/jmpdyctx.html