leezer3 / OpenBVE

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

Improve support for textual X objects #87

Closed marcriera closed 6 years ago

marcriera commented 8 years ago

OpenBVE already supports textual X objects using templates, which enables compatibility with BVE5 X objects. While most converted objects work, X objects designed from scratch have some variations which prevent them from being loaded correctly.

The issue comes up when an X object defines names for meshes and materials, and then makes references to them using that name. I am attaching two objects to show you the difference (they are part of the Fuji line for BVE5).

BG.zip

BG04 is loaded correctly by OpenBVE, because the materials are defined inside the 'Mesh' template. In BG05, however, the materials are defined outside of the mesh and then referenced using a name. The rest of the content is the same you would find in a 'normal' X object. It is a bit difficult to explain here, but it will be clear if you compare the files.

leezer3 commented 8 years ago

The names for meshes and materials aren't actually a particularly big deal.

There are some rather more interesting issues involved in this file it's use of array separators is rather inconsistent.

First, take the a quick sample from the array declared for the mesh:

Mesh mesh_0{
70;
-424.2636;235.6190;-424.2637;,
-299.9998;-78.5398;-519.6151;,

You'll note that it's using the semicolon as the argument separator, and the comma as the member separator.

Now the texture co-ords array:

  MeshTextureCoords {
70;
-3.7500,-2.0000;

Here, it's using the comma as the argument separator and the semicolon as the member separator. There's a bunch of other somewhat related issues too, associated with characters not being in the position they're expected to be.

It wouldn't be a big deal if the whole file was consistant, but it's not.....

leezer3 commented 8 years ago

Getting somewhere; I've decided the easiest way to do this, is just to run a preprocessing loop to set the line endings to those which we understand.

This is the current loop:

            for (int i = 0; i < Lines.Length; i++)
            {
                if (i == 36)
                {
                    int t = i;
                }
                string[] splitLine = Lines[i].Split(',');
                if (splitLine.Length == 2 && splitLine[1].Trim().Length > 0)
                {
                    if (!splitLine[1].EndsWith(";"))
                    {
                        splitLine[1] = splitLine[1] + ";";
                    }
                    else
                    {
                        splitLine[1] = splitLine[1] + ",";
                    }
                    Lines[i] = splitLine[0] + ';' + splitLine[1];
                }
                else if (((splitLine.Length >= 4 && Lines[i].EndsWith(",")) || (splitLine.Length >= 3 && Lines[i].EndsWith(";;") && !Lines[i-1].EndsWith(";,")) || (splitLine.Length >= 3 && Lines[i].EndsWith(";") && Lines[i-1].Length > 5 && Lines[i-1].EndsWith(";"))) && !splitLine[splitLine.Length - 2].EndsWith(";") && Lines[i -1].Length > 5)
                {
                    Lines[i - 1] = Lines[i - 1].Substring(0, Lines[i - 1].Length - 1) + ";,";
                }

                if ((Lines[i].IndexOf('}') != -1 || Lines[i].IndexOf('{') != -1) && Lines[i - 1].EndsWith(";,"))
                {
                    Lines[i - 1] = Lines[i - 1].Substring(0, Lines[i - 1].Length - 2) + ";;";
                }

            }

Please excuse the rather oversized if conditions.....

This then works if I manually insert the materials in the expected place. Still thinking about the best way to sort out getting them into the material list, but I think this can probably be done in the current function somewhere.

leezer3 commented 8 years ago

I think I've got it. https://github.com/leezer3/OpenBVE/tree/AlternateX

Supports a maximum of 6 declared textures per mesh, which I think ought to be enough.

I've checked this for reversions on everything I've got floating around, but I don't want to merge this into anywhere until it's been a little more tested.... Possibly should have based off the BVE5 branch, but if these check out OK, I'll just create a new commit on that one rather than merging this.

leezer3 commented 8 years ago

Arrgh.... I think I must have broken something whilst merging into the main program.

Will take a closer look tonight, but I'm afraid that the above commit is actually broken....

leezer3 commented 8 years ago

OK, trying again! Now supports any number of strings, and generally works a little better.

A secondary problem: If a texture is not found, BVE5 would appear to try all potential formats, and pick any available texture which matches the filename. I don't like this at all......

Only way I can think of of handling it remotely well is to only attempt this when loading BVE5 routes directly from in-game (And possibly routeviewer, but even that isn't something I like at all) Thoughts?

Edit: I also note that a couple of the Fuji files refer to TGA textures. Have you seen any routes which actually use TGA files? https://github.com/leezer3/OpenBVE/pull/59 Licencing on that pull is somewhat unclear hence why it's not merged though. Almost wants a non-free plugins download.....

marcriera commented 8 years ago

Trying all potential formats is a very dirty trick, I do not like how BVE5 is sometimes extremely permissive (this is important enough to show a warning). I know it may break some content, but I would skip this (no good developer would be that irresponsible).

I am unable to find any TGA textures in the BVE5 I have (not even in the Fuji files), and the BVE5 documentation says only BMP and PNG images are supported. However, adding TGA support would be interesting, of course. The problem is, as you say, licensing. There should be a way to support it without breaking anything, but I have no clue either...