DrawTileSelection Questions
Moderator: OpenTTD Developers
-
- Engineer
- Posts: 56
- Joined: 03 Jul 2009 02:16
DrawTileSelection Questions
Requesting info on DrawTileSelection - I want to be able to call this function from within either an onclick,onpaint(stationviewwindow). It seams that they are not defined in viewport_func.h i guess thats because they are for being called directly from eg buildroadstationwindow. I am thinking of function overloading and adding the overloaded func to the header file(i want the function to accept x,y instead of getting them from the pointer) What is the most code correct way to do this,
3.New Function
2.Function Overloading
4.Neither Because theyre out of your scope and you should post a var that gets checked in func xxx and does it there.
1.Neither Because another unified way to mark tile selections exists and is xxxx
5.Neither, some of the code in buildroadstationwindow and other variants should be moved into respective DrawXXXStationCatchmentArea(x1,y1,)(x2,y2)(Other Variations)
6.Neither Catchment Area Hilight Is already being worked on by someone else and is almost complete
3.New Function
2.Function Overloading
4.Neither Because theyre out of your scope and you should post a var that gets checked in func xxx and does it there.
1.Neither Because another unified way to mark tile selections exists and is xxxx
5.Neither, some of the code in buildroadstationwindow and other variants should be moved into respective DrawXXXStationCatchmentArea(x1,y1,)(x2,y2)(Other Variations)
6.Neither Catchment Area Hilight Is already being worked on by someone else and is almost complete
- Attachments
-
- catchment2.patch
- Doesnt Work Yet, Damages codecorrectness in Index: src/station.cpp
- (3.32 KiB) Downloaded 226 times
- stevenh
- TTDPatch Developer
- Posts: 759
- Joined: 24 Jul 2005 05:07
- Location: Canberra, Australia
- Contact:
Re: DrawTileSelection Questions
I'd started considering options for showing all station highlighting at once (good for building stations and knowing where other catchment areas were) and had considered creating a new hashtable with array[tileindex] = new list(station_ids_who_catch_this_tile);id10terror wrote:...Catchment Area Hilight Is already being worked on...
Haven't had enough time/motivation to sit in front of a computer and sort it out though.
What are your exact motives?
Currently the _thd struct for the highlight descriptor is very limiting. It would nearly be more fun to have a hashtable[tile_index] full of bools to indicate highlighting tiles in the current drawing loop. But then for my purposes I'd have to refresh that hashtable each time.
-
- Engineer
- Posts: 56
- Joined: 03 Jul 2009 02:16
Re: DrawTileSelection Questions
Display catchment area on a per station basis
currently i have added a widget to the stationviewwindow it has no pic or text atm, my idea is to make it toggle
and based on wether or not it is depressed then make the appropriate calls to
overload DrawTileSelection(x,y,stationtype)(for each type and tile(for distant join))
DrawTileSelectionEx(x,y,stationtype)(for each type and tile(for distant join)) or
Station->DrawCatchmentArea(x,y,stationtype)
i should mention if you call DrawTileSelection atm it will use your mouse cords to get a tile x,y because its only called during placement of a new station(well pre placement and not on placement or at anytime after(*1))
*1 havent been able to spot DrawTileSelection being used anywhere else other than pre station placement
currently i have added a widget to the stationviewwindow it has no pic or text atm, my idea is to make it toggle
and based on wether or not it is depressed then make the appropriate calls to
overload DrawTileSelection(x,y,stationtype)(for each type and tile(for distant join))
DrawTileSelectionEx(x,y,stationtype)(for each type and tile(for distant join)) or
Station->DrawCatchmentArea(x,y,stationtype)
i should mention if you call DrawTileSelection atm it will use your mouse cords to get a tile x,y because its only called during placement of a new station(well pre placement and not on placement or at anytime after(*1))
*1 havent been able to spot DrawTileSelection being used anywhere else other than pre station placement
Re: DrawTileSelection Questions
I made some approach to the same problem so maybe I can help.
Take a closer look how the selection is drawn.
When viewport redraws itself it calls among others ViewportAddLandscape to draw landscape and selection. Function takes every tile that needs to be drawn, retrieves its shape and placement information (TileInfo) draws its ground sprite and finally draws it's selection calling DrawTileSelection.
DrawTileSelection checks if currently being drawn tile belongs to current selection and if it dose, draws proper selection sprite. Information about current selection (position, size and type) is in global variable (viewport.cpp):Notice that this design allows only one selection at time.
So what you need to do is to extend _thd structure, or maybe better would be to create new global variable, to hold extra information about catchment area to be drawn. Let's call this information "catchment selection".
The actions that you need to implement are:
1. In DrawTileSelection check if currently being drawn tile belongs to any "catchment selection" and if does, draw rectangular selection
2. In station window, when selecting "show catchment area" button add catchment area of this station to "catchment selection"
3. When unselecting "show catchment area" button or closing station window remove its catchment area from "catchment selection"
4. When changing shape of station (adding or removing tiles) update its "catchment selection"
The heaviest impact to performance (among those which we can optimize) has checking if currently being drawn tile belongs to "catchment selection". This information must be calculated as fast as possible so I suggest to hold "catchment selection" of one station as a minimum set of rectangles (they can intersect) plus bounding rectangle. If you decide to this solution and have problem with algorithm I can help
.
My other proposition is to draw catchment area in colour of company. Intersecting areas of different companies may be drawn in some special colour.
Take a closer look how the selection is drawn.
When viewport redraws itself it calls among others ViewportAddLandscape to draw landscape and selection. Function takes every tile that needs to be drawn, retrieves its shape and placement information (TileInfo) draws its ground sprite and finally draws it's selection calling DrawTileSelection.
DrawTileSelection checks if currently being drawn tile belongs to current selection and if it dose, draws proper selection sprite. Information about current selection (position, size and type) is in global variable (viewport.cpp):
Code: Select all
TileHighlightData _thd;
So what you need to do is to extend _thd structure, or maybe better would be to create new global variable, to hold extra information about catchment area to be drawn. Let's call this information "catchment selection".
The actions that you need to implement are:
1. In DrawTileSelection check if currently being drawn tile belongs to any "catchment selection" and if does, draw rectangular selection
2. In station window, when selecting "show catchment area" button add catchment area of this station to "catchment selection"
3. When unselecting "show catchment area" button or closing station window remove its catchment area from "catchment selection"
4. When changing shape of station (adding or removing tiles) update its "catchment selection"
The heaviest impact to performance (among those which we can optimize) has checking if currently being drawn tile belongs to "catchment selection". This information must be calculated as fast as possible so I suggest to hold "catchment selection" of one station as a minimum set of rectangles (they can intersect) plus bounding rectangle. If you decide to this solution and have problem with algorithm I can help

