News:

Simutrans.com Portal
Our Simutrans site. You can find everything about Simutrans from here.

Bridge graphics

Started by jamespetts, January 01, 2015, 11:29:10 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jamespetts

(I hope, incidentally, that this is the correct board on which to put code queries: I put it here because the "help centre" is more for game play queries, and the answer to my queries should at least count as code documentation).

I am looking into separating bridges and tunnels from their underlying ways. Looking at the code, it seems as though this is less difficult than it might first have appeared, as there is already a partial separation between the "tunnelboden" and "brueckenboden" (that is, the tunnel and bridge "grounds") and the way that stands atop them in the code, but this difference is suppressed in a few places. One of the most important places is in wegbauer.cc:


            // bridges/tunnels have their own track type and must not upgrade
            if(gr->get_typ()==grund_t::brueckenboden  ||  gr->get_typ()==grund_t::tunnelboden) {
                continue;
            }


Commenting this out allows building of a new way over the bridge. There will also be places that set the speed and weight limits based on the bridge rather than the way itself, and I should be able to find these easily and change them. I will also need to find a way of making the way remover remove the underlying way without removing the bridge/tunnel itself, as, without doing that, it is not possible to build a way of one type over a bridge initially built for another type.

The graphics code, however, I know rather less about. What I do infer is that it is possible in the existing code to display a way over an existing bridge, as this is already done in preview mode when a way is dragged over a bridge. However, again, the display of the underlying way type is evidently suppressed by the code. (This is not so in tunnels, where the underlying way type is shown in underground mode, although it does seem to apply for tunnel portals). Does anyone have any idea in the code where this suppression of the underlying way graphic is located? I have hardly touched the graphics code (apart from the UI) since I first started working on Experimental, concentrating instead on game mechanics, so any pointers would be greatly appreciated.

Elevated ways look as though they may be more of a problem, as there is no way/bridge separation there already in the code. Any thoughts on how best to deal with this would be appreciated (including whether there would be any pitfalls in attempting to make elevated ways more like bridges in this regard).

