Skip to content

Commit

Permalink
Improve node tree overall usage.
Browse files Browse the repository at this point in the history
`zsorted_children()` no longer returns parent
comments added
during constructing `RenderCtx`, making clear that some procedures require zsortedness and exclusion of certain nodes, while some procedures just require all nodes in arbitary order
Use HashMap instead of BTreeMap for the uuid -> index map. No point sorting uuids.
  • Loading branch information
Richardn2002 committed Aug 6, 2023
1 parent 76c0837 commit e004d59
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 69 deletions.
3 changes: 0 additions & 3 deletions inox2d-wgpu/src/node_bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,6 @@ pub fn node_bundles_for_model(
let mut bundles = Vec::new();

for child_id in puppet.nodes.zsorted_children(uuid) {
if child_id == uuid {
continue;
}
let child = puppet.nodes.get_node(child_id).unwrap();

if let InoxData::Part(part) = &child.data {
Expand Down
4 changes: 2 additions & 2 deletions inox2d/src/formats/serialize.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::{BTreeMap, HashMap};
use std::collections::HashMap;

use glam::{vec2, Vec2};
use indextree::Arena;
Expand Down Expand Up @@ -415,7 +415,7 @@ fn deserialize_nodes<T>(
deserialize_node_custom: &impl Fn(&str, &JsonObject) -> InoxParseResult<T>,
) -> InoxParseResult<InoxNodeTree<T>> {
let mut arena = Arena::new();
let mut uuids = BTreeMap::new();
let mut uuids = HashMap::new();

let root_node = deserialize_node_ext(obj, deserialize_node_custom)?;
let root_uuid = root_node.uuid;
Expand Down
10 changes: 8 additions & 2 deletions inox2d/src/nodes/node_tree.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::fmt::Display;

use indextree::{Arena, NodeId};
Expand All @@ -9,7 +9,7 @@ use super::node::{InoxNode, InoxNodeUuid};
pub struct InoxNodeTree<T = ()> {
pub root: indextree::NodeId,
pub arena: Arena<InoxNode<T>>,
pub uuids: BTreeMap<InoxNodeUuid, indextree::NodeId>,
pub uuids: HashMap<InoxNodeUuid, indextree::NodeId>,
}

impl<T> InoxNodeTree<T> {
Expand Down Expand Up @@ -81,16 +81,22 @@ impl<T> InoxNodeTree<T> {
sort_uuids_by_zsort(uuid_zsorts)
}

/// all nodes, zsorted, with composite children excluded
pub fn zsorted_root(&self) -> Vec<InoxNodeUuid> {
let root = self.arena.get(self.root).unwrap().get();
self.sort_by_zsort(root, true)
}

/// all children, grandchildren..., zsorted, with parent excluded
pub fn zsorted_children(&self, id: InoxNodeUuid) -> Vec<InoxNodeUuid> {
let node = self.arena.get(self.uuids[&id]).unwrap().get();
self.sort_by_zsort(node, false)
.into_iter()
.filter(|uuid| *uuid != node.uuid)
.collect::<Vec<_>>()
}

/// all nodes
pub fn all_node_ids(&self) -> Vec<InoxNodeUuid> {
self.arena.iter().map(|n| n.get().uuid).collect()
}
Expand Down
96 changes: 34 additions & 62 deletions inox2d/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,91 +99,63 @@ pub type NodeRenderCtxs = HashMap<InoxNodeUuid, NodeRenderCtx>;
#[derive(Debug)]
pub struct RenderCtx {
pub vertex_buffers: VertexBuffers,
pub drawables_zsorted: Vec<InoxNodeUuid>,
/// all nodes that need respective draw method calls
/// including standalone parts, composite parents
/// excluding plain mesh masks, composite children
pub root_drawables_zsorted: Vec<InoxNodeUuid>,
pub node_render_ctxs: NodeRenderCtxs,
}

impl RenderCtx {
fn add_part<T>(
nodes: &InoxNodeTree<T>,
uuid: InoxNodeUuid,
vertex_buffers: &mut VertexBuffers,
node_render_ctxs: &mut NodeRenderCtxs,
) {
let node = nodes.get_node(uuid).unwrap();
pub fn new<T>(nodes: &InoxNodeTree<T>) -> Self {
let mut vertex_buffers = VertexBuffers::default();
let mut root_drawables_zsorted: Vec<InoxNodeUuid> = Vec::new();
let mut node_render_ctxs = HashMap::new();

for uuid in nodes.all_node_ids() {
let node = nodes.get_node(uuid).unwrap();

if let InoxData::Part(ref part) = node.data {
let (index_offset, vert_offset) = vertex_buffers.push(&part.mesh);
node_render_ctxs.insert(
uuid,
NodeRenderCtx {
trans: Mat4::default(),
trans_offset: node.trans_offset,
kind: RenderCtxKind::Part(PartRenderCtx {
index_offset,
vert_offset,
index_len: part.mesh.indices.len(),
vert_len: part.mesh.vertices.len(),
}),
kind: match node.data {
InoxData::Part(ref part) => {
let (index_offset, vert_offset) = vertex_buffers.push(&part.mesh);
RenderCtxKind::Part(PartRenderCtx {
index_offset,
vert_offset,
index_len: part.mesh.indices.len(),
vert_len: part.mesh.vertices.len(),
})
}

InoxData::Composite(_) => {
RenderCtxKind::Composite(nodes.zsorted_children(uuid))
}

_ => RenderCtxKind::Node,
},
},
);
}
}

pub fn new<T>(nodes: &InoxNodeTree<T>) -> Self {
let mut vertex_buffers = VertexBuffers::default();
let mut drawables_zsorted: Vec<InoxNodeUuid> = Vec::new();
let mut node_render_ctxs = HashMap::new();

let nodes_zsorted = nodes.zsorted_root();
for &uuid in &nodes_zsorted {
for uuid in nodes.zsorted_root() {
let node = nodes.get_node(uuid).unwrap();

match node.data {
InoxData::Part(_) => {
Self::add_part(nodes, uuid, &mut vertex_buffers, &mut node_render_ctxs);
drawables_zsorted.push(uuid);
InoxData::Part(_) | InoxData::Composite(_) => {
root_drawables_zsorted.push(uuid);
}
InoxData::Composite(_) => {
// Children include the parent composite, so we have to filter it out.
// TODO: wait... does it make sense for it to do that?
let children = nodes
.zsorted_children(node.uuid)
.into_iter()
.filter(|uuid| *uuid != node.uuid)
.collect::<Vec<_>>();

// put composite children's meshes into composite bufs
for &uuid in &children {
Self::add_part(nodes, uuid, &mut vertex_buffers, &mut node_render_ctxs);
}

node_render_ctxs.insert(
uuid,
NodeRenderCtx {
trans: Mat4::default(),
trans_offset: node.trans_offset,
kind: RenderCtxKind::Composite(children),
},
);
drawables_zsorted.push(uuid);
}
_ => {
node_render_ctxs.insert(
uuid,
NodeRenderCtx {
trans: Mat4::default(),
trans_offset: node.trans_offset,
kind: RenderCtxKind::Node,
},
);
}
_ => (),
}
}

Self {
vertex_buffers,
drawables_zsorted,
root_drawables_zsorted,
node_render_ctxs,
}
}
Expand Down Expand Up @@ -395,7 +367,7 @@ impl<T: InoxRenderer> InoxRendererCommon for T {
}

fn draw(&self, camera: &Mat4, puppet: &Puppet) {
for &uuid in &puppet.render_ctx.drawables_zsorted {
for &uuid in &puppet.render_ctx.root_drawables_zsorted {
let node = puppet.nodes.get_node(uuid).unwrap();
let node_render_ctx = &puppet.render_ctx.node_render_ctxs[&uuid];

Expand Down

0 comments on commit e004d59

Please sign in to comment.