My other proposition is to draw catchment area in colour of company. Intersecting areas of different companies may be drawn in some special colour.
![Pleased :]](./images/smilies/pleased.gif)
Re: DrawTileSelection Questions
Take a look at the attached patch against r14481 (i.e. it will not apply to current trunk), which I needed for debugging a while back.
Mind, that station catchment is different for production and acceptance, which is imo the main reason why this feature is not available in ottd. (just to avoid all those pointless question, why it is like that and not different)
For acceptance it is a simple rectangle. (keywords: station walking, distant join cheat) That is also what the attached patch displays.
For production it is a simple rectangle around industries/houses, which adds up to something completely unrectangular for stations.
Mind, that station catchment is different for production and acceptance, which is imo the main reason why this feature is not available in ottd. (just to avoid all those pointless question, why it is like that and not different)
For acceptance it is a simple rectangle. (keywords: station walking, distant join cheat) That is also what the attached patch displays.
For production it is a simple rectangle around industries/houses, which adds up to something completely unrectangular for stations.
- Attachments
-
- show_station_catchment.diff
- old patch; won't apply to HEAD
- (3.03 KiB) Downloaded 224 times
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
- stevenh
- TTDPatch Developer
- Posts: 759
- Joined: 24 Jul 2005 05:07
- Location: Canberra, Australia
- Contact:
Re: DrawTileSelection Questions
id10terror, so we're all after the same thing... the issue is that we're all restricted by the current _thd struct which only expects 'selection' to be one rectangular area of tiles per viewport redraw.
adf88, you've just confirmed everything I managed to ascertain from the source code... And I like your idea about a global variable for station catchment. This is what I was about to dig in to and was going to use an array or hashtable (as we don't need it to be fixed size since it will only change upon station modification/addition/removal.) Each slot in the hashtable would then contain a list of station IDs of which you could then work out company colours and work out how to draw the selection tiles.
Of course, the original _thd can stay, to allow the current cursor-oriented catchment area display.
frosch, thanks for the information on the two types of catchment areas... I'm a little curious as to exactly how it works though. Any station would simply have it's targeted producing industry in it's acceptance rectangle?. I understand that this same concept on a a city wouldn't be a clean rectangle, as they hardly ever are, but for the stations we're talking about, they'll always be rectangles?
adf88, you've just confirmed everything I managed to ascertain from the source code... And I like your idea about a global variable for station catchment. This is what I was about to dig in to and was going to use an array or hashtable (as we don't need it to be fixed size since it will only change upon station modification/addition/removal.) Each slot in the hashtable would then contain a list of station IDs of which you could then work out company colours and work out how to draw the selection tiles.
Of course, the original _thd can stay, to allow the current cursor-oriented catchment area display.
frosch, thanks for the information on the two types of catchment areas... I'm a little curious as to exactly how it works though. Any station would simply have it's targeted producing industry in it's acceptance rectangle?. I understand that this same concept on a a city wouldn't be a clean rectangle, as they hardly ever are, but for the stations we're talking about, they'll always be rectangles?
Re: DrawTileSelection Questions
I also worked on something like that some weeks ago, but got no time to continue. And I am still learning how ottd is done ...
The patch below adds a button in the station gui (between location & accepts buttons) to toggle the station coverage (acceptance) and an "overlay" toolbar (in the setting menu) to activate/toggle it for all stations.
It's working but has some bugs (no deleted station removal yet) and strange behaviours.
It's doing quite like adf88 and stevenh said : a global hashtable which contains toggled stations pointer. It just call a DrawOverlay function in every tile's DrawTile somewhere between foundation drawing and the rest above.
It works on acceptance and not production ... which i still don't really understand : if it is working as "real" covered area (not bounding area but really in distance of every station tile), i don't see where yet. Maybe in the industry/town production process ?
(As for the overlays, I planned to build a overlay system which can display catchment but also other per tile information as a color/texture (like tracks traffic for example)).
I will try to make it bug free and to correct and refactor the code (don't mind it now please).
The patch below adds a button in the station gui (between location & accepts buttons) to toggle the station coverage (acceptance) and an "overlay" toolbar (in the setting menu) to activate/toggle it for all stations.
It's working but has some bugs (no deleted station removal yet) and strange behaviours.
It's doing quite like adf88 and stevenh said : a global hashtable which contains toggled stations pointer. It just call a DrawOverlay function in every tile's DrawTile somewhere between foundation drawing and the rest above.
It works on acceptance and not production ... which i still don't really understand : if it is working as "real" covered area (not bounding area but really in distance of every station tile), i don't see where yet. Maybe in the industry/town production process ?
(As for the overlays, I planned to build a overlay system which can display catchment but also other per tile information as a color/texture (like tracks traffic for example)).
I will try to make it bug free and to correct and refactor the code (don't mind it now please).
- Attachments
-
- overlay_coverage_r17147.diff
- (23.68 KiB) Downloaded 205 times
Re: DrawTileSelection Questions
The acceptance area is a station bounding box + maximal radius (see UpdateStationAcceptance in sttaion_cmd.cpp), red rectangle on image.
It's badly designed. Devs - don't you think?
The "gather" area is a sum of bounding boxes + radius of each station tile (see FindStationsAroundTiles in sttaion_cmd.cpp), purple squares on image.

It's badly designed. Devs - don't you think?

The "gather" area is a sum of bounding boxes + radius of each station tile (see FindStationsAroundTiles in sttaion_cmd.cpp), purple squares on image.
Last edited by adf88 on 11 Aug 2009 12:20, edited 5 times in total.
![Pleased :]](./images/smilies/pleased.gif)
- stevenh
- TTDPatch Developer
- Posts: 759
- Joined: 24 Jul 2005 05:07
- Location: Canberra, Australia
- Contact:
Re: DrawTileSelection Questions
Understood... just tested this out in the game and now I understand how it works.. I had previously played the game thinking otherwise!adf88 wrote:The "gather" area is a sum of bounding boxes + radius of each station tile (see FindStationsAroundTiles in sttaion_cmd.cpp), purple squares on image.
Acceptance should, I suppose, either act as above, or the "gathering" should work as acceptance does... but then 'cheating' [station-walking,distant-join,as-mentioned-above] becomes more of an issue.
I suppose if we were to help each other out and get this done then we should have one standard method for both. I'd suggest the "gathering" method. And then tidying up whomever wrote the neatest code and implement the drawing of it.
Re: DrawTileSelection Questions
Interesting thread!
Until now I also thought both acceptance and production used the red rectangle - so it's really only acceptance that uses this rectangular area? hmm.
Anyway, if anyone were to change this, the question is how much more computational effort it takes and if that is worth it.
My guess is that devs have already thought about it but dismissed it because of the extra computations.
Until now I also thought both acceptance and production used the red rectangle - so it's really only acceptance that uses this rectangular area? hmm.
Anyway, if anyone were to change this, the question is how much more computational effort it takes and if that is worth it.
My guess is that devs have already thought about it but dismissed it because of the extra computations.
-
- Engineer
- Posts: 56
- Joined: 03 Jul 2009 02:16
Re: DrawTileSelection Questions
Hmn didnt know about different accept/generate.
DrawTileSelection makes decisions to
DrawTileSelectionRect e.g. DrawTileSelectionRect(ti, PALETTE_SEL_TILE_BLUE)
DrawTileSelectionSprite
gehene has a more comprehensive solution
thanks adf88 i should now probably spend some time looking at ViewportAddLandscape calls
mine involves drawing from the stationviewwindow, in this manner a few stations catchments could be shown together but not the every station at once. This serves to limit the overhead, as soon as you would close the stationviewwindow the overlay would dissapear and not be drawn or thought about anymore. Also from within the stationviewwindow you are given a handle to the station class (polymorphic basestation && busstation && other??) and from this handle you can get all the station tiles. then you could mimic somthing like
int rad = _settings_game.station.modified_catchment ? CA_TRUCK /* = CA_BUS */ : CA_UNMODIFIED;
SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
DrawTileSelection(overloadx,overloady) - overload because by default it will look at the mouse pointer coordinates.
what is the most code correct way of doing this?
Another note on catchments, they could be cached per base station and only recaclulated when adding or removing from basestations as such they could be used by the main game engine and or drawtileselection without the overhead of recalculation the catchment area per tick as in adf88 method
A unified way to mark selections may also benefit other patches by providing a simple way to draw attention to or visually classify a set of tiles
DrawTileSelection makes decisions to
DrawTileSelectionRect e.g. DrawTileSelectionRect(ti, PALETTE_SEL_TILE_BLUE)
DrawTileSelectionSprite
gehene has a more comprehensive solution
thanks adf88 i should now probably spend some time looking at ViewportAddLandscape calls
mine involves drawing from the stationviewwindow, in this manner a few stations catchments could be shown together but not the every station at once. This serves to limit the overhead, as soon as you would close the stationviewwindow the overlay would dissapear and not be drawn or thought about anymore. Also from within the stationviewwindow you are given a handle to the station class (polymorphic basestation && busstation && other??) and from this handle you can get all the station tiles. then you could mimic somthing like
int rad = _settings_game.station.modified_catchment ? CA_TRUCK /* = CA_BUS */ : CA_UNMODIFIED;
SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
DrawTileSelection(overloadx,overloady) - overload because by default it will look at the mouse pointer coordinates.
what is the most code correct way of doing this?
Another note on catchments, they could be cached per base station and only recaclulated when adding or removing from basestations as such they could be used by the main game engine and or drawtileselection without the overhead of recalculation the catchment area per tick as in adf88 method
A unified way to mark selections may also benefit other patches by providing a simple way to draw attention to or visually classify a set of tiles
Re: DrawTileSelection Questions
While adf88's explaination about acceptance is correct, you missed that industries are also non-rectangular.
The attached image shows, that the truckstop got goods, though even the build-gui does not show it.
This effect becomes more visible the more non-rectangular the industries/stations are. (e.g. some FIRS industries are quite non-rectangular)
Btw. If you haven't already guessed so, I am not interested in changing any of these rules.
The attached image shows, that the truckstop got goods, though even the build-gui does not show it.
This effect becomes more visible the more non-rectangular the industries/stations are. (e.g. some FIRS industries are quite non-rectangular)
Btw. If you haven't already guessed so, I am not interested in changing any of these rules.
- Attachments
-
- transfer from industry->station uses bounding box of industry
- supplyrectangle.png (56.81 KiB) Viewed 1199 times
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
-
- Engineer
- Posts: 56
- Joined: 03 Jul 2009 02:16
Re: DrawTileSelection Questions - Catchment Area
<edit> Ghene has a working solution at -> http://www.tt-forums.net/viewtopic.php?f=33&t=44835 </edit>
Hmn the differences in acceptance/production complicates things.
Its not nessary to change the game mechanics(i'm pretty sure someone in newgrf will do this later). But this makes a stronger case to have a seperate drawstationcatchment function so it could be called in a uniform manner that doesn't require extra maintainence later on.
Noting that the current _thd struct will remain because it handles drawing the catchment without a station, unless you overload the new drawstationcatchment functions to be able to draw a particular station type/lenght without the station actually existing(as its done now by getting the tile the mouse is over).
I'd be happy being able to see the 'normal' catchment area without opening the new station window.
If worst comes to worst we could add a widget to industryviewwindow? that displays its bounding box
I like drawing things from window onpaint events as when the window gets closed your code doesn't execute anymore but i'm guessing that i'm creating a scenario where the graphics engine draws the tiles then the windows on top of the tiles and then(because of me) drawing to the tiles again before repeating.
No Complaints - I like all the info thats been provided but i need to know the most 'correct' way of doing this if we don't do it correctly it will never make trunk
Hmn the differences in acceptance/production complicates things.
Its not nessary to change the game mechanics(i'm pretty sure someone in newgrf will do this later). But this makes a stronger case to have a seperate drawstationcatchment function so it could be called in a uniform manner that doesn't require extra maintainence later on.
Noting that the current _thd struct will remain because it handles drawing the catchment without a station, unless you overload the new drawstationcatchment functions to be able to draw a particular station type/lenght without the station actually existing(as its done now by getting the tile the mouse is over).
I'd be happy being able to see the 'normal' catchment area without opening the new station window.
If worst comes to worst we could add a widget to industryviewwindow? that displays its bounding box
I like drawing things from window onpaint events as when the window gets closed your code doesn't execute anymore but i'm guessing that i'm creating a scenario where the graphics engine draws the tiles then the windows on top of the tiles and then(because of me) drawing to the tiles again before repeating.
No Complaints - I like all the info thats been provided but i need to know the most 'correct' way of doing this if we don't do it correctly it will never make trunk
Who is online
Users browsing this forum: No registered users and 1 guest