Has anyone managed to successfully load and display textured .OBJ models using Android Processing?

edited January 2017 in Android Mode

I'd appreciate any good tips on how to do this with existing .OBJ model with associated .MTL and image texture files

Tagged:

Answers

  • I have done it before with a provided example. However I am not sure if it works for all the designated OBJ objects. It depends on how your OBJ object was generated as there are multiple programs capable in doing that. First, try using the java mode and see if it works.

    Here is a sample code.

    Kf

    PShape sh;
    int r, y;
    float scaleFactor = .04;
    
    void setup() {
      size(600,400, P3D);
      orientation(PORTRAIT);
    
      noStroke();
    
      sh = loadShape("file.obj");  
      y = height;
    }
    
    void draw() {
      background(0);
      lights();  //(2)
    
      translate(width/2, y);  //(3)
      scale(scaleFactor);  //(4)
      rotateX(PI);  //(5)
      rotateY(radians(r));  //(6)
    
      shape(sh);  //(7)
    }
    
    
    void mouseDragged()  //(9)
    {
      if (abs(mouseX - pmouseX) < 50) 
        r += mouseX - pmouseX;
      if (abs(mouseY - pmouseY) < 50) 
        y += mouseY - pmouseY;
    }
    
  • edited January 2017

    Kf, Thanks for sharing your code. I tried it with a .OBJ and the .MTL and .jpg files in the data folder. The only thing I modified in the code was the file and scale factor.

    In Java mode, everything works as expected and I can see the 3D model with the correct texture applied. In Android mode, the 3D model renders correctly, but with no texture, just gray model.

    I also tried the example in Processing under Files>Examples>Shape>LoadDisplayOBJ, and I get the same results: works great in Java mode (with all the rocket texture). In Android mode: gray model only.

    I wonder if .MTL and/or texture files are not supported in Android mode. Is it necessary to somehow load the .MTL and .jpg files for Android to properly use them?

    Thanks,

  • Unfortunately this is as much as I know about these files. I will try to run the examples to confirm your results from provided examples. I will let other forum goers with more experience comment about proper approaches or further details about this operation of loading obj files.

    Kf

  • Hi, MTL loading in version 3.0.x of the mode is broken. The next version will include a fix, but until it becomes available you can try out this temporary workaround: copy the mtl and texture files from the assets to the location returned by sketchFile() (the mode is trying to load them from the latter, instead from the assets, which is the correct thing to do).

    The LoadDisplayOBJ built-in example could read something like this after applying the workaround:

    import java.io.FileOutputStream;
    
    PShape rocket;
    float ry;
    
    public void setup() {
      size(640, 360, P3D);
      orientation(LANDSCAPE);
    
      try {  
        InputStream mtlAsset = getActivity().getAssets().open("rocket.mtl");
        InputStream texAsset = getActivity().getAssets().open("rocket.png");
        File mtlFile = new File(getFile("rocket.mtl"));
        File texFile = new File(getFile("rocket.png"));
        copyAssetToFile(mtlAsset, mtlFile);
        copyAssetToFile(texAsset, texFile);
      } catch (IOException ex) {
        throw new RuntimeException(ex);
      }
    
      rocket = loadShape("rocket.obj");
    }
    
    public void draw() {
      background(0);
      lights();
    
      translate(width/2, height/2 + 100, -200);
      rotateZ(PI);
      rotateY(ry);
      shape(rocket);
    
      ry += 0.02;
    }
    
    String getFile(String filename) {
      File file = sketchFile(filename);    
      return file.getAbsolutePath();    
    }
    
    void copyAssetToFile(InputStream asset, File file) {
      if (!file.exists()) try {
        int size = asset.available();
        byte[] buffer = new byte[size];
        asset.read(buffer);
        asset.close();
    
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(buffer);
        fos.close();
      } catch (Exception e) { 
        throw new RuntimeException(e); 
      }
    }
    

    I hope this helps.

  • Thanks Kf for your help.

    codeanticode: Thanks for providing the workaround code. I gave it a try and got the error 'The function "getActivity()" does not exist'. I am running Processing 3.2.3. Do I need a different version or to do an import? Thanks,

  • ok, if you are using version 3.0.2 of the mode (the one available through the CM) then getActivity() should work. With the beta releases (the ones that support wallpapers, watch faces, etc) you need to call surface.getActivity().

  • edited January 2017

    Great. I used version 3.0.2 and it worked. Thank you very much!

  • @MMIX2009 So yes, I confirm running Files>Examples>Shape>LoadDisplayOBJ works in java but same problem in android as you reported. Solution by @codeanticode did the trick. Thanks for sharing the solution.

    @MMIX2009 Can I ask you what is your source of OBJ files? Or how do you usually generate yours?

    Kf

  • edited January 2017

    @Kf: I used the files from a few Processing examples. If you're looking for other .OBJ files with associated assets to try against the code, here is a source I found: http://www.turbosquid.com/Search/3D-Models/free/obj

  • If anyone is interested, I added a function for @codeanticode's working sample sketch above. This allows loading several .OBJ, .MTL, and texture image files using calls to loadAsset(String str, String img), where str is the .MTL and img is the texture image file (.png, .jpg, etc.) instead of writing the try/catch block for each .OBJ model. For example, I will call loadAsset("rocket.mtl","rocket.png");right before rocket = loadShape("rocket.obj");

    void loadAsset(String str, String img) {
    
      try {  
        InputStream mtlAsset = getActivity().getAssets().open(str);
        InputStream texAsset = getActivity().getAssets().open(img);
        File mtlFile = new File(getFile(str));
        File texFile = new File(getFile(img));
        copyAssetToFile(mtlAsset, mtlFile);
        copyAssetToFile(texAsset, texFile);
      } 
      catch (IOException ex) {
        throw new RuntimeException(ex);
      }
    }
    
Sign In or Register to comment.