Twinklebear / tobj

Tiny OBJ Loader in Rust
MIT License
233 stars 47 forks source link

Does not load material files with spaces in the name correctly #63

Closed AHL00 closed 5 months ago

AHL00 commented 6 months ago

If a material file has a space in the name, only the first word in the name is passed to the material_loader closure.

joshlengel commented 5 months ago

Can confirm this issue as well. Just opened a pull request for a fix.

joshlengel commented 5 months ago

After doing some digging in the specification for the obj format I discovered that mtllib accepts a space separated list of filenames. As such, any filenames containing spaces are actually invalid according to the spec. The parser is, in it's current state, unable to handle multiple filenames.

My suggestion would be to either

  1. ignore the specification and just parse the argument as one filename, thereby allowing filenames with spaces. Seeing as most exporters don't export multiple mtl files but do include spaces this would actually improve the reliability of the parser at the cost of not being compliant.
  2. properly parse the list of filenames and make the parser compliant.

I'd leave it up to the maintainers to choose which option is better. Either way, a fix is warranted.

Hope this helps :)

Twinklebear commented 5 months ago

Interesting, I just checked out https://paulbourke.net/dataformats/obj/ myself:

mtllib filename1 filename2 . . .

    Polygonal and free-form geometry statement.

    Specifies the material library file for the material definitions
    set with the usemtl statement. You can specify multiple filenames
    with mtllib. If multiple filenames are specified, the first file
    listed is searched first for the material definition, the second
    file is searched next, and so on.

    When you assign a material library using the Model program, only
    one map library per .obj file is allowed. You can assign multiple
    libraries using a text editor.

    filename is the name of the library file that defines the
    materials.  There is no default.

I've never run into mtllib used in this way, to list multiple files. I just did a test in Blender of exporting an OBJ file with spaces in the name to see what it does in that case, and it exports an mtllib entry with spaces (so technically against the "spec", as much as obj has a "spec").

Here's that bit of the OBJ file, but you can also try for yourself:

# Blender 4.0.2
# www.blender.org
mtllib its got spaces.mtl
o Cube
etc...

I think assuming spaces can be in the filename is more common, and not that its a space separate list of names, so lets just go with supporting spaces in the file names (what Blender does).

I just was thinking about the usemtl if the material name can also have a space, but in that case Blender inserts underscores.

Twinklebear commented 5 months ago

Closed by #64