Incidentally, I did suggest this improvement to Markhos in his "bored programmer" thread as he has already started on a bridge related project. If he is reading this and has decided to work on this feature for Standard, I should be grateful if he could let me know so that we do not have two incompatible ways of doing the same thing (and I can only imagine that Markhos's code would be more robust than mine in any event).
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

Another complication is that the graphics doesn't distinguish between the way and the rest of the bridge structure either, which mean that either compatibility with existing pak files are broken, or there must be a relatively huge amount of code duplication to handle both cases. That won't make this code any easier to understand.

jamespetts

Quote from: Ters on January 01, 2015, 12:35:56 PM
Another complication is that the graphics doesn't distinguish between the way and the rest of the bridge structure either, which mean that either compatibility with existing pak files are broken, or there must be a relatively huge amount of code duplication to handle both cases. That won't make this code any easier to understand.

Where in the code does this lack of distinction occur?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

Quote from: jamespetts on January 01, 2015, 12:37:42 PM
Where in the code does this lack of distinction occur?

I said it was the graphics, not the code, although it applies to both.

jamespetts

#4
Quote from: Ters on January 01, 2015, 01:03:53 PM
I said it was the graphics, not the code, although it applies to both.

Ohh, I see: yes, I am aware of that, although I had rather hoped that it would be possible in the code simply to overlay the way graphic upon the appropriate part of the bridge graphic, which I hope will be relatively straightforward since exactly this is already done when previewing dragging a way over a bridge.

Edit: I have managed to find part of the answer in weg_t::calc_bild:


    else if(  from->ist_tunnel() &&  from->ist_karten_boden()  &&  (grund_t::underground_mode==grund_t::ugm_none || (grund_t::underground_mode==grund_t::ugm_level && from->get_hoehe()<grund_t::underground_level))  ) {
        // in tunnel mouth, no underground mode
        set_bild(IMG_LEER);
        set_after_bild(IMG_LEER);
    }
    else if(  from->ist_bruecke()  &&  from->obj_bei(0)==this  ) {
        // first way on a bridge (bruecke_t will set the image)
#ifdef MULTI_THREAD
        pthread_mutex_unlock( &weg_calc_bild_mutex );
#endif
        return;
    }


Commenting out the bridge section allows a way graphic to be overlaid over the bridge graphic, although there are two problems with this so far: the first is that the back image of the bridge's rear wall disappears and the second is that there always seems to be one tile on the bridge where the overlay does not work.

Commenting out the tunnel section does not work quite as well as, not only do the ways not overlay the bases of the portals, but they appear against the land behind the portal. This is potentially a harder problem to solve as the clipping code for this does not appear to exist: this exact same graphical anomaly can be seen if one drags a way through a tunnel already.

Edit 2: Even more oddly, the above effect appears to apply to road and canal but not railway bridges. I suspect that what is happening is that the various calc_bild() methods (on the bridge and on the underlying way) are just competing to put a pointer to an image in a single slot which is then red by obj_t::display, rather than there being a system for obj_t::display to render the bridge background image then to render the way image, then to render the bridge foreground image (which is presumably in fact what happens with the way preview when a way is dragged over a bridge). Can anyone confirm whether this is correct?

Edit 3: Yes, it appears that the above was correct: the behaviour is for bridges not to have their own background image (though they have their own foreground image), but to use the way's background image, and return a blank image when the get_bild() method is called. By giving the bridges their own images separately stored from the ways, I am able to overlay a way over a bridge image and display both at once. Unfortunately, the bridge image is drawn on top of the way image rather than the other way around, with the result that the way image is obscured by the bridge's built in way image unless I compile a special bridge graphic with transparency where the way should go (although it is difficult to get the borders clean). This is one way of doing it, but it would be preferable to overlay the way over the bridge graphic to avoid having to redo all of the bridge graphics. Does anyone have any idea how I might be able to alter the sequence in which the objects are inserted into the tile such as to reverse the order of display?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

I was not, and still am not, sure whether it is the ground or the way that is the visible bridge today.

jamespetts

#6
It's the way. It's an odd setup.

However, moving further onwards, another difficulty emerges if I were to use the transparent bridge graphic method. Slope tiles involving sloping ground set the way to appear on the lower, rather than the higher, level. This does not show with the normal graphics because this image is disabled and overwritten with the bridge image. However, when I enable separate way and bridge graphics, this is shown in the incorrect position. I do not understand the graphics system well enough to know how to set this image to the correct position (I cannot see anything for adjusting an image in the z dimension), so any assistance would be appreciated.

Edit: The above problem appears to be solved by setting:

weg0->set_yoff(-gr->get_weg_yoff() );

Where "slope" is a non-NULL value. This works rather nicely in the transparent graphics model. The transparent graphics model does have the downside that it needs graphics redrawing and that tram tracks on old, non-transparent bridge graphics do not show properly. I have not, however, been able to get the overlay model working.

There still remains the issue as to clipping the ways underneath tunnel portals. I do not know where to begin in terms of altering the clipping code. One possibility the circumvent this is to have a special way image for tunnel entry, and just be the graphic showing the way beneath the tunnel: this could be set relatively easily in the code instead of the normal way image, and would resolve the clipping issue, in effect, by having it pre-done manually in the graphics. This would be time consuming to implement in the pakset, however.

Any views on how to deal with these issues would be welcome.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

I have very much given up the relationship between world and graphics in Simutrans. The way it's done might very well have been the best way to get enough performance out of it, at least back when Simutrans was born, but it's become almost impossible to work with. To really meet the wanted features of today, one would have to delete simgraph, remove every image_id field, remove all display and calc_bild member functions, and just write the rendering anew from the ground up.

jamespetts

Quote from: Ters on January 01, 2015, 10:10:25 PM
I have very much given up the relationship between world and graphics in Simutrans. The way it's done might very well have been the best way to get enough performance out of it, at least back when Simutrans was born, but it's become almost impossible to work with. To really meet the wanted features of today, one would have to delete simgraph, remove every image_id field, remove all display and calc_bild member functions, and just write the rendering anew from the ground up.

I shan't be doing any of that - but I am making slow progress with the separation of bridges and ways.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

kierongreen

Just a comment on bridges - these should have a speed and weight limits of their own, with vehicle speed and weight limits being the lower of way and bridge limits in both cases. In the 19th century you should have a choice between making short and long term choices between wooden and brick bridges for example.

jamespetts

#10
Quote from: kierongreen on January 01, 2015, 10:23:54 PM
Just a comment on bridges - these should have a speed and weight limits of their own, with vehicle speed and weight limits being the lower of way and bridge limits in both cases. In the 19th century you should have a choice between making short and long term choices between wooden and brick bridges for example.

Yes, that is more or less what I am doing (working on the speed limits now), save that the way weight limit is an axle load limit, whereas the bridge weight limit is a convoy weight limit.

A slightly trickier thing is the aqueduct, where it should not be possible to upgrade the way from, say, a tub boat aqueduct to a ship canal aqueduct. Perhaps it will suffice merely to set the most restrictive weight, speed and way constraints, although attempting to upgrade will make the graphics look very silly. Perhaps bridges should have a setting to indicate whether they should display the way graphic on top of them or not?

Edit: Hmm - a bit of trouble with the speed limits: I cannot find how to access a pointer to the bridge (so that I can get to its besch) from weg_t::set_besch.  Does anyone have an idea how to get a pointer to a bridge from a ground tile?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

kierongreen

To get ground tile an object (including a way) is on try
grund_t *planquadrat_t::get_boden_von_obj(obj_t *obj) const

To get a bridge object that is on a ground tile you can use
bruecke_t *bridge = gr->find<bruecke_t>();

jamespetts

Excellent! Thank you, that works perfectly. I do wonder whether some of the code that I am writing for this might be useful in Standard, too, as I think that there has been a demand for this from Standard as well as Experimental players, and most of my changes (except those relating to axle loads and bridge weight limits, as well as way constraints) are not specific to Experimental. Have a look at the way-wear branch on my Github repository to see the progress so far (I still have some work to do with tunnels, and elevated ways will need a different approach entirely which may well be less suitable for Standard, although it is a great shame that we have the bridge/elevated way dichotomy in the first place).

Incidentally, I have found an easy and effective way to neutralise the way part of the bridge images in Pak128.Britain using the "wizard " select function in the GIMP and calibrating it for saturation (this worked well with the cobblestone road which was grey, but it may work less well for other roads or railways).
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

kierongreen

When this topic came up before there were issues about different bridges having different methods of tracklaying on them. Ways on top of a brick viaduct may well have the same ballast as those on the ground, but a timber trestle bridge will likely just have the rails directly secured to the structure. With careful use of masking in bridge images this should work, as you can ensure that only way rails are visible for example. Your point about the elevated way/bridge dichotomy is well made, indeed when making changes to bridges thought should be given into seeing if the two can be combined. I had previously thought about bridges having an couple of extra flags to indicate constraints that would apply to bridges:
can change height
allow junctions/curves

bridge start/end tiles would be as present, but for bridges that allowed height changes and/or junctions and curves intermediate tiles would be enhanced versions of elevated ways which would have graphics to allow taller piers to cope with varying ground heights. For bridges which were only straight then there would be the option of multiple graphical tiles along that straight, this would for example allow more realistic suspension bridges.

As long as it doesn't over complicate construction I think it stands a reasonable chance of making it into Standard. I think it would be best though if all the bridge changes were made at once in time for the next big release.

jamespetts

Thank you for your thoughts: this is an interesting subject indeed. Combining bridges and elevated ways strikes me as both potentially very difficult and potentially very rewarding. Weighing the cost in time against the reward is not easy since the former is hard to assess (and the latter would lead to some saving in time, which is easier but still not entirely straightforward to assess). Can you give me some idea as to the nature of the changes that would have to be made to the bridge code in order to accommodate level changes and junctions?

Other difficulties might include stacking and treatment of historic elevated ways from old saved games, as well as interpreting historic paksets which have elevated ways rather than bridges defined (and what about monorails and some maglevs where the normal way type is elevated)? Any thoughts on these issues would be appreciated.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

The Hood

Would it not be possible to simply define bridges as elevated ways - bridges are essentially straight elevated ways after all. Bridges could be converted to elevated ways on loading from old saves. The only change would be pillars - I think at present elevated ways must be only single height above ground but if you had a system (like in locomotion / roller coaster tycoon) where you built ways at a given level and the pillars were just added to the right height automatically below, that would do the job better? No idea how that works code-wise however...

jamespetts

The trouble is that elevated ways, unlike bridges, do not have a separate way that can be laid upon them: they are all one thing. I have managed to make it possible to change the way over a bridge without changing the bridge itself, which is a significant advance, but this cannot be done with elevated ways (at least, not without drastically changing them to make them almost identical to bridges, except for the height changes, junctions and stacking, which is more or less what Kieron was suggesting).
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Ters

Elevated ways can also only be one level high, and so need short bridges to reach ground level except at cliffs. Combining the two might still be a good idea, but involves turning bridges and elevated ways into something new, not turning on into the other.

jamespetts

Quote from: Ters on January 02, 2015, 12:57:43 PM
Elevated ways can also only be one level high, and so need short bridges to reach ground level except at cliffs. Combining the two might still be a good idea, but involves turning bridges and elevated ways into something new, not turning on into the other.

That sounds complicated.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

kierongreen

Bridges, like tunnels are not intrinsically tied to being level and straight. The difference between the two is that tunnels only have images defined for entrances, whereas bridges also have images defined for intermediate tiles. Originally tunnels had no need for any intermediate tiles as there was no underground mode, and when this was introduced then plain way images were used, later to be replaced by tunnel way images. The two types, tunnels and tunnel ways are constructed using the same icon.

One option is for bridges and elevated ways to remain distinct in terms of objects, but to link the two together just as for tunnels. This means an xref from the bridge to an associated elevated way. There is the issue you point out about elevated ways not having separate way and bridge components is valid though. An alternative would be to convert elevated ways into separate ways and bridge objects on loading (bridges being extended to provide necessary objects). How you'd find the correct objects to convert the elevated way into is another matter....

Yes it might be complicated but it's better to bite the bullet now and have one coherent set of changes to bridges that have been properly planned, rather than several successive changes which may or may not lead to the desired goal. This is particularly true when changes might require redrawing bridges for example.

jamespetts

#20
This is a somewhat complex subject. On the one hand, the needs of Experimental and Standard are different in some respects (I am embarking upon this project because separating the bridges and tunnels from the underlying ways is important for the new feature currently in progress of having ways wear out and need to be replaced). On the other hand, there is much benefit for the separation for Standard, too, and it has been discussed for a time. If I were successfully able to implement this in Experimental, much of the code would be able relatively easily to be able to be backported to Standard. That would have the particular advantage that it would not be necessary to have different pakset graphics between Experimental and Standard.

The unhelpful bridge/elevated way dichotomy makes things more difficult. It would be useful to overcome it somehow (my initial idea was to use the upgrade group/way only cost system that I had initially planned for bridges and tunnels before discovering that separating them from their underlying way was not only more satisfactory but also actually easier). However, if there is a sensible way of doing this by combining bridges/elevated ways into a single, better, type of bridge, then that would be even better. However, I should probably have difficulty undertaking a task of quite this scale alone, as this would require changes much more fundamental than those that I have so far made (I have only been able to go as far as I have because the underlying separation of bridges and ways was already present in the code, but not fully used).

In the circumstances, may I request some collaboration on this part of the task? Whether it is done by first backporting that work that I have done into Standard and then working on that before I extract the relevant parts of the code to Experimental again, or whether all the work is done first in Experimental and then the relevant parts extracted to Standard is a matter for discussion, but, much as I see the benefit in what Kieron suggests, I can only imagine that I should struggle to implement this fundamental a change to parts of the code of which I have a limited understanding alone.

Edit: Also, I am having some difficulty finding any way of allowing a way of one type over a bridge to be replaced with a way of another type, as the way building tool will refuse to find a route over tiles with another way on them, and I cannot find the specific piece of code that tells so to refuse.

Edit 2: Given that it seems unlikely that it will be possible to merge bridges and elevated ways soon, I have implemented the (rather simple) upgrade group and way only cost system, which is useful for elevated ways, but conceivably might have other uses. The system is very straightforward: for any given way, there is an "upgrade group" and a "way only cost". If these are not defined in the .dat file, they are assumed to be zero and the same as the normal cost respectively. Whenever a player upgrades a way with another way, if the upgrade group of both ways is the same, the way only cost is charged instead of the normal cost. This allows elevated ways to be upgraded with other elevated ways that differ only by the surface rather than the structure.

Edit 3: I have now finished at least an initial implementation of this, which is on the way-improvements branch of my Github repository. I have not been able to merge elevated ways and bridges, but have at least introduced the group upgrade cost system described above. The separation of ways and bridges seems to work quite well, although tram tracks over old style bridges are not properly shown, and some canal bridges have artefacts on the towpath that I do not fully understand given that the underlying way is set not to be drawn when the bridge does not have has_own_way=0 in the .dat file. I have not done anything with tunnel portals: one simple option might be just to depict the entry way in shadow, although I do not know whether that works with the shading directions.

I have begun to convert the Pak128.Britain bridges to the new system, focussing first on the brick arch viaduct bridges, and have been able to rationalise considerably so far, removing the need for separate graphics for road and rail bridge for the snow type, and having only one bridge each for road and rail for the non snow type. The narrow gauge implementation of the bridge unfortunately has a transparent gulley along one side where the track is too narrow to cover the expanse of the bridge: it will probably be necessary to have a separate narrow gauge version of the bridge. I have yet to attempt the more complex bridges, so may yet happen upon unforeseen pitfalls, but can always fall back to the old system of letting the bridge provide the way graphic (as will be necessary for the wooden trestle road bridge with its wooden surface).

It is quite a happy thing for the same bridge built in different eras automatically to have different road/track on it, and this really does seem to enhance the game, especially as it will now be so much easier to balance bridges and tunnels.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.