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

Bad polygon(s) on metal layer (#1) for Z80 sim #26

Closed
logoliv opened this issue Jun 11, 2024 · 11 comments
Closed

Bad polygon(s) on metal layer (#1) for Z80 sim #26

logoliv opened this issue Jun 11, 2024 · 11 comments

Comments

@logoliv
Copy link

logoliv commented Jun 11, 2024

There are some bad polygon points for metal layer (layer #1 in the sim) between #42 and ab0 pins (on the left) and one bad point is completely on the top left of the simulation (near the _busrq pin).
Capture d’écran 2024-06-11 224243
The layer is fine on the http://www.visual6502.org/JSSim/expert-z80.html page and in Z80 Explorer application.

@floooh
Copy link
Owner

floooh commented Jun 12, 2024

Thanks for noticing that and writing the issue. It's most likely a bug in the offline-triangulation script https://github.com/floooh/v6502r/blob/master/ext/visual6502/segdefs.py and only affects rendering, but not the actual emulator functionality.

No promises yet when I get around fixing the issue.

PS: thinking about it I wonder if it's a precision problem. The mesh vertex positions are stored as 16-bit integers: (https://raw.githubusercontent.com/floooh/v6502r/master/src/z80/segdefs.c) and for the more 'dense' Z80 some closeby vertex positions might be collapsed into the same 16-bit integer value...

@logoliv
Copy link
Author

logoliv commented Jun 12, 2024

Thanks for your answer. I know it doesn't affect the simulation but it spoils the pretty look of your work :)
I have a doubt about the precision problem : this part of the chip is not very dense.
Please when you correct that, could you release an update in your visualz80remix repository ?

@logoliv
Copy link
Author

logoliv commented Jun 12, 2024

By the way, if I compare your segdefs.c with the original Visual Z80 segdefs.js, it seems all the coordinates have been multiplied by 2

var segdefs = [
[ 48,'-',0,4613,4961,4644,4961,4644,4951,4613,4951],
[ 49,'-',0,55,4959,86,4959,86,4949,55,4949],
[ 50,'-',0,4652,4943,4661,4943,4661,4912,4652,4912],
[ 51,'-',0,38,4942,47,4942,47,4911,38,4911]...

@floooh
Copy link
Owner

floooh commented Jun 12, 2024

Yeah, I'm passing in a scale factor 2 here only for the Z80:

segdefs.dump(src_dir, dst_dir, 2)

Reason might be that the input data for the Z80 has x.5 values, see this comment (which is only about negative 0.5) though:

# NOTE: the +1 is because the Z80 has some coords -0.5
x = int(float(tokens[i]) * scale) + 1
y = int(float(tokens[i+1]) * scale) + 1

...it looks more and more like a rounding/clamping issue though (or maybe even a 16-bit overflow issue).

PS: yeah, when you look at the Z80 segdefs.js input file, there's a lot of x.5 values:

https://raw.githubusercontent.com/floooh/v6502r/master/ext/visual6502/z80/segdefs.js

...that explains the multiplication by 2 at least.

@logoliv
Copy link
Author

logoliv commented Jun 12, 2024

I noticed that all closed shapes with a "hole" inside are scrambled (like in my capture for the A, 8, 4 and 0 characters, but the V is correct), so my advice is that the problem is in indexation of vertexes for these types of polygons.
Capture d’écran 2024-06-12 232816

@fghsgh
Copy link

fghsgh commented Sep 23, 2024

The original segdefs.js file has a weird format for segments that allows defining multiple polygons per segment.

  • If there is only one polygon, all the points of the polygon are given in order. The last boundary line is implicit. So something like A,B,C,D to define the polygon ABCD.
  • If there are multiple polygons, a duplicate point signifies the end of the polygon, after which a second polygon starts. So something like A,B,C,D,A,E,F,G,H,E to define the polygons ABCD and EFGH (yes, including that final duplicate point).

Note that while rendering the second case like the first case would still work if there are at most two polygons (like the O in Zilog), it breaks if there are more than two. For example, A,B,C,D,A, E,F,G,H,E, I,J,K,L,I using the one polygon code would render a line AE, a line EI, and a line IA, therefore drawing a triange between these three points when there shouldn't be one:
image
Alternatively, it could be resolved by a point E after the definition of IJKL: A,B,C,D,A,E,F,G,H,E,I,J,K,L,I,E (and then do this in FILO order for each additional polygon in the segment). This would instead draw the lines AE,EI,IE,EA, which are all 0-width.

Also note that you cannot simply split these polygons into multiple segments, as one polygon inside another polygon within the same segment should cause it to be inverted, causing a hollow space inside the outer polygon (this is used extensively in the letters screenshotted above). Meanwhile, a polygon inside another polygon from a different segment will just cause them to overlap.

I figured this out while making my own renderer. I can share my code for reference if requested, but it's written in Lua, and it may not be helpful in the first place, as I do not use triangulation at all.

I do not know if all the polygons are still guaranteed to be counterclockwise (I am calculating the signed area of each polygon of each segment and adjusting my polygon rendering accordingly in my code), and I don't know if there are any other formats the segment definition could take on aside from the two above. All my assertion checks succeed though, and I haven't noticed any visual glitches.

@floooh
Copy link
Owner

floooh commented Sep 27, 2024

Thanks a lot for this investigation and detailed explanation @fghsgh! I'm not sure yet when I will return to the project and fix this issue, but a link to your Lua code would be appreciated (fwiw, I didn't spend a lot of time on the offline triangulation, it's all in a sloppily cobbled together python script (https://github.com/floooh/v6502r/blob/master/ext/visual6502/segdefs.py), so when I touch that area again I might as well rewrite the whole renderer and picking code anyway).

@verhovsky
Copy link

Similar sort of issue in the decode logic part (the top part) of the 6502

Screenshot 2024-12-11 at 10 07 55

@floooh
Copy link
Owner

floooh commented Dec 14, 2024

Some progress by switching to a different triangulation library (https://github.com/joshuaskelly/earcut-python), which is also much faster. I "just" need to figure out how to deal with holes, and some problems that look like in @fghsgh's screenshots.

The TL;DR is basically that the original visual6502 rendering uses HTML canvas2d paths for rendering (so the triangulation must match canvas2D's filled polygon rendering, e.g. these are the important parts:

The outer loop over 'segments':

https://github.com/trebonian/visual6502/blob/d8ecc129b34e0eaf320e0400fcf33329475bdb1e/wires.js#L83-L92

...and the inner loop over vertices:

https://github.com/trebonian/visual6502/blob/d8ecc129b34e0eaf320e0400fcf33329475bdb1e/wires.js#L227-L234

Screenshot 2024-12-14 at 17 53 45Screenshot 2024-12-14 at 17 54 07Screenshot 2024-12-14 at 17 54 18

@floooh
Copy link
Owner

floooh commented Dec 15, 2024

I think I got it :)

Screenshot 2024-12-15 at 14 12 02 Screenshot 2024-12-15 at 14 12 11 Screenshot 2024-12-15 at 14 12 24

...with the following triangulation rules:

  • on the 6502 segment definition, there are some segments with a duplicate vertex at start, those don't seem to cause any harm, but I'm skipping those (I think those are the reason why the original segment renderer in visual6502 starts at the second vertex and adds the first vertex at the end (which then basically closes the loop for such 'duplicate first vertex' segments): https://github.com/trebonian/visual6502/blob/d8ecc129b34e0eaf320e0400fcf33329475bdb1e/wires.js#L232-L233)
  • for segments with multiple paths (e.g. where a vertex is identical with a start vertex, e.g. the path loops back to the start vertex), all following paths define holes, this situation only exists in the Z80 segment definition
  • both the 6502 and 2a03 don't seem to have any 'multi-path segments' (e.g. no segments with holes)

...in the offline triangulation I'm now looking for those special cases and prepare the input to the python earcut library accordingly.

@floooh
Copy link
Owner

floooh commented Dec 15, 2024

PS: the new triangulation doesn't fix those aritfacts in the 6502 simulation though, I think these are actual precision (or maybe rounding) problems in the dataset. For instance on the original visual6502 some of those can be seen too:

image

Similar sort of issue in the decode logic part (the top part) of the 6502

Screenshot 2024-12-11 at 10 07 55

@floooh floooh closed this as completed in 3cc4581 Dec 15, 2024
floooh added a commit that referenced this issue Dec 15, 2024
Fix (most) triangulation issues (fixes #26)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants