DrawTileSelection Questions

Forum for technical discussions regarding development. If you have a general suggestion, problem or comment, please use one of the other forums.

Moderator: OpenTTD Developers

Post Reply
id10terror
Engineer
Engineer
Posts: 56
Joined: 03 Jul 2009 02:16

DrawTileSelection Questions

Post by id10terror »

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
Attachments
catchment2.patch
Doesnt Work Yet, Damages codecorrectness in Index: src/station.cpp
(3.32 KiB) Downloaded 226 times
User avatar
stevenh
TTDPatch Developer
TTDPatch Developer
Posts: 759
Joined: 24 Jul 2005 05:07
Location: Canberra, Australia
Contact:

Re: DrawTileSelection Questions

Post by stevenh »

id10terror wrote:...Catchment Area Hilight Is already being worked on...
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);

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.
id10terror
Engineer
Engineer
Posts: 56
Joined: 03 Jul 2009 02:16

Re: DrawTileSelection Questions

Post by id10terror »

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
User avatar
adf88
Chief Executive
Chief Executive
Posts: 644
Joined: 14 Jan 2008 15:51
Location: PL

Re: DrawTileSelection Questions

Post by adf88 »

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):

Code: Select all

TileHighlightData _thd;
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.
:] don't worry, be happy and checkout my patches
frosch
OpenTTD Developer
OpenTTD Developer
Posts: 991
Joined: 20 Dec 2006 13:31
Location: Aschaffenburg

Re: DrawTileSelection Questions

Post by frosch »

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.
Attachments
show_station_catchment.diff
old patch; won't apply to HEAD
(3.03 KiB) Downloaded 224 times
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
User avatar
stevenh
TTDPatch Developer
TTDPatch Developer
Posts: 759
Joined: 24 Jul 2005 05:07
Location: Canberra, Australia
Contact:

Re: DrawTileSelection Questions

Post by stevenh »

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?
gehene
Engineer
Engineer
Posts: 4
Joined: 10 Aug 2009 23:24

Re: DrawTileSelection Questions

Post by gehene »

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).
Attachments
overlay_coverage_r17147.diff
(23.68 KiB) Downloaded 205 times
User avatar
adf88
Chief Executive
Chief Executive
Posts: 644
Joined: 14 Jan 2008 15:51
Location: PL

Re: DrawTileSelection Questions

Post by adf88 »

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? :roll:

The "gather" area is a sum of bounding boxes + radius of each station tile (see FindStationsAroundTiles in sttaion_cmd.cpp), purple squares on image.

Image
Last edited by adf88 on 11 Aug 2009 12:20, edited 5 times in total.
:] don't worry, be happy and checkout my patches
User avatar
stevenh
TTDPatch Developer
TTDPatch Developer
Posts: 759
Joined: 24 Jul 2005 05:07
Location: Canberra, Australia
Contact:

Re: DrawTileSelection Questions

Post by stevenh »

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.
Understood... just tested this out in the game and now I understand how it works.. I had previously played the game thinking otherwise!

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.
Roujin
Tycoon
Tycoon
Posts: 1884
Joined: 08 Apr 2007 04:07

Re: DrawTileSelection Questions

Post by Roujin »

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.
* @Belugas wonders what is worst... a mom or a wife...
<Lakie> Well, they do the same thing but the code is different.

______________
My patches
check my wiki page (sticky button) for a complete list

ImageImage
ImageImageImageImageImageImageImage
id10terror
Engineer
Engineer
Posts: 56
Joined: 03 Jul 2009 02:16

Re: DrawTileSelection Questions

Post by id10terror »

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
frosch
OpenTTD Developer
OpenTTD Developer
Posts: 991
Joined: 20 Dec 2006 13:31
Location: Aschaffenburg

Re: DrawTileSelection Questions

Post by frosch »

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.
Attachments
transfer from industry-&gt;station uses bounding box of industry
transfer from industry->station uses bounding box of industry
supplyrectangle.png (56.81 KiB) Viewed 1199 times
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
id10terror
Engineer
Engineer
Posts: 56
Joined: 03 Jul 2009 02:16

Re: DrawTileSelection Questions - Catchment Area

Post by id10terror »

<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
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: No registered users and 1 guest