Fix skeleton bone deletion reordering all bones - #383
Merged
donkeyProgramming merged 2 commits intoAug 9, 2026
Merged
Conversation
The BMD editor was read-only: it parsed a .bmd and rendered a text dump of every field. There was no writer at all, so nothing could be saved. Format layer: - Add BmdWriter, mirroring BmdParser section-for-section over the whole file (not just the editable categories), with a self-check that re-parses its own output before returning. Legacy/undocumented branches that the parser itself discards throw NotSupportedException rather than silently corrupting data. - Capture data the parser previously read purely to advance the stream and then dropped, which a writer cannot reproduce otherwise: BmdFile.SectionVersions, PropInfo.PropIndex (prop string tables contain duplicate paths, so re-deriving an index can silently repoint a prop), and CultureMask.RawBytes (several bit positions map to no named field and would be zeroed on reconstruction). - Fix BmdParser never populating BmdFile.Props (the shared prop string table was read and thrown away). - Fix unreachable spotlight branch: `if (Version > 3) ... else if (Version > 4)` meant v>4 spotlights read a UInt32 PdlcMask instead of a UInt64, misaligning the stream by 4 bytes. Editor: - Implement ISaveableEditor with a Save button and dirty tracking. - Per-category transform editing, exposing only the degrees of freedom the format actually stores: full TRS for props/decals/VFX/composite scenes and polymesh v>3; position+rotation for spot lights; position only for point lights, light probes, terrain hole vertices, sounds, and polymesh v<=3 (bulk vertex offset). Transforms are edited as position / euler degrees / scale rather than raw matrices. - Add BmdGizmoComponent (ported from CscGizmoComponent) driving the same properties, with rotate/scale gated to categories that support them. - Replace the text-dump details panel with per-category templates of real controls, and make paths editable (prop model, VFX, sound event, polymesh material, composite scene file). - Group the component tree into collapsible per-category sections and split decals out from props. - Add an "Add" menu covering all ten categories, matching the CSC editor. - Add Terry project export (.terry/.layer) via pack file context menu. - Remove the unused BmdSceneView/Bmd3DSceneViewer/BmdSceneViewModel trio and the unreferenced BmdBmdReferenceKey class. Verified: all 44 local .bmd files (36 campaign prefabs, 8 terrain tile_maps) round-trip byte-for-byte identical; edits through the view models change only the intended bytes; the ten Add-menu defaults write and re-parse correctly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GameSkeleton.DeleteBone rebuilt the entire bone list by re-numbering every bone via a depth-first traversal of the parent/child tree. That traversal order doesn't necessarily match the skeleton's original bone order (siblings whose subtrees aren't contiguous in the flat list get shuffled), so deleting one bone could silently reorder every other bone's index. Rewritten to remove only the deleted bone (and its descendants) while keeping the relative order of the remaining bones unchanged.
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.
GameSkeleton.DeleteBonerenumbered every bone via a depth-first tree traversal, which doesn't necessarily match the skeleton's original bone order — deleting one bone could silently reorder every other bone's index. Now only the deleted bone (and its descendants) are removed; the rest keep their original relative order.Added a regression test reproducing the reordering with an unrelated bone deletion.