Пример #1
0
 /** Initializes a new OBJ Object with the given filename. */
 public PShapeOBJ(PApplet parent, String filename) {
   this(parent, parent.createReader(filename), getBasePath(parent, filename));
 }
Пример #2
0
  protected static void parseOBJ(
      PApplet parent,
      String path,
      BufferedReader reader,
      ArrayList<OBJFace> faces,
      ArrayList<OBJMaterial> materials,
      ArrayList<PVector> coords,
      ArrayList<PVector> normals,
      ArrayList<PVector> texcoords) {
    Map<String, Integer> mtlTable = new HashMap<String, Integer>();
    int mtlIdxCur = -1;
    boolean readv, readvn, readvt;
    try {

      readv = readvn = readvt = false;
      String line;
      String gname = "object";
      while ((line = reader.readLine()) != null) {
        // Parse the line.
        line = line.trim();
        if (line.equals("") || line.indexOf('#') == 0) {
          // Empty line of comment, ignore line
          continue;
        }

        // The below patch/hack comes from Carlos Tomas Marti and is a
        // fix for single backslashes in Rhino obj files

        // BEGINNING OF RHINO OBJ FILES HACK
        // Statements can be broken in multiple lines using '\' at the
        // end of a line.
        // In regular expressions, the backslash is also an escape
        // character.
        // The regular expression \\ matches a single backslash. This
        // regular expression as a Java string, becomes "\\\\".
        // That's right: 4 backslashes to match a single one.
        while (line.contains("\\")) {
          line = line.split("\\\\")[0];
          final String s = reader.readLine();
          if (s != null) line += s;
        }
        // END OF RHINO OBJ FILES HACK

        String[] parts = line.split("\\s+");
        // if not a blank line, process the line.
        if (parts.length > 0) {
          if (parts[0].equals("v")) {
            // vertex
            PVector tempv =
                new PVector(
                    Float.valueOf(parts[1]).floatValue(),
                    Float.valueOf(parts[2]).floatValue(),
                    Float.valueOf(parts[3]).floatValue());
            coords.add(tempv);
            readv = true;
          } else if (parts[0].equals("vn")) {
            // normal
            PVector tempn =
                new PVector(
                    Float.valueOf(parts[1]).floatValue(),
                    Float.valueOf(parts[2]).floatValue(),
                    Float.valueOf(parts[3]).floatValue());
            normals.add(tempn);
            readvn = true;
          } else if (parts[0].equals("vt")) {
            // uv, inverting v to take into account Processing's inverted Y axis
            // with respect to OpenGL.
            PVector tempv =
                new PVector(
                    Float.valueOf(parts[1]).floatValue(), 1 - Float.valueOf(parts[2]).floatValue());
            texcoords.add(tempv);
            readvt = true;
          } else if (parts[0].equals("o")) {
            // Object name is ignored, for now.
          } else if (parts[0].equals("mtllib")) {
            if (parts[1] != null) {
              String fn = parts[1];
              if (fn.indexOf(File.separator) == -1 && !path.equals("")) {
                // Relative file name, adding the base path.
                fn = path + File.separator + fn;
              }
              BufferedReader mreader = parent.createReader(fn);
              if (mreader != null) {
                parseMTL(parent, path, mreader, materials, mtlTable);
                mreader.close();
              }
            }
          } else if (parts[0].equals("g")) {
            gname = 1 < parts.length ? parts[1] : "";
          } else if (parts[0].equals("usemtl")) {
            // Getting index of current active material (will be applied on
            // all subsequent faces).
            if (parts[1] != null) {
              String mtlname = parts[1];
              if (mtlTable.containsKey(mtlname)) {
                Integer tempInt = mtlTable.get(mtlname);
                mtlIdxCur = tempInt.intValue();
              } else {
                mtlIdxCur = -1;
              }
            }
          } else if (parts[0].equals("f")) {
            // Face setting
            OBJFace face = new OBJFace();
            face.matIdx = mtlIdxCur;
            face.name = gname;

            for (int i = 1; i < parts.length; i++) {
              String seg = parts[i];

              if (seg.indexOf("/") > 0) {
                String[] forder = seg.split("/");

                if (forder.length > 2) {
                  // Getting vertex and texture and normal indexes.
                  if (forder[0].length() > 0 && readv) {
                    face.vertIdx.add(Integer.valueOf(forder[0]));
                  }

                  if (forder[1].length() > 0 && readvt) {
                    face.texIdx.add(Integer.valueOf(forder[1]));
                  }

                  if (forder[2].length() > 0 && readvn) {
                    face.normIdx.add(Integer.valueOf(forder[2]));
                  }
                } else if (forder.length > 1) {
                  // Getting vertex and texture/normal indexes.
                  if (forder[0].length() > 0 && readv) {
                    face.vertIdx.add(Integer.valueOf(forder[0]));
                  }

                  if (forder[1].length() > 0) {
                    if (readvt) {
                      face.texIdx.add(Integer.valueOf(forder[1]));
                    } else if (readvn) {
                      face.normIdx.add(Integer.valueOf(forder[1]));
                    }
                  }

                } else if (forder.length > 0) {
                  // Getting vertex index only.
                  if (forder[0].length() > 0 && readv) {
                    face.vertIdx.add(Integer.valueOf(forder[0]));
                  }
                }
              } else {
                // Getting vertex index only.
                if (seg.length() > 0 && readv) {
                  face.vertIdx.add(Integer.valueOf(seg));
                }
              }
            }

            faces.add(face);
          }
        }
      }

      if (materials.size() == 0) {
        // No materials definition so far. Adding one default material.
        OBJMaterial defMtl = new OBJMaterial();
        materials.add(defMtl);
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }