Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sprite sorter issue #2078

Closed
DorpsGek opened this issue Jun 14, 2008 · 16 comments
Closed

Sprite sorter issue #2078

DorpsGek opened this issue Jun 14, 2008 · 16 comments
Labels
component: NewGRF This issue is related to NewGRFs flyspray This issue is imported from FlySpray (https://bugs.openttd.org/)

Comments

@DorpsGek
Copy link
Member

George opened the ticket and wrote:

R13485M

This sprite definition should (IMHO) make left part to be drawn in front of the middle part
488 * 88 02 07 01 08
3E 05 00 00
00 80 00 80 00 00 00 10 01 06
01 80 00 80 00 00 00 01 10 06
12 80 00 80 09 00 00 06 03 07
04 80 00 80 01 0A 00 02 06 04
14 80 00 80 03 03 00 03 03 0A
0A 80 00 80 0B 08 00 01 01 04
0A 80 00 80 08 0B 00 01 01 04
18 80 00 80 0C 0C 00 04 04 05

But as you can see on the screen shot, it does not work as intended.

Attachments

Reported version: trunk
Operating system: Windows


This issue was imported from FlySpray: https://bugs.openttd.org/task/2078
@DorpsGek
Copy link
Member Author

frosch wrote:

Try to avoid overlapping boxes. What happens, when you change the extents of the first two BB to <16, 0, 6> and <0, 16, 6>? I.e. replace the 1 by 0.

But why do you create such a complicated layout at all? Just put there one big bounding box (starting at <0,0,0>, extents <16, 16, 10>) and place the remaining sprites as childsprites. That is better in any case...


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4292

@DorpsGek
Copy link
Member Author

George wrote:

But these two boxes do not overlap, don't they?

I've tried to change the code as you suggested, but the problem remained
485 * 98 02 07 01 09
3E 05 00 00
00 80 00 80 00 00 00 10 00 06
01 80 00 80 00 00 00 00 10 06
04 80 0B 83 01 0A 00 02 06 04
12 80 00 80 09 00 00 06 03 07
14 80 00 80 03 03 00 03 03 0A
0A 80 0D 83 0A 07 00 01 01 04
0A 80 0F 83 07 0A 00 01 01 04
06 00 00 80 03 0F 00 02 01 0F
18 00 00 80 0C 0C 00 04 04 05

IMHO, that is not a right solution, because I plan to add the animation, where RV would pass through the station and that bounding box would come out from the parent tile, and to draw this behaviour correctly, other parts should be separated bounding boxes (correct me if I'm wrong).
Also I hope to have pass through houses someday, and then I would have no way to control sprites order except bounding boxes, don't I?


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4303

@DorpsGek
Copy link
Member Author

frosch wrote:

Ok, sorry for pointing you in the wrong direction.

The BB # 1 of the left sprite extents from < 9,0,0 > to < 9,0,0 > + < 6,3,7 > = < 15,3,7 >
The BB # 2 of the middle sprite extents from < 3,3,0 > to < 3,3,0 > + < 3,3,10 > = < 6,6,10 >
The BB # 3 of the right sprite extents from < 1,10,0 > to < 1,10,0 > + < 2,6,4 > = < 3,16,4 >

That means wrt. Y # 2 starts, where # 1 ends. So # 1 and # 2 do neither overlap wrt. X nor Y. Therefore the sorting order of these BB is indefinite.
The same holds for # 2 and # 3.

To make it definite, ensure that the BBs overlap in either X or Y direction.
I.e. if # 2 should be drawn behind # 1 and # 3: Change the extents of # 1 from < 6,3,7 > to < 6,4,7 > and of # 2 from < 2,6,4 > to < 3, 6, 4 >. Or let # 2 start from < 2,2,0 >.

If # 2 should be drawn in front of # 1 and # 3: Change BB # 1 to start at < 5,0,0 > and BB # 2 to start at < 1,5,0 >.


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4308

@DorpsGek
Copy link
Member Author

George wrote:

May be I'm understanding it wrong, but IMHO < 9,0,0 > to < 9,0,0 > + < 6,3,7 > should be < 14,2,6 >
Also, I can't understand why should the order be undefined. See the image. 1 is in front of 2.
Of cause 1 and 3 are located on one level, and here goes the rule "the right one is drawn first". At least I came to conclusion that TTDP works this way.
Of cause there may be alternative calculation, where the front point is used instead of middle point as the base point. This is up to OTTD devs, of cause.
In my case I'll move BB# 2 to 1,1,0

Attachments


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4313

@DorpsGek
Copy link
Member Author

frosch wrote:

The barycenter-rule is only used when the BB overlap. If they do not overlap, they are compared by their X, Y and Z position. If these three orders come to different results, the order is indefinite.

Example:
In the attached picture you can see two cases. In both the red and the green BB have the same positions relative to each other. But a the third blue box decides the correct order. If there are only the red and the green box you cannot tell the order, as you don't know which blue box may appear later during drawing.

Attachments


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4314

@DorpsGek
Copy link
Member Author

George wrote:

The question is how OTTD should support this "indefinite result". There must be some rule, Imho.
Does OTTD calculates 2 different sprite orders in cases, represented on your picture?


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4316

@DorpsGek
Copy link
Member Author

frosch wrote:

Well, this is not an OTTD specific issue. TTDP won't be able to sort those BB neither in all cases. Sprite sorting is in general not well-defined. Try the attachment: Please sort the three BB, so it results in the right picture. Good luck :)

However these "indefinite results" only bother, if the sprites extent over their BBs. And that is the fault of the one who defined the BB. The Sprite Sorter only knows about the BBs, not about the sprites. Sure, in a lot of cases it is not possible to make the BB large enough, as they would interact in a bad way with other BB, but then it is as well the job of the BB designer to arrange them, so it works. I.e. to make sure there are enough X/Y/Z relations in the interacting BB.

In your case the partial X and partial Y sorters report different results. As one of them is the correct one, you have to ensure, that the other partial order does not call its voice. You do that, by making the BB overlap in the direction, that should not influence the result.

Example: BB # 1 extents from X=1 to X=2

  1. If both X coordinates of BB # 2 are <= 1, the "partial X-sorter" says: Draw BB # 2 in front of BB # 1.
  2. If both X coordinates of BB # 2 are >= 2, the "partial X-sorter" says: Draw BB # 1 in front of BB # 2.
  3. If the X coordinates of the two BB overlap, the "partial X-sorter" says: I don't care, let the other partial sorters decide.

If the three partial Sorters X, Y and Z agree, the BB are sorted that way.
If they all say "i don't care" the barycenter rule is used. (Note: This rule is not present in original TTD, but in both OTTD and TTDP)
If they do not agree, then the order of the BB is not changed. But later a third BB # 3 might appear, that says # 1 < # 3 < # 2 or # 2 < # 3 < # 1. And then # 1 and # 2 will also be sorted.

If there is no such BB # 3, the order of # 1 and # 2 is random, and will usally result in some flickering (relative to heavy flickering in the attached situation).

And no, OTTD cannot try every N*(N-1)*...21 ways to sort N BB. Plus it would not be of any use, as it then still cannot decide, which one is the correct. For more details on the spritesorter I have to point you towards the sourcecode: viewport.cpp::ViewportSortParentSprites()

Attachments


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4317

@DorpsGek
Copy link
Member Author

George wrote:

Sorry, I'm confused with your answer:

  1. do you want to say, that the arrangement of BBs on picture is possible? It looks like impossible to me. What am I missing?
  2. do you want to say, that if the order of BBs # 1 ? # 2 (is undefined), than their order would stay undefined even if there is BB3 that # 1 < # 3 < # 2, because it takes too much CPU to find this BB3 ?

This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4318

@DorpsGek
Copy link
Member Author

frosch wrote:

  1. you are right.
  2. If there is such a BB # 3 it will place # 1 and # 2 in the correct order. But if there is none, it won't be detected.

This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4319

@DorpsGek
Copy link
Member Author

George wrote:

  1. How?
  2. And what will happen if both # 1 < # 3 < # 2 and # 2 < # 4 < # 1 happens?

This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4320

@DorpsGek
Copy link
Member Author

frosch wrote:

  1. err, it is impossible.
  2. then you have # 1 < # 3 < # 2 < # 4 < # 1. It's like 1) and will result in heavy flickering.

This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4321

@DorpsGek
Copy link
Member Author

George wrote:

  1. why? 3 and 4 can overlap, can't they? Like your previous image, where both middle BB are represented.

This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4322

@DorpsGek
Copy link
Member Author

frosch wrote:

Don't know where your last "why?" refers to. However:
Unfortunatelly the sprite order is not transitive, i.e. # 3 < # 2 < # 4 does NOT imply # 3 < # 4. If that were the case, it would be a lot easier. However if # 3 < # 4 or if they are not comparable # 3 ? # 4, the sprite sorter is lucky.
But if there is a cycle in the order (no matter if of length 3, 4 or more) it will result in heavy flickering.

So, did you change your BB to be no longer indefinite? I.e. can I close the task?


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4329

@DorpsGek
Copy link
Member Author

George wrote:

I moved my block to 1,1,0 and the order is correct now, but the task should stay open.
Imho, if the order is undef (# 1 ? # 2), and there is no # 1 < # 3 < # 2, than the sorter should ALSO compare centers and make a decision (http://bugs.openttd.org/?getfile=3012), and in case they are on one level, it should use the rule "right one first" (or left one, it does not matter, but one decision should be selected and documented). This way there should be no undefined orders. Yes, there would be orders change (for example if BB3 would disappear), but it would be always defined. It does not matter how right the order is, but it is alway better than undefined order. Then the task may be closed.

Summary:
There should be defined order, so the GRF coder could always calculate the result in advance.


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4334

@DorpsGek
Copy link
Member Author

frosch wrote:

In that case it is a duplicate of #119, as it also deals with undefined orders.


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078#comment4337

@DorpsGek
Copy link
Member Author

frosch closed the ticket.

Reason for closing: Duplicate

of #119


This comment was imported from FlySpray: https://bugs.openttd.org/task/2078

@DorpsGek DorpsGek added flyspray This issue is imported from FlySpray (https://bugs.openttd.org/) component: NewGRF This issue is related to NewGRFs bug labels Apr 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: NewGRF This issue is related to NewGRFs flyspray This issue is imported from FlySpray (https://bugs.openttd.org/)
Projects
None yet
Development

No branches or pull requests

1 participant