Refactor node building logic to support recursive child attachment in bridge reification
This commit is contained in:
@@ -134,21 +134,24 @@ impl Reify for BridgeState {
|
||||
}
|
||||
}
|
||||
|
||||
let children = self.nodes.iter().filter_map(|(id, node)| {
|
||||
// Helper to recursively build a node and its children
|
||||
fn build_node(
|
||||
id: u64,
|
||||
nodes: &HashMap<u64, Node>,
|
||||
downloader: &ModelDownloader,
|
||||
) -> Option<(u64, ast::elements::Spatial)> {
|
||||
let node = nodes.get(&id)?;
|
||||
let dims = glam::Vec3::from(node.dimensions);
|
||||
if dims.length() < 0.001 {
|
||||
eprintln!("[bridge/reify] Skipping node {} (zero dimensions)", id);
|
||||
return None;
|
||||
}
|
||||
|
||||
let (scale, rot, trans) = node.transform.to_scale_rotation_translation();
|
||||
let vis_scale = if dims.length() > 0.001 { dims } else { scale };
|
||||
|
||||
let trans_array = [trans.x, trans.y, trans.z];
|
||||
let rot_array = [rot.x, rot.y, rot.z, rot.w];
|
||||
let scale_array = [vis_scale.x, vis_scale.y, vis_scale.z];
|
||||
let transform = stardust_xr_fusion::spatial::Transform::from_translation_rotation_scale(trans_array, rot_array, scale_array);
|
||||
|
||||
// Try to load the appropriate model based on entity type and model URL
|
||||
let model_child = if let Some(model_path) = get_model_path(node.entity_type, &node.model_url, downloader) {
|
||||
let entity_type_name = match node.entity_type {
|
||||
@@ -160,18 +163,14 @@ impl Reify for BridgeState {
|
||||
6 => "light",
|
||||
_ => "unknown"
|
||||
};
|
||||
|
||||
let model_source = if !node.model_url.is_empty() {
|
||||
format!("from URL: {}", node.model_url)
|
||||
} else {
|
||||
format!("primitive from {}", model_path.display())
|
||||
};
|
||||
|
||||
eprintln!("[bridge/reify] Loading {} for node {} {}", entity_type_name, id, model_source);
|
||||
|
||||
match node.entity_type {
|
||||
4 => {
|
||||
// Text entity: use node.name as text for now
|
||||
let text = ast::elements::Text::new(&node.name)
|
||||
.character_height(node.dimensions[1].max(0.01))
|
||||
.color(ast::elements::RgbaLinear::new(
|
||||
@@ -180,18 +179,15 @@ impl Reify for BridgeState {
|
||||
Some(text.build())
|
||||
}
|
||||
5 => {
|
||||
// Image entity: use PanelUI as a placeholder for now
|
||||
eprintln!("[bridge/reify] Image entity type detected for node {}. Using PanelUI as placeholder.", id);
|
||||
let panel = ast::elements::PanelUI::default();
|
||||
Some(panel.build())
|
||||
}
|
||||
6 => {
|
||||
// Light entity: use asteroids Light element
|
||||
eprintln!("[bridge/reify] Light entity type detected for node {}.", id);
|
||||
let color = ast::elements::RgbaLinear::new(
|
||||
node.color[0], node.color[1], node.color[2], node.color[3]
|
||||
);
|
||||
// Use y dimension as intensity if available, else default to 1.0
|
||||
let intensity = node.dimensions.get(1).copied().unwrap_or(1.0).max(0.01);
|
||||
let light = ast::elements::Light::new()
|
||||
.color(color)
|
||||
@@ -199,7 +195,6 @@ impl Reify for BridgeState {
|
||||
Some(light.build())
|
||||
}
|
||||
7 => {
|
||||
// Zone entity: use asteroids Zone element
|
||||
eprintln!("[bridge/reify] Zone entity type detected for node {}.", id);
|
||||
let color = ast::elements::RgbaLinear::new(
|
||||
node.color[0], node.color[1], node.color[2], node.color[3]
|
||||
@@ -238,14 +233,30 @@ impl Reify for BridgeState {
|
||||
eprintln!("[bridge/reify] No model available for entity type {} (node {})", node.entity_type, id);
|
||||
None
|
||||
};
|
||||
|
||||
Some((*id, Spatial::default()
|
||||
// Recursively build children
|
||||
let children: Vec<_> = nodes.iter()
|
||||
.filter_map(|(child_id, child_node)| {
|
||||
if child_node.parent == Some(id) {
|
||||
build_node(*child_id, nodes, downloader)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let mut spatial = Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.maybe_child(model_child)))
|
||||
});
|
||||
|
||||
PlaySpace.build().stable_children(children)
|
||||
.maybe_child(model_child);
|
||||
for (_cid, child_spatial) in children {
|
||||
spatial = spatial.child(child_spatial);
|
||||
}
|
||||
Some((id, spatial))
|
||||
}
|
||||
// Only attach root nodes (no parent) to PlaySpace
|
||||
let root_nodes: Vec<_> = self.nodes.iter()
|
||||
.filter_map(|(id, node)| if node.parent.is_none() { build_node(*id, &self.nodes, downloader) } else { None })
|
||||
.collect();
|
||||
PlaySpace.build().stable_children(root_nodes)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user