Use the "Forum Search"
It may help you to find anything in the forum ;).

front / back images for roadsigns

Started by THLeaderH, October 31, 2021, 09:23:31 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


This is a request for a new feature in simutrans. We discussed this topic 4 years ago, but at that time, the implementation was uncompleted because the specifications expanded so much.
Updating an old thread is generally not recommended as an our forum rule, so this time, I resubmit the patch and want to focus on the front / back image feature itself. The other requirements such as slope and diagonal images should be discussed in another thread, since considering about them later does not do harm in the implementations.

I want to support front / back images for roadsigns. The dat format for images should be similar to the definition in ways and wayobjs.

In the current simutrans, roadsigns does not support front images. Front / back of the images is switched according to the direction of the roadsign. This works well for pole shape roadsigns, but does not work for arch shape roadsigns.

These roadsigns should be drawn like below.

EDIT: This section is obsolete. Please see,21202.msg197771.html#msg197771

The dat of a roadsign should be like this.

Icon=> foo.0.2

"Image[X]" represents back images and "frontImage[X]" represents front images.
To preserve the conventional behavior, a roadsign without frontImage should behave in the conventional way, that means the front/back is automatically set. For the case that the all images should be in background, `no_foreground` parameter should be set to 1 like below. This parameter have an effect only when foreground images are not specified and the default value is 0. In case that front images are specified, all `Image`s is treated as background images regardless of the direction.


A makeobj update is required. This feature should not affect the drawing of conventional roadsigns.

In the thread of four years ago, there were some additional requirements for road sign images. The unimplemented requirements for road sign images are categorized into these four items.

1. front / back images
2. diagonal images
3. slope images
4. images with snow

I asked some Japanese add-on authors which features are needed, and they answered that front/back and diagonal images are strongly needed, while slope and snow images are not so much needed. This topic board should concentrate on front/back images, so maybe I'll post the patch to support diagonal images as another topic.

I will submit the implementation later.


So what is with switching images according to drive_on_left? SO there should be a no change on left_side_driving or so.
And instead of number, having image[N] Image W E NW SW NE SE be more decriptive for the makers. This will also makes clear that these are new indended this way, even without a frontimage.


Sorry for not mentioning the behavior with drive_on_left and that is the biggest problem for this feature.
For arch shape signs which this feature want to support, the conventional image offset approach does not work. One of the simplest approach is just not switching images according to drive_on_left or signal_on_left if front images are defined. Currently, most of Japanese roadsign addons (even pole shape signs) set offset_left=0 thus not shifting images is reasonable to some extent.

Of course, this approach ruins the benefit of drive_to_left and signal_on_left feature and I want to make arch shape roadsigns usable both on right-hand driving and left-hand driving. To do this, I am thinking to shift and invert images. I will update when I come up with a good image transformation logic.


Perhaps for arch shaped signs it would be best to have two sets of images - drive on right (front/back) and drive on left (front/back). Even for simple pole signs, the left_offset is quite rough method, and the sign should be positioned carefully to look good on both sides.


That could be done when using symbols instead numbers for images (Like Nl and Nr and so on). But I think for now a "no_left_swapping=1" flag might be enough.


"no_left_swapping=1" seems to be unneccesary because "offset_left=0" brings the same effect. Is it right?


It still swaps the back and frontimage, I think. However, it is a long time since I touched that part of the code.


Sorry for late reply.
IMO, when front images are defined, there is no meaning in swapping front and back images when drive_on_left is enabled. Image position shift can be preserved, but swapping front and back does not solve any problems. Thus, I think there should be no image swapping when front images are defined.

I thought about generating road sign images for left-side driving from the images for right-side driving, but at least, it needs to specify the axis position to turn over the images and there is no guarantee that it works well. There seems to be no significant difference in he effort to make a road sign addon between generating a separated road sign for left-side driving, so for now, for arch shape road signs, I think it's enough to make a separated version of road sign for left-side driving.


I have looked again into the current code a little more. You can make a bridge sign like this using the current code by cutting it and distribute the halves into the forward and backward directions (see attached images/dat/png). This will break on slopes, but also your roadsign above will not work on slopes either. And of course it will not work for choose signs, since one has to swap the indicator directions.

And indeed there is no need for swapping when front and backimage is defined for an arch sign. However, a private road sign using a traffic light (which is currently handled as a hack) could under the new system swap front and back image to go from left hand to right hand driving.

If going for full flexibility, one may need something like

Which comes close to what directional wayobj needs (especially if there is provision to handle crossings as well). Of course directional wayobj is a completely different topic.


