leezer3 / OpenBVE

OpenBVE- A free train simulator
http://www.openbve-project.net
275 stars 52 forks source link

IndexOutofBoundsException when loading a Wavefront object #560

Open zbx1425 opened 3 years ago

zbx1425 commented 3 years ago

Description

I just decided to test out the wavefront object parser. I tried it on a very simple object, and it failed to load.

Reproduction

A dummy test model. holder.zip

Debugging

It seems that some MeshFaces in the object claims they have material id 4, while there are only 4 materials in the array of the Mesh, thus causing this exception. The object itself only have 1 single material.

Logs

12:37:27  Plugin Object.Wavefront.dll raised the following exception at LoadObject:索引超出了数组界限。
12:37:27  No plugin found that is capable of loading object F:\Program Files (x86)\openBVE\UserData\LegacyContent\Railway\Object\zbx1425\holder.obj

Related information

Windows 10 2004

leezer3 commented 3 years ago

I think the build from today will fix this, issue with the original wavefront parser only. Assimp works OK with your test object.

Note that the scale is completely out of wack. Will think about handling that, as sketchup imported models are going to be quite common & it states the scale in the file, but I don't think obj has a native specified method of defining a scale, just extensions....

There's always something that's not quiten expected.....

leezer3 commented 3 years ago

Scale handling added too. https://vps.bvecornwall.co.uk/OpenBVE/Builds/OpenBVE-2020-11-28.zip

From the looks of things, there are some other funky scaled files, but I need actual examples of these to play with if they come up.

zbx1425 commented 3 years ago

Assimp seems more stable when parsing OBJ and X objects. Should I prefer using Assimp? But Assimp is not selected by default, is it because compatibility issues, or cross-platform problems?

zbx1425 commented 3 years ago

Have not tried the latest build yet, but another problem is that IndexOutofBoundsException is thrown when the model is used in a route, while no exception showed in ObjectViewer.

zbx1425 commented 3 years ago

No, definitely not working at all. Tested the latest nightly build. this model still does not load in both ObjectViewer and the main program. IndexOutofBoundsException was thrown.

Error           Plugin Object.Wavefront.dll raised the following exception at LoadObject:索引超出了数组界限。
Error           No plugin found that is capable of loading object F:\Program Files (x86)\openBVE\UserData\LegacyContent\Railway\Object\zbx1425\holder.obj
Critical        Unhandled error (未将对象引用设置到对象的实例。) encountered while processing the file F:\Program Files (x86)\openBVE\UserData\LegacyContent\Railway\Object\zbx1425\holder.obj.
leezer3 commented 3 years ago

nobug Definitely works here, just tried it with a freshly downloaded copy of the build from today.

(Note that your object at correct scale is now too small to see without considerable zooming in)

Are you trying to load it via an animated file or something more unusual?

zbx1425 commented 3 years ago

Oops. Tested again, it works on both 12-02 and 12-05. Thanks! Maybe last time I accidentally started 11-08 or 1.7.2.1 while thought I used 12-02, probably because I clicked on the wrong folder 🤣


Another problem is that Sketchup objects with textures, when imported, gets their V coords inverted. It seems that the OBJ format does not specify how the coord system should be, so... should we add an Sketchup-specific hack for this?


There is a weird texture difference when a model is loaded with Assimp parser. Original: (V inverted for the aforementioned reason) image Assimp: image Model used to reproduce this issue: mudu.zip Note that some faces are also inverted. This is because the author of the model has little experience in modelling, and Sketchup always shows both sides of a face, so he wasn't aware of getting the faces in the wrong direction while modelling. Maybe a hack can be considered to make all faces bidirectional for Sketchup objects, so the objects' appearance will be identical in OpenBVE and Sketchup (seems a bit too violent/overkilling though)

leezer3 commented 3 years ago

Interesting. I think assimp must be applying unwanted alpha from that pic.

leezer3 commented 3 years ago

https://stackoverflow.com/questions/5585368/problems-using-wavefront-objs-texture-coordinates-in-android-opengl-es/5605027#5605027

Inverting the texture co-ordinates may well be right for all files, but I need to try a few more samples. (I'm sure I tested it as OK when I built the thing first with a relatively complex house though.....)

zbx1425 commented 3 years ago

Unfortunately I also got little (and some conflicting) info about it from Google. As for the modelling software that I knowed about, Sketchup has the origin at bottom-left by default and cannot be changed, while Metasequoia has it at top-left by default but can flip it if chosen in export settings. So it seems that the origin is highly implemention-specific, and inverting the coordinates will surely break many models, as there are also (perhaps lots of) softwares that take top-left as origin by default.

Perhaps we can test out the behavior of other softwares such as 3DMax, Blender or Maya. On the other hand, if we cannot get a definite solution, then making it an Sketchup-specific hack (by checking the comment at the top of the file) (for its large user base) for now might be a considerable idea.

leezer3 commented 3 years ago

Fixed the transparency issue, and added a Sketchup specific hack for the minute.

If using anything exported from Sketchup, I'd suggest the new renderer. Those files are a mess internally.

zbx1425 commented 3 years ago

Another problem is that the X axis in Sketchup objects are reversed. Parsed: image Intended: image Maybe this also requires a Skechup specific hack.

zbx1425 commented 3 years ago

Yet another problem is about the MTL parser

And some other problems about the OBJ parser


https://github.com/leezer3/OpenBVE/blob/63b809a990d7f34a46c65039f454259616935b01/source/Plugins/Object.Wavefront/Parsers/WavefrontObjParser.cs#L449 According to Wikipedia:

Materials can be transparent. This is referred to as being dissolved. Unlike real transparency, the result does not depend upon the thickness of the object. A value of 1.0 for "d" is the default and means fully opaque, as does a value of 0.0 for "Tr". Dissolve works on all illumination models.

# some implementations use 'd'
d 0.9
# others use 'Tr' (inverted: Tr = 1 - d)
Tr 0.1

I think the current handling did exactly the opposite. Materials with the d 1.0 instruction are treated as completely transparent instead of completely opaque, which causes many faces to disappear in some models.

leezer3 commented 3 years ago

I get the horrible suspicion that we're heading into implementation specific territory again with the d value.

Will add tr, and see what I can do with assimp.

Reversing the X coords is heading into somewhat dangerous territory, much more so than playing with texture mapping. Will think about that one a bit.

zbx1425 commented 3 years ago

I did more research on how Sketchup handles axis. It turned out that it uses a left-handed coordinate system, in contrast to OpenGL.

It does have a Axis Tool that allows you to set the axis directions to whatever you want, but it seems the output is always left-handed (in the way of X+ to the right, Y+ to the top, Z+ to the front) no matter how the axes are played around inside sketchup.

Reversing the Z axis seems to work correctly, at least for the Sketchup 2019 installation at my place, and all Sketchup models I have on my computer. Model positions as well as the axes' positive directions are correct. (I originally thought it was about the X axis, but it turned out the Z axis needs to be reversed)


"d" is for "dissolve", and "Tr" is for "transparent", so I think there should be less ambiguity going around it? At least wikipedia doesn't say it's implemention specific.


By the way, it would be of great convenience if the "Grid" function in the object viewer can show which direction is the positive direction of each axis. For example, Sketchup shows the positive half of an axis as a solid line, and the negative half as a dotted line.

zbx1425 commented 3 years ago

Correction. Sketchup uses a right-handed coordinate system (Z out), instead of the Direct3D left-handed coordinate system (Z in) that BVE is using. So I think flipping the Z axis should fix the difference for Sketchup.