News:

Simutrans Forum Archive
A complete record of the old Simutrans Forum.

Network Diagram Tool Integration in Simutrans

Started by Fabio, January 31, 2011, 03:59:51 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Markohs

so the map is drawn each frame?

And yea, blending layers by fixed amounts is already possible using pix_blend75_15... etc

prissi

The lines need only be redrawn upon schedule_counter in welt is advanced. Otherwise not lines were changed for sure. Thus a slightly time consuming inital drawing routine is ok; as long as the points or whatever is cached.

yorkeiser

In the beginning I tried to put code inside calc_map(), but what I drawed from there was overwritten by the rest of the map (grass, seas, cities), so I temporarily moved it inside zeichnen(). Doing so, also allows me to test performances of the routine.
Of course I know it's not the ideal place to put this code because map viewer really doesn't need fast refresh, even if at the moment I didn't notice any performance issue (in fast forward mode I have the same speed factor than with other minimaps, also on quite complex maps).
I think in the final version we'd have to precalculate all coordinates, store them, draw stored coordinates and only at some large intervals (eg 30 seconds) or for some events happening, recalculate everything. No need to say, I have no idea how to achieve this refresh in simutrans architecture.

However, let's make things step by step: where do you think it would be the optimal place for the code that spools lines and calls graphic routines?
Is there any drawing routine that isn't called at every frame but has reference to minimap panel and is already used to draw on it?

EDIT: I read prissi's post. What if a schedule is only updated ? (e.g. adding a station to a schedule). Is there any event fired?

prissi

Since those "events" (increaseing schedule counter) are to notice the stations that the connections need updates, any relevant change (beyond waiting times) must give updates. In debug mode, you will see a star repc. a cross near the time acceleration indicator in the lower right.

yorkeiser

#74
Ok, I edit here to not post a new message. After further investigation, I noticed that it would be nice to put drawing code in calc_map(), that is called, as far as I can see, when you press a minimap button or change zoom level. But doing so I encountered a great problem:

all map modes implemented in calc_map() call set_relief_farbe_area() method, which draw on *relief. If I write on relief, in fact I have no overwrite issues.
The problem is that all graphic primitives I need are implemented in simgraph16.cc (display_direct_line(), display_pixel()...), and they write on *textur, not on *relief.
Now, if I call the primitives I need from calc_map(), they are drawn for a moment, then overwritten by *relief. If I skip relief drawing, lines are overwritten and nothing is plotted (the result is a totally green map). It seems that *relief masks *texture, on which rely graphic primitives.
In fact, as I can see, map modes that need to draw only full rectangles (calling set_relief_farbe_area) are in calc_map(), while map modes that need to draw single lines (as city limits mode) are in zeichnen(): it seems like program is not designed to call graphic primitives from calc_map().

Can anyone solve this, or at least explain me panel drawing pipeline, if I'm (probably) missing something?

Fabio

#75
Quote from: yorkeiser on April 12, 2012, 08:59:31 AM
Many thanks for your (wagon of) ideas, you're giving an enormous contribution to development and graphical improvement ;)

Well, I try to contribute as I can, I'm glad you value my suggestions. This tool might really add a lot to the gaming experience.


Quote from: yorkeiser on April 12, 2012, 08:59:31 AM
- I think actual line drawing of "show schedule" can surely be improved, but I also think this functionality is very useful in order to find a single line on map. Map viewer instead gives a "general" schema of the network, but can't actually help you finding single schedules on map. I think this feature surely deserves a deeper discussion involving also other users

I agree. We need a public debate about it, after this project is released.


Quote from: yorkeiser on April 12, 2012, 08:59:31 AM
- Do you mean I can add a toggle button (near "show schedule" etc...) to show/hide cities? If so, it could be a good idea, but we'd have to think how that new button behaves on other minimaps (cities, pax, stop status etc)


No, I mean to *remove* the existing Cities/Citta' button and add a *new* Show Cities toggle option, so that city names are shown/hidden no matter what other button is chosen (Map view, Tracks/binari, Speed limits/limiti velocita', cities, pax, stop status etc...)
We could do the same with City limits/Limiti citta'. Those two can be handy also when specific views are chosen, instead of being a view on their own.