Imho, it would be very welcome to have a patch that brings proper front/back images like for way-objects + plus the distinction left/right hand traffic. Then artists would have full control for image placement. Of course, we would need some compatibility code for existing objects, which could be moved to the object reader.
Parsley, sage, rosemary, and maggikraut.


I finally understood why we can achieve an arch shape road sign with front/back images with the current code! We can make it by making it a bi-directional road sign. I thought that arch shape road signs had to be one way signs because SIS, an infrastructure addon serires that is popular in Japan, implemented these signs as one way signs. However, in the most cases, the main purpose of these arch shape road sign is just a decoration, and the signs can be bi-directional.

Yes, with the current code, a road sign has to be bi-directional to use front/back images and that is same for railway signals. There is a railway signal addon that draws mechanical box for the safety system together with the signal pole, and that needs front/back images. I cannot immediately find the signal addon itself for now, but I'm asking the author to provide the example.

Anyway, we can make road sign addons with front/back images by making the sign bi-directional, but one way road signs including choose signs and railway signals cannot use front/back image. This time, I want to give addon authors full flexibility for images.

For traffic lights, direction letters like "EN" and "NE" properly represents the image for right side driving and left side driving. However, for normal road signs and railway signals, should direction letters be "RE" and "LE", that means the image toward east in right side driving, and the image toward east in left side driving?


I thought arch signs when using NE and EN for forward and backward directions will not be easily compatible with left side driving. Thus some explicit "driving_side=left|right|both|mirror" For only available in the menu with the right driving direction, and only mirror (with the given offset) when "mirror"

EDIT: I found some fragments of a patch when trying to introduce directional wayobj. There I thought about frontdiagonal[] and backdiagonal[].


`driving_side` parameter seems to be good for arch shape signs, but we do not have a good algorithm for image mirroring, so `driving_side` should be {left|right|both} and that should be enough.
So, let's fix the image definition syntax with it.
At first, I thought to replace current `image[0]` syntax with `image[N]` because we will support diagonal and slope images, but this approarch is not suitable for railway signals because railway signals have images not only for direction but also for state, such as red and green state and images for non-electrified truck. So I think we should continue using number to specify the images for road signs and railway signals.
It seems that diagonal and slope images can be defined by `Diagonal[0]` and `ImageUp[0]` syntax. We'll have a discussion about the syntax for diagonal and slope images in another thread and we can concentrate only on normal images this time.

We have to consider about two cases depending on whether the sign has separated front and back images or not.

Case 1: Signs or signals that have only one image for each direction and state
The dat definition should be like this.

Icon=> ...

In this case, front / back of images is set by the system depending on the direction and left side driving setting. Although almost all parameters work as the conventional spec, `driving_side` is added and the default value is `both`, and that brings the conventional behavior. When `driving_side=right`, the sign or signal is available only for right side driving. When `driving_side=left`, the sign or signal is available only for left side driving.

Case 2: Signs or signals that have front and back image for each direction and state
The dat definition should be like this.

Icon=> ...

In this case, image front/back swapping and position shifting does not occur for drive_on_left because current image shifting algorithm is for pole shape signs and is not suitable for arch shape signs. Therefore, the following parameters do nothing.
- offset_left
- no_foreground
When `driving_side=both`, exactly same images are shown for both right side driving and left side driving. When `driving_side=right`, the sign or signal is available only for right side driving. When `driving_side=left`, the sign or signal is available only for left side driving.


I think in regards to traffic lights and signals, rather (front)image[NE][0...3] for states 0..3 would be the best syntax for graphic guys. This makes the position very clear, and you still have the second number for state, eletrification etc.

This requires old signs to change the source code for new makeobj, but this should not be a problem. The whole image number system is a hack, and adding foreground images to this just makes it an even larger hack.


Quote from: prissi on November 14, 2021, 12:59:19 PM
I think in regards to traffic lights and signals, rather (front)image[NE][0...3] for states 0..3 would be the best syntax for graphic guys. This makes the position very clear, and you still have the second number for state, eletrification etc.

This requires old signs to change the source code for new makeobj, but this should not be a problem. The whole image number system is a hack, and adding foreground images to this just makes it an even larger hack.
I like this definition syntax renewal and I made a topic for it.,21217.0.html

Since the definition of front / back images needs only `front` and `back` prefixes for each image definition syntax, the implementation of front / back images and that of image definition syntax renewal are independent to some extent. Although we cannot implement them simultaneously, which we implement first is not a huge problem because the implementation of front / back images just uses the pursing logic for the image definitions with the prefix.

