viewer,ship: external parts ON by default + Ships catalog = composite ships only
Fixes the two things the user saw in the Ships browser: - "Can't find the thrusters": show_external defaulted OFF, hiding the engine rig / bridge / turrets entirely. Externals are EXACT since the node-TRS fix, so the toggle now defaults ON (relabelled; off = bare hull bodies). - "Some parts very far away": families without a composite scene graph (fighter morph sets like f002 whose detached parts are authored far from the origin, shared turret/prop part families) fell into the stack-at-origin fallback and rendered as piles with stray pieces. ShipModel now carries has_composite and the catalog lists only real assembled ships. Offline audit across ALL stages (ship_audit example): the only far-away outliers were composite-less f002 morph parts (now filtered); every capital ship assembles coherently (e108 places its 7 turret instances, f105 its mirrored shield generators). All primary composites are single-key tracks — multikey exists only in animation composites (e901 attacks, missile-open), which assemble_ship does not select. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -613,7 +613,7 @@ pub struct ShipRow {
|
||||
}
|
||||
|
||||
/// The Ships browser state — capital ships assembled from XBG7 part families.
|
||||
#[derive(Resource, Default)]
|
||||
#[derive(Resource)]
|
||||
pub struct ShipBrowser {
|
||||
pub open: bool,
|
||||
pub loading: bool,
|
||||
@@ -624,11 +624,27 @@ pub struct ShipBrowser {
|
||||
pub rows: Vec<ShipRow>,
|
||||
/// Family id of the ship currently rendered (for row highlight).
|
||||
pub selected: Option<String>,
|
||||
/// Also place the approximate external parts (bridge / shield gen / engines at
|
||||
/// their `GN_*` hardpoint frames). Off by default → the exact hull only.
|
||||
/// Also place the external parts: bridge / shield generators / the engine
|
||||
/// cluster rig / cross-mounted turrets. EXACT (capture-validated) since the
|
||||
/// node-TRS fix, so ON by default; off = bare hull bodies only.
|
||||
pub show_external: bool,
|
||||
}
|
||||
|
||||
impl Default for ShipBrowser {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
open: false,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
filter: String::new(),
|
||||
faction: String::new(),
|
||||
rows: Vec::new(),
|
||||
selected: None,
|
||||
show_external: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Ask the loader to scan the stage containers and build the ship catalog.
|
||||
#[derive(Event, Default)]
|
||||
pub struct RequestShipCatalog;
|
||||
@@ -3860,8 +3876,11 @@ fn build_ship_catalog(source: &SourceKind) -> Vec<ShipRow> {
|
||||
};
|
||||
let label = format!("S{n:02}");
|
||||
for sm in ships_in_container(&bytes) {
|
||||
// Skip single-piece props / debris — not "whole ships".
|
||||
if sm.parts.len() < 2 {
|
||||
// Skip single-piece props / debris — not "whole ships" — and any
|
||||
// family with no composite scene graph (fighter morph sets, shared
|
||||
// turret parts): those have no placement data and would render as a
|
||||
// pile at the origin with stray far-away pieces.
|
||||
if sm.parts.len() < 2 || !sm.has_composite {
|
||||
continue;
|
||||
}
|
||||
let v = vmap.get(&sm.id);
|
||||
|
||||
@@ -1590,7 +1590,7 @@ fn draw_ships_ui(
|
||||
}
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
ui.checkbox(&mut ships.show_external, "Show external parts");
|
||||
ui.checkbox(&mut ships.show_external, "External parts (bridge/engines/turrets)");
|
||||
ui.label(
|
||||
egui::RichText::new("(bridge / shield gens / engines — approximate placement)")
|
||||
.weak()
|
||||
|
||||
Reference in New Issue
Block a user