Search Unity

ObjReader - load .obj files at runtime

Discussion in 'Assets and Asset Store' started by Eric5h5, May 7, 2013.

  1. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    This has been around a while, but I didn't have a separate topic for it. Version 2.0 is out now! ObjReader loads arbitrary .obj files at runtime...great for modding and other user-created content. It works on all platforms, and with all languages. Includes source code. Available on my site and the Unity asset store.



    Yes, the ridiculously-overdue version 2.0 is out, with MTL support. Feature highlights:

    • Loads .obj files at runtime with a high degree of compatibility, quickly.
    • Can load .mtl files to use for materials, including texture loading (png and jpg format only).
    • Support for transparent and opaque materials.
    • Can override ambient, diffuse, and specular colors from the .mtl file with your own material.
    • Can have different groups in the same .obj file be separate GameObjects, or combined into one.
    • If combined into one GameObject, different groups can be submeshes or not.
    • Can compute tangents for use with bumpmapped shaders.
    • Can use supplied normals from the .obj file, or have them computed.
    • Can apply arbitrary scaling, rotation, and position to the imported mesh.
    There are two functions, ConvertString and ConvertFile. With ConvertString, you can provide strings for the .obj and .mtl files that you can load from arbitrary sources, including the web. With ConvertFile, you provide a complete file path, and ObjReader will load that, and optionally look for the appropriate .mtl and texture files. Note that ConvertFile won't work in a webplayer due to Unity restrictions on accessing external files.

    If you have any questions, find any bugs, or have any feature suggestions, post them here. If you bought from my site and don't have the latest version (currently 2.0), send me a PM with the address you used when buying. Update notices are sent out automatically for new versions, but you need to make sure you opt in to that (if you don't, then I can't send any update notices to you), and you might also want to check your spam folder.

    --Eric
     
    Gozdek likes this.
  2. Tripwire

    Tripwire

    Joined:
    Oct 12, 2010
    Posts:
    442
    Hi,

    I'd like to buy this asset but i have some questions:

    1. Is this asset compatible with Android
    2. Is the loading time faster then Resources.load()?

    We are using resources.load now but on Android it takes way too long to load the 3D model.

    Thx!
     
  3. jc_lvngstn

    jc_lvngstn

    Joined:
    Jul 19, 2006
    Posts:
    1,508
    Thanks, this is a great asset.
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I haven't tested it personally, but it works on iOS so there's no reason it wouldn't work on Android.

    Resources.Load is very fast since it's stored in native format and requires no conversion. I don't think you're having issues with Resources.Load per se; probably it's something else like applying a mesh collider.

    Thank you!

    --Eric
     
  5. Tripwire

    Tripwire

    Joined:
    Oct 12, 2010
    Posts:
    442
    I think the problem is that the model is around 18MB, which is a bit big for mobile.
     
  6. SevenBits

    SevenBits

    Joined:
    Dec 26, 2011
    Posts:
    1,953
  7. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    there is compiled dll :( will not work on some platforms, can you include source code?
     
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Managed dll files work on all platforms.
     
  9. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    Managed dll files will not work on all platforms, not work on flash for example,
     
    Last edited: Jul 8, 2013
  10. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    If all operations in the dll are supported by Unity's flash platform, it will work. But as its api is far from complete, you are right and it is likely that it doesn't work.
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    All of my utilities include source code; the description on the asset store specifically mentions this. If the DLL doesn't work in Flash then I don't think the source code would either, but Unity Flash publishing is discontinued anyway so it's not really feasible to provide support for it.

    --Eric
     
  12. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    Thanks for reply,
    why there is dll then? does source code of this dll included?

    if not, i can't modify or extend it, and if there any bugs i can't fix them
     
  13. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    As I already stated (and as the Asset Store description says), the source code is included. The DLL is also included for convenience; you use one other the other.

    --Eric
     
    twobob likes this.
  14. JAvaHell

    JAvaHell

    Joined:
    Jul 5, 2013
    Posts:
    4
    Hi~ I’m korean develoment for android unity3d wpf

    It is very interesting to me, this is an asset.

    Want to ask you a few questions to apologize

    1. Web Player platform support available?

    2. Do you require Unity Pro Version?

    3. Animation, texture features, such as methane real support?

    4. It is availabel that load .FBX object at runtime?

    If possible, try to buy the contents of the above idea.

    Have a nice day~
     
  15. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    1. It will work in a webplayer, although loading .obj files from a website currently doesn't automatically load .mtl files. (Edit: it does now.)
    2. No.
    3. The .obj format doesn't support animation. I was not able to understand the rest of this question.
    4. Only .obj files are supported.

    --Eric
     
  16. GiantGrey

    GiantGrey

    Joined:
    Jul 2, 2012
    Posts:
    268
    yesss! finally .mtl support!! thank you! :)
     
  17. JAvaHell

    JAvaHell

    Joined:
    Jul 5, 2013
    Posts:
    4
    Thank's for your answer!!

    The reason for the question of my third, because it import to the fbx object.
     
  18. ModSimTeam

    ModSimTeam

    Joined:
    Sep 9, 2012
    Posts:
    7
    We just purchased from the Asset Store. Seems too work great and we like the ease of use. We tried importing an obj with multiple textures (three) and the importer seems to only import the first texture. We are exporting out of Blender 3D. Should the importer work with models using more than one texture? If so, Are there particular setting that we should be using during export?

    Our .mtl file seems to be pointing to the correct textures. The .mtl file is as follows:

    Code (csharp):
    1.  
    2. # Blender MTL File: 'None'
    3. # Material Count: 3
    4.  
    5. newmtl Material
    6. Ns 96.078431
    7. Ka 0.000000 0.000000 0.000000
    8. Kd 0.640000 0.640000 0.640000
    9. Ks 0.500000 0.500000 0.500000
    10. Ni 1.000000
    11. d 1.000000
    12. illum 2
    13. map_Kd IMG_4071.JPG
    14.  
    15. newmtl Material.001
    16. Ns 96.078431
    17. Ka 0.000000 0.000000 0.000000
    18. Kd 0.640000 0.640000 0.640000
    19. Ks 0.500000 0.500000 0.500000
    20. Ni 1.000000
    21. d 1.000000
    22. illum 2
    23. map_Kd SH.jpg
    24.  
    25. newmtl Material.002
    26. Ns 96.078431
    27. Ka 0.000000 0.000000 0.000000
    28. Kd 0.640000 0.640000 0.640000
    29. Ks 0.500000 0.500000 0.500000
    30. Ni 1.000000
    31. d 1.000000
    32. illum 2
    33. map_Kd Image_2.jpg
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The importer works with multiple textures. Are you using "combine multiple groups"? If so, you'd need to also use "use submeshes when combining" in order to have multiple textures. Otherwise the first material would be used for the entire object.

    --Eric
     
  20. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Version 2.1 is out now; buyers from my website with update notifications turned on will have gotten an email, and I'll be uploading it to the Asset Store next. Updated stuff:

    Additions:
    • ConvertFileAsync function, which automatically loads OBJ files from the internet, including MTL and texture files where appropriate. This includes a progress variable for the entire combined download. It's also possible to download multiple OBJ files simultaneously.

    Changes:
    • Changed group detection, so more OBJ files are imported correctly (specifically, OBJ files generated by Sketchup, which are kind of weird, and possibly others).
    • A few speedups, so OBJ parsing is ~10% faster.
    • Better handling for files that aren't actually OBJ files.

    Fixes:
    • Lines that start with whitespace are parsed correctly.

    --Eric
     
  21. stevenapolo7

    stevenapolo7

    Joined:
    Aug 15, 2012
    Posts:
    24
    Hi, i just bought it but im not good with coding so i need some help: First question, how can i load an obj from a local directory? second, is possible to load the obj via file browser, i mean press a gui button and explore into my files and select the one i want to load? Thanks!
     
  22. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The "Example3" demo shows how to load from a local folder, the relevant lines being:

    Code (csharp):
    1. objFileName = Application.dataPath + "/ObjReader/Sample Files/" + objFileName;
    2. ObjReader.use.ConvertFile (objFileName, true, standardMaterial, transparentMaterial);
    You can load via a file browser if you have one that works in a build, such as UniFileBrowser. In this case you'd use the OpenFileWindow function in UFB (you can use filtering so only .obj files show up), and then use the resulting path in the ObjReader.ConvertFile function.

    --Eric
     
  23. Ghetz

    Ghetz

    Joined:
    Sep 25, 2013
    Posts:
    5
    I am trying to load obj files at runtime in the web player and for almost a month now, no success. It won't even load a cube!
    The obj files and the cross domain.xml file are even in the same folder as the webplayer on the server.

    I have used the example for loading from url provided, and still no success.

    Maybe Eric5h5 could advise what I am doing wrong.

    Ghetz
     
  24. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The WWW example works great in a web browser, as you can tell from making a build with the default url (the .obj on my site). I would guess your crossdomain.xml file is wrong, however internet/website access issues are way out of my control and I can't really do anything about them I'm afraid.

    --Eric
     
  25. dolaniyan

    dolaniyan

    Joined:
    Sep 8, 2013
    Posts:
    2
    Hi Eric5h5, I also bought the ObjReader about a month ago and I have been having problems loading obj files on the web player. It works fine on Unity but once I run it in a browser, it doesn't work. I have added the crossdomain.xml to my server and I have also run your samples just like you said. It only loads in Unity, once I run it in the browser, it doesn't work. It also works fine when deployed on android but the webplayer seems to be the problem. I tried loading in the obj file as text using WWW class but even the ConvertString() method doesn't work on the webplayer too. I am using Unity version 4.2.1f4. Thanks for you quick anticipated response.

    David.
     
  26. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    What happens if you make a webplayer build from the Example2-WWW demo, as-is? (As in, not changing the URL or anything, so it loads from my website.) It works fine here.

    --Eric
     
  27. dolaniyan

    dolaniyan

    Joined:
    Sep 8, 2013
    Posts:
    2
    H Eric, I have tried loading your sample as-is but it doesn't work too. Are you testing your webplayer builds from within Unity or in a web browser? I can view the 3D model when I build as web player within the Unity interface but when I build and run in a web browser such as Chrome or IE, it doesn't display the model. What version of Unity are you running. Do you have any idea why this is happening?

    Thanks,

    David.
     
  28. Ghetz

    Ghetz

    Joined:
    Sep 25, 2013
    Posts:
    5
    Hi Eric, ObjReader now loads excellently in the web player. You were right - the problem was with my website. Many thanks, it is a brilliant piece of code. The textures are not loading but I will try and sort that out, as I think the problem may be due to the texture paths in the mtl file. One question though, how can I alter the imported OBJ's position and rotation in the script that calls ObjReader?
     
  29. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It works in the editor and any platform I build to, including the web player, on any version of Unity as long as it's 3.4 or later. I can only guess it's some kind of network issue. Here's a web build on my site.

    Assuming you mean you want to alter the vertices in the imported .obj, then probably the simplest way is:

    Code (csharp):
    1. var objReader = FindObjectOfType(ObjReader);
    2. objReader.objRotation = Vector3(something);
    3. objReader.objPosition = Vector3(something);
    Otherwise you can change the position/rotation of the imported GameObject using the Transform as usual.

    --Eric
     
  30. ZAAK

    ZAAK

    Joined:
    Oct 27, 2013
    Posts:
    8
    Hi Eric

    I've bought your script to load OBJ models at runtime on iOS devices, either from StreamingAssets/Resources or the Web later on. - If I try to load the Car_obj from your example on the iPad, the object turns all pink... while it gets loaded just fine in the Unity editor with all the materials. - On the other hand, the pig model works on the iPad, although it uses only solid colored materials as well... - Is there any way to fix that somehow?
     
  31. augmob

    augmob

    Joined:
    Jan 14, 2014
    Posts:
    2
    Hi Eric,

    1. Will the plugin work for iOS and Android? I am in search for a plugin that can load 3D models from a web url. The plugin should work on both iOS and Android.

    2. How can I load a model that is having multiple textures?


    Thanks,
    BP
     
  32. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yes.

    It's automatic; if the model has multiple textures then it will create submeshes as needed.

    --Eric
     
  33. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    Do imported groups receive their own local origin for rotations, rather than the global origin?
     
  34. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    ObjReader assumes that (0, 0, 0) is the center since there is no pivot point feature of .obj files. So, rotation is basically global.

    --Eric
     
  35. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    So in other words, articulated bodies (vehicles, characters) can't be rigged, or at least out-of-the-box?
     
  36. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, the .obj format isn't suitable for animation at all.

    --Eric
     
  37. Ghetz

    Ghetz

    Joined:
    Sep 25, 2013
    Posts:
    5
    Hi Eric

    Can you help with a c# equivalent? Many thanks.
     
  38. Ghetz

    Ghetz

    Joined:
    Sep 25, 2013
    Posts:
    5
    I meant a c# equivalent of:

    var objReader = FindObjectOfType(ObjReader);
    objReader.objRotation = Vector3(something);
    objReader.objPosition = Vector3(something);
     
  39. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    var objReader = FindObjectOfType(typeof(ObjReader)) as ObjReader;
    objReader.objRotation = new Vector3(something);

    --Eric
     
  40. Ghetz

    Ghetz

    Joined:
    Sep 25, 2013
    Posts:
    5
    Thanks Eric,

    I was leaving out the "as ObjReader" part and running into all sort of problems. Still learning c#, will get there one day.

    Cheers
     
  41. gheeler

    gheeler

    Joined:
    Nov 7, 2012
    Posts:
    18
    Have you any plans to support objects with more than 65000 verts like the way unity does in the editor?
     
  42. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Possibly, though not in the immediate future.

    --Eric
     
  43. m_bec

    m_bec

    Joined:
    Feb 3, 2014
    Posts:
    3
    How do I change the obj's name after it is loaded into the scene? For instance, in the first example scene, Car_obj has the name Essuies-glace in the hierarchy. Is there a way to change that dynamically?
     
  44. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You can change the gameObject.name as usual, using the GameObject array returned by ConvertFile.

    --Eric
     
  45. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    Hey Eric5h5,
    I'm unable to load my model.

    Here's what I'm using:
    objFileName = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)+"/PrintableObjects/SOAP_RAZOR_DISH.obj";
    ObjReader.use.ConvertFile (objFileName, false);

    Here's what is returned:

    Argument is out of range.
    Parameter name: index
    UnityEngine.Debug:Log(Object)
    ObjReader:CreateObjects(String, Boolean, Dictionary`2, Material, ObjData)
    ObjReader:Convert(String, String, Material, Material, String, Boolean)
    ObjReader:ConvertFile(String, Boolean, Material, Material, ObjData)
    ObjReader:ConvertFile(String, Boolean)
    $:MoveNext() (at Assets/ObjReader/Demo Scripts/Example3-ExternalFile.js:16)

    Any ideas?
     
  46. Batigol

    Batigol

    Joined:
    Oct 17, 2012
    Posts:
    234
    hi Eric5h5, do you think you will make fbxReader?
    so many people need it :)
     
  47. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Do you have a link to the .obj file? (If you don't want it public, send me a PM.)

    Probably not; it's complicated by the fact that there are both binary and text versions. I've seen other runtime FBX libraries available, so you could use those.

    --Eric
     
  48. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    ObjReader 2.2 is out now:

    Improvements:
    • Better error handling when loading WWW files.
    • Reduced memory usage and increased speed.
    • Better OBJ file compatibility, specifically with files generated by Meshlab.

    Fixes:
    • ConvertString works with MTL file strings in the webplayer.
    • Missing MTL files will still allow the object to be created (without any materials of course).

    --Eric
     
  49. pajamajama

    pajamajama

    Joined:
    Oct 22, 2012
    Posts:
    66
    Hey Eric,

    I am loading multiple files on start, so I use:

    objPath = "somepath"
    ObjReader.use.ConvertFileAsync (objPath, false)
    objPath = "newpath"
    ObjReader.use.ConvertFileAsync (objPath, false)
    //etc

    They all load fine. Awesome. However the names of the loaded gameobjects are some strange long descriptions that was most likely inside their .obj files. Because I wont know what these names will be at runtime, I have no way of accessing those gam objects to name them appropriately. Or do I?

    Here's what I need to do:
    1. on start: load all the obj files within a given folder (I'm able to do this now).
    2. change each gameobject's name to its file name (I can access the file name, just need to access the gameobject).
    3. parent each gameobject to the proper (each different) transform.

    It would be nice if I could store these gameobjects into different arrays somehow, since I will have multiple folders of obj files that will each serve different purposes. I noticed the async function has a gameobjects array but it returns null even if the objects load. Perhaps I'm using it incorrectly? Is there a reason why the non-async function does not have a gameobject array?

    Thank you,
    Pajama
     
  50. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The gameObjects array isn't null after the import is completed. e.g., "Debug.Log (objData.gameObjects[0].name)" will print the first name in the array, in the Example2-WWW script, if you put it at the end of the Load function. The non-async ConvertFile function returns a GameObject[] array which can be accessed as usual.

    --Eric