Repository navigation
Fix F3DEX3 binary export of triangles and light counts - #739
Merged
Merged
Conversation
…ounts
Exporting a display list as binary or insertable binary with F3DEX3 selected fails
before writing anything:
ValueError: invalid literal for int() with base 10: 'NUMLIGHTS_1NUMLIGHTS_1...'
and, past that, `PluginError: SP2Triangles not available in Fast3D.`
Two separate causes, both specific to F3DEX3:
`F3D.NUML` multiplied the macro name by 0x10 instead of the light count it looks up,
because the F3DEX3 branch runs before the lookup.
Three binary encoders test `F3DEX_GBI or F3DLP_GBI`, that is "is this F3DEX1", where
what they mean is "is this any F3DEX". F3DEX3 deliberately leaves `F3DEX_GBI` false
(see the comment in `F3D.__init__`: F3DEX3 is F3DEX2, but F3DEX3 is not F3DEX1), so
it fell through to the original F3D encodings:
* `_gsSP1Triangle_w1f` scaled vertex indices by 10 instead of 2 and wrote flag as a
separate byte. In F3DEX2 and later that byte lands on the command byte, so a
triangle with flag 2 turned G_TRI1 (0x05) into 0x07.
* `SP2Triangles` raised outright, which is why no F3DEX3 binary export completed.
* `SPCullDisplayList` used the F3D vertex scaling.
Verification, Blender 4.2.16 LTS:
* encoding SP1Triangle and SP2Triangles over 34 index/flag combinations for F3D,
F3DEX/LX, F3DLX.Rej, F3DEX2/LX2 and F3DEX3, then decoding the words back: every
case now round-trips its indices, its flag and its command byte. Of 62 encodings,
the 14 that change are all F3DEX3; F3D, F3DEX1 and F3DEX2 are byte identical.
* insertable binary export of a test mesh: F3DEX3 went from raising to producing a
display list whose 8 two-triangle commands index inside the 56 vertex buffer.
F3D and F3DEX2 exports are byte identical before and after.
* C export of a 22 mesh corpus for F3D, F3DEX2 and F3DEX3 is unchanged.
Dragorn421
approved these changes
Sep 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Exporting a display list as Binary or Insertable Binary with F3DEX3 selected fails before anything is written:
and, once that is out of the way:
Both reproduce without a scene:
The first prints the macro name repeated 16 times instead of a number, the second raises.
Cause
Two unrelated slips, both specific to F3DEX3.
F3D.NUMLreturnsn * 0x10for F3DEX3 beforenhas been looked up inself.numLights, so it multiplies the macro name string instead of the light count.Three binary encoders test
F3DEX_GBI or F3DLP_GBI, i.e. "is this F3DEX1", where what is meant is "is this any F3DEX". F3DEX3 deliberately leavesF3DEX_GBIfalse — the comment inF3D.__init__spells it out: F3DEX2 is F3DEX1 and F3DEX3 is F3DEX2, but F3DEX3 is not F3DEX1 — so it fell through to the original F3D encodings:_gsSP1Triangle_w1fscaled vertex indices by 10 instead of 2, and wrote the flag as its own byte. From F3DEX2 on, that byte lands on the command byte: a triangle with flag 2 turnedG_TRI1(0x05) into 0x07.SP2Trianglesraised, which is why no F3DEX3 binary export ever completed.SPCullDisplayListused the F3D vertex scaling.Fix
NUMLlooks the count up first. The three encoders testnot f3d.F3D_OLD_GBI, which is true for every F3DEX generation and false for original F3D, so F3D keeps its own encodings.Verification
Blender 4.2.16 LTS.
SP1TriangleandSP2Trianglesover 34 index/flag combinations for F3D, F3DEX/LX, F3DLX.Rej, F3DEX2/LX2 and F3DEX3, then decoded the words back. Every case now round-trips its indices, its flag and its command byte. Of 62 encodings, the 14 that change are all F3DEX3; F3D, F3DEX1 and F3DEX2 come out byte identical.I can check the encoding and the structure of the output, not that a console draws it, so this is "F3DEX3 binary export now writes what the GBI specifies" rather than "F3DEX3 binary export is fully supported".