Quote from: yorkeiser on April 12, 2012, 08:59:31 AM
- Circle drawing is slightly more expensive in cpu time than square drawing, and usually there are many stations on the map, so this can affect performance. Of course I admit that circles probably would give the map a better look

Not necessarily. Being so small, we don't need real circles, but pre-calculated pixel maps could suffice.
E.g.
Bus stops (3 px)
XXX
XXX
XXX


Rail Station (5 px)
XXX
XXXXX
XXXXX
XXXXX
XXX


Airports (7 px)
  XXX 
XXXXX
XXXXXXX
XXXXXXX
XXXXXXX
XXXXX
  XXX


I would also distinguish stops served by only one line from those served by multiple lines (hubs)

E.g.
Stop (1 line)
Hub (2 lines or more)
Bus/Tram/Monorail/Other
3 px
5 px
Railway/Maglev
5 px
7 px
Harbour
5 px
7 px
Airport
5 px
9 px

Airports could have an airplane icon near, harbours an anchor or a ship. Those symbols should be already present in GUI symbols, as they are used e.g. in schedule dialog.

Monorail lines (and stations) should use same style (for lines and stops) as trams; maglevs same as trains IMHO.




Another idea:
Colours would be nicer if persistent between sessions. Could each line object store its color? This way, colours would be assigned when creating/updating a line and the network morphology would be better analyzed in this moment instead of drawing time. It could also be possible for the player to customize a line color -- if wanted -- from line management dialog.

prissi

First the relief map is copied to screen. On that you can call whatever method you like in zeichnen. The reason is, that calculation the map means touching every tile which is very time consuming.

If you have a list of coordinates, then you could calculate those list only when needed, and then just draw them in zeichnen every time. That is fast enough imho.

yorkeiser

@prissi
ok, it's clear. So I'll initialize coordinates in some place and draw them in zeichnen. I think doing like this wouldn't cause performance trouble, due to the fact that there are no problems also now that coordinate calculus and drawing are both done in zeichnen.

@fabio
- about removing city button and replacing with a toggle button: I support this solution, but this is out of MapViewer's development scope. As a temporary alternative, maybe I could use actual behavior of other minimaps also for map viewer, that is showing city names only if CTRL is being pressed
- about circles: it's definitely a good idea and I'll work on it together with the implementation of airport/harbor symbols (they're all pre-calculated bitmap masks): I didn't think about using precalculated graphics, and instanly get afraid of perfomances issues a general circle routine could cause
- also hubs being greater based on lines entering in the station is definitely a very good idea. The problem is that I actually couldn't find in class haltestalle_t a method that returns the number of schedules to which a station belongs, so I actually I'm making distinction between greater/smaller stations based on line types served by that station (1 line type -> small station, 2 or more -> hub); train and airport stations are bigger than others. I agree with maglevs behaving like trains (I often ignore them because I use pak128 for development...), and also for trams/bus/monorail in the same category (local transportation). The number of optimal pixels (3,5,7 and so on...) is to be refined, I think the best way is to produce some screenshots with different solutions, show them, and then hear for others' opinions
- Persistence of line colors is not achievable as far as I know, unless we add color information to the schedule, and thus probably change savefile format (and I think this is far beyond objectives of this integration).  A simple hack could be to write a routine that associates line color (that is substantially a number) to some unchangeable feature of the schedule, as its internal id or maybe its name, that is not supposed to change often. By example: color = internal_id % max_colors_for_this_line_type.

prissi

I would suggest focussing on the actual line creating part. About triggering of recalculation and so on, you could leave this also to the dev team for the final integration.

Personally, before this gets to abstract, just post a patch. Others may then also improve it, so we can jointly work on it. IT is done also with many other patches.

Also please do not get overboard by side options. First the basic function as a patch, so we are sure this work is not lost and can be tested with many complex and simple maps. All the other goodies can be added later ...

For isntance, at a certain point I am sure we have to drop lines, which has stops too close to each other. And so on, and then the issue of making the lines more straight and so on.

yorkeiser

Quote from: prissi on April 13, 2012, 09:35:22 AM
I would suggest focussing on the actual line creating part. About triggering of recalculation and so on, you could leave this also to the dev team for the final integration.
Line creating part is quite simple, as I intended it: for every player - for every schedule - for every station in the schedule, draw lines between stations, draw station spots. My main adding was to add primitives to draw different line types (dotted, bezier curves).
The main part left to do is to store lines/stations infos in some structure rather than recalculating them at every frame, but if you agree I'd leave this task to development team, that know program's flow structure.

Quote from: prissi on April 13, 2012, 09:35:22 AM
Personally, before this gets to abstract, just post a patch. Others may then also improve it, so we can jointly work on it. IT is done also with many other patches
As I told some posts above, I work off svn (I can't access it due to my network limitations), so I don't know how to automatically produce a patch. However, my sources are quite independant from the rest of the program, so what I can do, is to post my added parts, and in which file they go (mainly some methods in simgraph16.cc, the simple code to add a button in minimap, and the main calculus/drawing routine in reliefkarte_t::zeichnen()). All my code is stand alone, it isn't mixed with actual sources for external integration purposes.

Quote from: prissi on April 13, 2012, 09:35:22 AM
Also please do not get overboard by side options. First the basic function as a patch, so we are sure this work is not lost and can be tested with many complex and simple maps. All the other goodies can be added later ...
Why are you afraid for work getting lost? I won't disappear, and however I think developers wouldn't loose too much time to re-do this work ;)
prissi, I never claimed to develop MapViewer by myself, it must be done by development team, I told it in the beginning of this thread. This thread/task was only born to see if integration was possible and its possible results/enhancements; let's say what I did is a preview of the official implementation. My main concerns were about performance and mainly how graphics could appear in a small 256 colors mini-map, rather than in a full screen, 32-bit colored application. So actual side options, as you called them, in my point of view are the main task of this thread: share ideas with others of how things could be done, code them to see their graphical result, hear judgement and new ideas, and restart. Otherwise, my task here is finished: from now, if you want real integration as I do, you (we) have to wait for someone in the development team to take charge of the real implementation, and I surely support this and am available to share code, ideas or anything you ask.

prissi

Just share the modified files then. I would be very interesting (and many other too I suppose) to test them over the weekend. If there is a concrete patch/implementation etc. it is much easier to discuss.

yorkeiser

Here are the files I modified.
For ease of read and use, I enclosed code added by me between lines:
//yorkeiser begin
//yorkeiser end

There's only a row I had to modify, it's after comment:
//yorkeiser inline

Code added is quite dirty, many lines are commented, variables declared where they wouldn't have, lacking optimization etc.. but I don't mind, it's not intended to be a release, only an idea of what can be done.

prissi

#82
This worked quite well. Just airlines tend to go into strange directions ... Thank you very much!

Attached at patch, that uses a slightly dimmed world map. But this view is currently VERY cpu consuming, from 12% CPU to 100% single core usage with developed maps ...

EDIT: not sure, this version here seems not so CPU hungry. Still investigating.

yorkeiser

Quote from: prissi on April 13, 2012, 10:49:44 PM
This worked quite well. Just airlines tend to go into strange directions ... Thank you very much!

I didn't notice strange behaviours, can you please post a screenshot so I can see if I have any idea of what happens? The only issue I know is that Bezier curves routine must be enhanced, because it actually draws starting and ending with fixed directions (beziers need a tangent direction where they start and one where they end - Cx, Cy, Dx and Dy parameters in draw_bezier()). But those directions wouldn't have to be fixed, they would have to be parameterized with the direction defined by starting point and ending point of the arc.

You're welcome, but you don't have to thank me: I had much fun from simutrans until its really early versions, so if I can even do the smallest thing to repay the community for their work and can help improving the game, I do it happily.

P.S. Even with the non-optimized version I didn't notice strange cpu overload: development was done on a normal 2.67 Ghz quadcore laptop, maps tested have  ~2000 vehicles, ~150 lines, pak128 open r1150.

prissi

Try this map (pak64 with food chain)
http://www.physik.tu-berlin.de/~prissi/simutrans/The%20World-V2-102-2.sve

All airlines have a kink near mUrmansk or the noth pole. (Might be due to cold war still in progress on this map ;) )

