News:

The Forum Rules and Guidelines
Our forum has Rules and Guidelines. Please, be kind and read them ;).

An Idea for fixing vehicle alignments

Started by Leartin, January 17, 2021, 11:55:24 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Leartin

In the picture, you can see how a locomotive stops for a station and for a sign. This happens in North and West direction, and can't be fixed by a pak author, the difference is always there.

In an ideal world, the locomotive would stop for both signs and stations as it's seen to the left, yet when leaving, it would still go straight to the point it is on the right before turning the bend. And I think there is a relatively straightforward way to make that possible while also staying backwards compatible to existing paks.

We'd need these 5 steps:
- for each convoi, add an invisible vehicle of length 0 at front (and perhaps back).
- add a new parameter that defines the position of the rotation axis, similar to length. [call it 'axis' for now]. If none is given, make it a pak setting whether it's 0 or length/2, let's call that "oldaxis=true" for 0 and make it the default.
- redefine the distance between two vehicles A, B in the convoy. Instead of just A.length, it's A.length-A.axis+B.axis.
- when drawing a vehicle, in get_screen_offset, before turning steps into display_steps, add the vehicles axis*8 to the steps.
- make the 'hacks' for different directions optional for "oldaxis=true".

The difference in position in the image would be the one defined with axis. Compared to how it's now, you can imagine an invisible vehicle that has that very length in front of the locomotive - thus, that invisible vehicle would stop for the signal, and the locomotive would come in due distance after it. Once the signal opens, the locomotive still has to go that distance until it reaches the end of the tile and turns. The same would then be true for south and east, if vehicles are aligned properly.

But if nothing of the paks changes, the distance from the invisible convoi leader to the locomotive would be zero, therefore no change in behavior at all.


Why is this in extension request, rather than a patch? Because there is a good chance if I made a patch and it worked as intended and is completely optional, it would still not be accepted. So if this would be denied either way, you can tell me before I work on it (or even better: explain why it's a bad idea)

prissi

#1
The old driving further forward was a relic of the original tile drawing system, since overhanging into previous tiles messes up drawing order. Unless Simutrans is very overloaded (or in full forward mode) the drawing became much more sophisticated with partial clipping, and may no longer produce strong artefacts (although I did not test this). I think pak128.japan uses this approach. If going this route, one could realign automatically all vehicles on load time so that they do not overhang into the next tile and the just use the existing code and remove the driving less in stations and rather go to the end.

This would be the best solution, as it would also make the map totally rotation agnostic, while currently a rotated map and a rotated display behave differently, since train may overhang in station differently in different roations which could affect path reservation. But I think, I remember the visial experience with pak128.japan was not entire artefact free on bridges.

Adding automatically an invisible car in front in nonzero length two directions is a nice idea. But I wonder how this should be handled at direction changes, especially in these cases when the car vanishes or appear. The convoi would need to jump forward or backward so the rest moves smoothly. Or the car must enter the next tile and then start shrinking while the convoi drives on, so the reservation is kept.

The invisible car in front would not be very different from a simple patch that brakes trains half a tile before signals in north or west directions. This is not so difficult, since the convoi remember anyway the next signal (or crossing), so only this route tile must be handled specially.

However, adding automatically an invisble car in front would of course somewhat fixes road vehciles. Still, just jumping back the convoi will not work, since one cannot make sure that a car is not blocked again while driving the remainder of the tile after a crossing becomes free. So the invisble front car has to shrink on the next tile. And citycars will be left messed up.

Leartin

Quote from: prissi on January 18, 2021, 01:41:44 AM
If going this route, one could realign automatically all vehicles on load time so that they do not overhang into the next tile and the just use the existing code and remove the driving less in stations and rather go to the end. [...] This would be the best solution, as it would also make the map totally rotation agnostic, while currently a rotated map and a rotated display behave differently, since train may overhang in station differently in different roations which could affect path reservation. But I think, I remember the visial experience with pak128.japan was not entire artefact free on bridges.
I disagree that it would be the best solution, on the account that vehicles bending looks worse from south to southwest then from north to northeast, precisely because the rotation axis of the vehicle is at the very tip. But it is my intention to remove any rotation-dependent code. I suppose it might be a good idea to do that first, play around with realigned vehicles, and be very vigilant for artefacts, especially with bridges - since the artefacts that could appear should be the same.
Are vehicles actually the only thing currently preventing viewport rotation instead of map rotation? That would mean it's something certainly worth working on and more important than just getting nicer visuals.

Quote from: prissi on January 18, 2021, 01:41:44 AM
Adding automatically an invisible car in front in nonzero length two directions is a nice idea. But I wonder how this should be handled at direction changes, especially in these cases when the car vanishes or appear. The convoi would need to jump forward or backward so the rest moves smoothly. Or the car must enter the next tile and then start shrinking while the convoi drives on, so the reservation is kept. The invisible car in front would not be very different from a simple patch that brakes trains half a tile before signals in north or west directions. This is not so difficult, since the convoi remember anyway the next signal (or crossing), so only this route tile must be handled specially.
That's not quite it, though. The invisible car would be the space between where a vehicle stops and where it bends, for all directions, and not just for signs and crossings but also for vehicles having to wait since the next tile is occupied.

Quote from: prissi on January 18, 2021, 01:41:44 AMAnd citycars will be left messed up.
Unless they also become convois. But citycars are less messed up as-is, since they are typically short, don't have trailers and don't wait in stations. If you just align them such that they rotate nicely, they already work pretty well and only stick a bit of their nose over the tile edge, but less so than is typical in North/West currently.

prissi

Adding these invisible vehicles will not make the map movement rotation independent. It would rather extend the "station hack" to "everywhere hack north west". So it would not change anything for viewport rotation. Viewport rotation would require to move the vehicles in the same position in all rotations and directions and not to increase convoi length too.

The invisble vehicle will of course also affect the driving on straight roads north or west. As a consequence, less cars will fit on a north/west-bound road compared to driving south/east (because a car with length >8 or with a trailer would occupy two tiles for most of the time).

Having said that, as long as one is fine with the status quo (no map rotating for network games, or rather bad alignment if rotating viewport only) the invisible vehicles could certainly improve appearance in many situations.

Dwachs

Imho the idea is way too complicated. I think the following things would be enough to achieve your goal:
-- remove the special check for vehicles driving N/W in stations (vehicle.cc: vehicle_t::hop, lines 578-580).
-- use the idea with axis to change graphics orientation mid-tile (i.e. after half of the vehicle is on the new tile)
-- then graphics can be aligned to be always at the tile border

No need for invisible vehicles, no axis parameter in vehicle dats. It needs some compatibility switch for the whole pakset (or just the leading vehicle) to change graphics offsets on loading.

One can even push this further to allow for more graphics for turning or climbing vehicles.
Parsley, sage, rosemary, and maggikraut.

ceeac

I agree. Furthermore, when invisible vehicles are used, maps with lots of single-vehicle convoys might run into performance problems since more vehicles have to be updated (up to about 50% more on average, correct me if I'm wrong).

Leartin

Quote from: Dwachs on January 18, 2021, 09:01:06 AM
Imho the idea is way too complicated. I think the following things would be enough to achieve your goal:
-- remove the special check for vehicles driving N/W in stations (vehicle.cc: vehicle_t::hop, lines 578-580).
-- use the idea with axis to change graphics orientation mid-tile (i.e. after half of the vehicle is on the new tile)
-- then graphics can be aligned to be always at the tile border

No need for invisible vehicles, no axis parameter in vehicle dats. It needs some compatibility switch for the whole pakset (or just the leading vehicle) to change graphics offsets on loading.

Im not sure how you mean.
Say vehicles in stations and signs stop when they are "at the end of the tile". This would mean that they must be aligned like south and east are. In order for them to be able to move further without immediately turning, you'd have to make it such that a vehicle entering a tile wouldn't change direction immediately, but only after a certain amount of steps. This seems unintuitive to me, and I'm afraid the number of steps it would keep it's old orientation would need to be the same for each vehicle.
Say vehicles in stations and signs stop before they are at the end of the tile. In other words, the hack for north and west station would be applied for all directions + signs + crossings. Which includes a hackish count for whether vehicles are actually inside the station. Say a convoi of a total length of 32 turns in a two-tile station - wouldn't it be a bit hard to make it so it's actually in the station after turning, since it would occupy a different position (the very front wouldn't be were the very back was, since the back was technically outside the station, and now the front is not just within the station, but a few steps deeper inside for graphical alignment)


The invisible leader of the convoi, in combination with redefining the distance between two vehicles, would solve that.
In numbers: Say you have a convoi, a length 4 truck with length 10 trailer. The convoi has length 14, so it fits one tile. Instead of a defined axis (which indeed is optional) we just use length/2 (and (length+1)/2 for the length after the axis)
So the convoi begins at the very edge, with what I called an invisible vehicle of length 0. Then, truck.length/2 steps after that, there is the truck. Then, (truck.length+1)/2 + trailer.length/2 steps behind, is the trailer. Finally, (trailer.length+1)/2 steps behind, is the "end of convoi". Those distances summed up are still the length of the convoi, so that's all fine, and the position of the 'end of convoi' is exactly where the 'beginning of convoi' would be if the convoi turns 180°

Dwachs

Quote from: Leartin on January 18, 2021, 10:58:51 AM
Say vehicles in stations and signs stop when they are "at the end of the tile". This would mean that they must be aligned like south and east are. In order for them to be able to move further without immediately turning, you'd have to make it such that a vehicle entering a tile wouldn't change direction immediately, but only after a certain amount of steps.
Yes, I meant this. As we are talking about visual/graphical orientation this will only affect vehicles that are on screen. And yes, the graphic has to change when the centre of the vehicle crosses tile borders. It need not to be the same for all vehicles. This would require some additional logics in the display code, but would hopefully remove any need for hacks (driving not to end of station, invisible vehicles).
Parsley, sage, rosemary, and maggikraut.

Leartin

I feel like I shouldn't have said "invisible vehicle".
Invisible vehicles are certainly hackish, but it's a good analogy for "abstracting a convoy down to it's beginning and end", which isn't hackish at all. I'm curious: If you'd know the beginning and end of any convoi on the map, would you even need to sync the vehicles in that convoi, or could you define their precise position, rotation etc. only in case they are on screen? Given how much is typically on the screen compared to how much isn't, couldn't that rather increase performance?

Plus, I feel like when the vehicle is on the tile that only has track from south to west, while it looks and behaves like going north, only to be a moment later on a tile that has track from east to west, but look and behave as if it went northwest still, is just another hack.





prissi

Middle vehicle do not much. They update their graphics when the direction changes and update their step positions. This is anyway needed, in case the view is changed. They still need to be added to the track to avoid empty tiles. They need this also to calculate their braking weight (i.e. know if the direction is changed or if they are on a slope) for the acceleration.

Since the display routines can handle 16 bit offsets, one can just shift them on the fly (like for driving left etc) back on N and W directions. I admid, this leaves the problem of turning at the front (which is the same for all direction). But stopping is much more obvious than turning.

The engine can handle this without much offfset errors. Here is an incomplete patch which show no graphic glitches, so the current engine is robust enough. I does not solve the ugly turning, of course. But with this the display view could be rotated, instead of the map, since the vehicles stay always on the same tiles.

makie

Quote from: prissi on January 18, 2021, 02:42:32 PMBut with this the display view could be rotated, instead of the map
Oh this sounds good.

Rotating maps if they are (very) big is time consuming because all data in the memory are moved.
Rotating only the view and there is no need for moving all data.

prissi

The other possibility could be to set all vehicles half a tile back. That would lead to correct cornering in all directions. Then extra provision is needed for signals and stations. i.e. stopping always half a tile early but in all directions. This would also allow for viewport only rotation.

Since this would affect any vehicle in any direction some new code for road vehicles (i.e. one tile ahead reservations) to fix crossing etc. would be needed.

I am not sure, what is easier to program. My gut feeling is that this option might be easier.