Therefore, I want to implement front / back images for a road sign first, then start the implementation of the image definition syntax renewal. We can discuss about the new image definition syntax while I implement the logic for front / back images.


I implemented this feature. Please download the diff file from the link below.

The diff can be seen on a browser from the following link.


I would like to avoid making display virtual, since it was avoided historically for performance reasons. There are routines instead to draw outline images. (Of course, if you wanted to draw two images then it would need to change.)

One can of course change things. But then one would need to change all display routines using outlines to do those themselves because inconsistent handling of similar things should be really avoided.


So do you mean that we should put the second back image id variable and the drawing routine in obj_t?
The outline drawing routine is used by many kinds of objects, so the outline drawing routine should be obj_t as it is. However, a road sign is the only object that needs two layer drawing routine for background and foreground, thus I think that two layer drawing routine should be in roadsign_t rather than in obj_t.

I'm sorry for not knowing the virtual function performance problem well. I have heard that the call of virtual functions is much slower than non-virtual functions, but this is only for function call. I think there is not so much impact on the entire display() function process because this function is not so small.


I am confused. Why are there two back- or frontimages needed, if the traffic lights are not touched? One front and one back should be enough for every case apart from traffic lights.

I admid, it is a little hard to follow everything without any comments.


Quote from: prissi on November 22, 2021, 11:56:34 AM
I am confused. Why are there two back- or frontimages needed, if the traffic lights are not touched? One front and one back should be enough for every case apart from traffic lights.

A road sign with `single_way=0` which is connected to north and south direction needs to draw the image of north and south at once. This means that the sign needs to draw the front north image, front south image, back north image, and back south image. Two layers for front and back images are needed for this situation.

The same problem happens for railway signals, and that is more inevitable. A railway signal where the way is connected to north and south direction switches its connected direction north / south / north+south by clicking. We should define the front and back images for each direction, and for north+south connection, we have to draw the front and back images of north and south direction.

As for the current implementation, a traffic light also supports front and back images. I did so simply because there is a little difficulty to do this, but I can remove this if it should not be included.


The performance of the virtual calls is not an issue anymore: there are the calls for transparent color and image-id in display() as well.

Now I understood why you want two images. But using the old N and S images for a NS sign does not make sense in the new system, it would be just another hack. Only directional images would give the full flexibility, i.e. image[N], image, image[NS]. (One would need a fallback for the drawing of old pak files anyway, but those are single fore and background anyway.)



IMO, using north image and south image for "north and south" connection status is not a hack but a natural and reasonable approach for railway signals.

If we really want to avoid the two layer drawing routine while supporting front and back images, we may have to make the following changes to the current spec.
- Road traffic lights do not support front and back images.
- The direction of images for a bi-directional road sign should be {NS|EW}, not {N|S|E|W}.
- The direction of images for a single way road sign should be {N|S|E|W}.
- When a railway signal has front and back images, the signal should have images for {N|S|E|W|NE|NW|SE|SW|NS|EW} directions.


I am not fully opposed. I just wonder, if you have a signal with front and backimages for both directions, two signalsbridge (or sign bridges) will look strange so close together and one maybe rather a single bridge in the middle with both signals on either side. However, there is no signal yet to do this, so it is purely theoretic. Also traffic light with front and backimage sounds good, so lets change display to virtual. (But the code needs more comments ... )

Moreover, since drawing trees is the more common task, using an own streamlines display() routine may make some sense too, performancewise.

If one draws both N and S backimages and frontimages for double way signs, this may not be the results the artist actually aimed for, like a bridge sign in the current system. Insofar, enforcing image[NS] and EW for double way signs makes some sense. I have not looked into makeobj on how easy it would to enforce.


Actually I want to enforce image[NS] and so on. This gives addon authors more flexibility and we can avoid implementing two layer drawing routine. Two layer drawing routine is theoretically not neccesary for supporting front and back images. So let's add some more image definitons and use the existing drawing routine.

The additional directions should be required only for the signs with front and back images. Signs with single layer images should require the same variety of images.

This makes the image definition completely different from the conventional one. Also, since we add some more directions, the syntax renewal must be done before we continue the implementation. So, I make this project pending once, and let's complete the image definition syntax renewal first.


NS and EW images may need some special handling on slopes (i.e. should they go on the middle of the slope?) There seems really a lot of challenges hidden here when one tries to do things properly.


There should be extra graphics possible for diagonals.

This doesn't look fine:
Remember the signal can stand at the left or right tile of the diagonals.