yorkeiser

I can't succeed loading that map on my development version, even importing last pak64 that works fine on latest nightly (r5636). However if you talk of "kinks" I suppose it just depends on that issue (but it really isn't an issue, the routine isn't complete yet) about tangents I told in the previous post. If you can post a screenshot, it would be helpful in order to investigate/replicate the issue on my test version (pak128).

P.S. Or maybe you simply have to provide a "War-free mode" in Simutrans ;)

prissi

You need to load pak64 with addons ...

Here is the screenshot.

yorkeiser

#87
Is there an all-inclusive download link for pak64+addons? I didn't find one on the forum, and since I don't follow pak64, I'd need a whole life to manually get the single add-ons, even if the problem is related to that and not to the version I use for debug, that I took from the aburch repository a month ago.

However, from what I can see from your screenshot, that is quite compressed, I only notice spikes in the north, and they're due to that problem of the beziers' tangent. Tangent is actually defined as (50,50), so it's a vector that points at South-East. In fact, all beziers (=airport lines) enter and exit from airport spots in south east direction, that is visually ugly. Entering/exiting directions would have to be parametric with the direction of the line, wouldn't have to be fixed as they actually are.
If there's another problem, I can't really see from the picture, maybe you can try to take a closest (more zoomed) screenshot and not compress it (save as .png). In the meanwhile, I'll try to get this savegame to work on my version.

P.S. This map is REALLY complex and there are MANY airlines, and bezier's drawing is slower than line drawing. Bezier curves actually are drawn as 32 segments polylines, I think that performance could be enhanced lowering this value to 8 or 16 segments, because every segment calculus involves some multiplications, as well as shifting.

P.P.S: World colors seem to me very nice, now it definitely looks very better than my version with white background

Randy007

@yorkeiser

realy,realy great job!!!
The only thing i am missing is the save as .pdf, so you can put it on a stick and go to a copyshop for a printout at DIN A3.
(gave them the small finger and they try to get the hole hand  ;) )

@prissi
Nice Map. But why you put Adler-Personenwagen to the trains to limit the speed to 50 km/h? Is the Trans-Sib realy that slow? Smolensk-Moskau is ~ 100 Km/h. And you have VT/VB98 running, but i can't find them in the depot  ???


prissi

#89
THis is the convoi replacer with stuff of vehciles not in production any more. This map is not from me, the original is on the old forum. It has several stuff missing, hence the random replacements.

EDIT: Version with very much cleaned up code. Using the control key, you can toggle between display by all colors or only line with player colros (most useful on servers). It will also ignore waypoints for line display.


yorkeiser

Quote from: Randy007 on April 16, 2012, 04:50:40 PM
realy,realy great job!!!
The only thing i am missing is the save as .pdf, so you can put it on a stick and go to a copyshop for a printout at DIN A3.
(gave them the small finger and they try to get the hole hand  ;) )

Many thanks Randy ;)
I don't plan writing a pdf exporter (unless MANY users require it), but If you check the thread related to the external map viewer (http://forum.simutrans.com/index.php?topic=9514.msg90289#msg90289), and you can use it, Vonjo added a feature for exporting your map diagram into a .png file.
Once you saved your .png, the internet provides you a lot of image->pdf converters; try to google "png to pdf", there is various stuff related and some converters seem to be free. I never used this kind of stuff, so I'm sorry, I cannot be more helpful.

prissi

#91
The kinks in the world map were due to waypoints. I removed waypoints, since this is anyway a schematic map, not a schedule.

EDIT: Attached a version which only uses diagonals.

yorkeiser

I had no much time to see this stuff, however I was trying to parameterize the function that draws airlines, to remove those horrible spikes.
The idea is to sum normal and tangent vectors in the vertexes of the arcs in order to find a sort of 45° vector, then shrink those vectors to not make a too "large" curve. Essentially I removed the 4 parameters that were defining fixed starting and ending directions for curves, and now it's the function itself that calculates those directions.
I tested it on two maps and seems to me giving better visual results, so I post here the code of the new function so whoever wants can give a try.
You also have to change the calls to draw_bezier(), removing the four parameters = 50, and of course fix simgraph.h changing the method's signature.

void draw_bezier(KOORD_VAL Ax, KOORD_VAL Ay, KOORD_VAL Bx, KOORD_VAL By, const PLAYER_COLOR_VAL colore,short draw, short dontDraw)
{
    KOORD_VAL Cx,Cy,Dx,Dy;
    //part changed
    KOORD_VAL normalX,normalY,directionX,directionY;
    normalX=(Ay-By)>>4;
    normalY=(Bx-Ax)>>4;
    directionX=(Bx-Ax)>>4;
    directionY=(By-Ay)>>4;
    Cx=Ax+normalX+directionX;
    Cy=Ay+normalY+directionY;
    Dx=Bx+normalX-directionX;
    Dy=By+normalY-directionY;
    //end of changes

    int a,b,rx,ry,oldx,oldy;
    //fixed point: we cycle between 0 and 32, rather than 0 and 1
    for (int t=0;t<=32;t++)
    {
        a = t;
        b = 32 - t;
        if (t>0)
        {
            oldx=rx;
            oldy=ry;
        }   
        rx = Ax*b*b*b + 3*Cx*b*b*a + 3*Dx*b*a*a + Bx*a*a*a; 
        ry = Ay*b*b*b + 3*Cy*b*b*a + 3*Dy*b*a*a + By*a*a*a;
        //fixed point: due to cycling between 0 and 32 (2<<5), we divide by 32^3=2>>15 because of cubic interpolation
        if (t>0)
            if (!draw && !dontDraw)
                display_direct_line(rx>>15,ry>>15,oldx>>15,oldy>>15,colore);
            else
                display_direct_line_dotted(rx>>15,ry>>15,oldx>>15,oldy>>15,draw,dontDraw,colore);
      }
}


prissi

Those spikes were due to waypoints in the north. It was actually really cold war ... Now the rouinte ignores waypoints.

greenling

I find that waypoints be don´t remove out the Map.
Waypoints make the Navigation lighter.
Opening hours 20:00 - 23:00
(In Night from friday on saturday and saturday on sunday it possibly that i be keep longer in Forum.)
I am The Assistant from Pakfilearcheologist!
Working on a big Problem!

prissi

Incorporated; some details will be polished and the symbols will be taken from images later.

The network of all passenger will be displayed, if the passenger button is dest is selected together with show schedule (and of course no schedule is visible). Same for mail and for freight. This allows to see those networks seperately. With control pressed, the player colors will be used (useful for netowrk display).

Thanks for the inspiration and first implementation!

yorkeiser

Downloaded last nightly: prissi, you did a great work. Diagonalization works well, adding player colors is really useful. I only noticed some little problems:
- diagonalization works badly in isometric mode
- when holding ctrl, player lines have 2/3 colors and not only one player color: is this done by purpose?
- large diagonal lines (train lines) result to be less thick than horizontal and vertical ones: if you used my routine for thick lines, I think that when drawing in diagonal direction, a couple of other single lines would have to be added in order to draw a thicker line
- this is only a personal opinion: main hubs spots (largest circles) imho could be slightly reduced, 3 or 4 pixels less in diameter. Smaller and greater circles also would have to be centered better respect to lines entering in them, because they seem slightly shifted towards north and left, respect to lines.

However, these only are small details: still amazing!

prissi

Without you it would not have started. So this goes also to your back.

The thick lines and the centering issues are is straight from you code ... I will look into them. Maybe even revise the thick line drawing code a little, as for vertical lines the rectangles acan be used.

I was also thinking about only a single color for the player view (the second darkest maybe). Now it cycles through 5 player colros.

yorkeiser

@prissi
As I can see, Bresenham circle routine draws circles with diameter of (radius*2)+1.
For radius, you're passing 5 for hubs and 3 for smaller stations, and it results in circles with respectively 11 and 7 pixels diameter. Previous version, which used fixed graphics, was using 5 pixels diameter for smaller station and 9 pixels for hubs. I suggest trying to decrease radiuses to 4 and 2 respectively, and see how it looks.

About non-centered lines: my thick lines routine isn't actually centered around its vertexes P1 and P2 (station coords): it first draws a single line from P1 and P2 (this would be centered), then shifts one pixel to the right (or bottom, depending on the inclination of the line) and draws another line, and so on, until it reaches its thickness. So in actual version it will always be shifted on the right or on the bottom, respect to its real vertexes. To center it, method should be modified in order to start not from P1.x but from P1.x - line_thickness/2 if it's shifting horizontally (P1.y-line_thickness/2 if shifting along y axis); same for P2.
Also, for diagonals it would have to draw some more lines, I think thickness*sqrt(2) lines approximately, because shifting is done in horizontal or vertical direction, not in diagonal direction that is longer by sqrt(2) factor.

Fabio

Wow, it's great! A dream come true.

I tested it very briefly, this is my first feedback, based on today's nightly.

- UI is very clever, but not so intuitive, it might be rethought later. E.g. remove Line net button; when Show schedules is selected, all legend buttons are disabled ("greyed out") but pax, mail, freight, Cities and city limits; if none is selected, show all, if one is selected, show only that one.

- Stations look great this size! I wouldn't rescale them. Also the background is awesome

- The palette of colors for lines seems a bit dull...

- If I have 2 lines sharing the same tracks, only one is displayed. E.g. Line 1: A-B-C-D; Line 2: E-B-C-F Between B and C only line 1 is shown. I would suggest all lines between 2 stations are shown, maybe enlarging the line and painting it in different colors (e.g. line 1 is red and line 2 is blue, both train: between B and C draw a 10 px line made of 5 red lines and 5 blue ones.

yorkeiser

Quote from: Fabio on April 18, 2012, 02:37:42 PM
- If I have 2 lines sharing the same tracks, only one is displayed. E.g. Line 1: A-B-C-D; Line 2: E-B-C-F Between B and C only line 1 is shown. I would suggest all lines between 2 stations are shown, maybe enlarging the line and painting it in different colors (e.g. line 1 is red and line 2 is blue, both train: between B and C draw a 10 px line made of 5 red lines and 5 blue ones.

This is not immediate to achieve because a line has no memory of how other lines are done: lines are drawn player by player, schedule by schedule.
A simple solution could be to save an array of stop connections for every rail arc (id station 1, id station 2) and, before painting the arc, control if there was already an arc connecting two stations, and if so shifting the arc to be drawn. I did something similar in the external tool.
This is a simple thought, prissi surely can have a smarter solution

prissi

#101
The line net button shows all lines; and if you have a single schedule selected, it will be still normally overlaid. I would rather add also tooltips to those buttons.

Displaying parallel lines in not trivial; especially since also lineless convois are also displayed, i.e. an additional line per lineless convoi, and lines go back and forward. If those would be also displayed, it will get very crowded. (I tried this, but it was really bad on ring lines.)

One might achieve this by first iteration over all schedules, then built connections out of those, and then finally draw them. Hmm, this sounds like very time consuming.

prissi

Ok, fabio, I added also offset for parallel lines. This concludes my work on the line mode. There are still some workplaces (like larger station symbols when many lines in in parallel) but those are quite difficult.

I will rather focus on the buttons in the minimap as many of those are rather obsolete and are in not particular order at all (just pasted to then end ... )

Markohs

Just checked this on a nigtly and I want to congratulate yorkeiser and prissi for such a nice and great addition to simutrans, it looks great.

Fabio

I tested again: it's simply awesome!
It might be tweaked some more, but right now it's simply amazing.
Thanks a lot, Prissi and Yorkeiser!