1 个不稳定版本
0.1.0 | 2023年2月9日 |
---|
#1384 in 游戏开发
48KB
893 行
场景图
本库提供了一个类似于Unity或Unreal引擎中使用的场景图结构。它速度快,性能好,易于操作。
快速入门
要安装,请将以下内容添加到您的Cargo.toml中
scene-graph = "0.1.0"
或运行
cargo add scene-graph
以下是一个基本的SceneGraph
示例
use scene_graph::SceneGraph;
fn main() {
let mut sg: SceneGraph<&'static str> = SceneGraph::new("root");
sg.attach_at_root("first child");
// note that insertion order is honored.
let second_child_handle = sg.attach_at_root("second child");
// collect the nodes
let nodes = Vec::from_iter(sg.iter().map(|(_parent, node)| *node));
// note that the "root" is not seen in an `iter` operation.
assert_eq!(nodes, ["first child", "second child"]);
sg.attach(second_child_handle, "first grand-child").unwrap();
sg.attach(second_child_handle, "second grand-child").unwrap();
sg.attach_at_root("weird third way younger child");
let nodes = Vec::from_iter(sg.iter().map(|(_parent, node)| *node));
// note the iteration order -- because we `iter` depth first, we'll get the youngest child last.
assert_eq!(
nodes,
[
"first child",
"second child",
"first grand-child",
"second grand-child",
"weird third way younger child"
]
);
}
SceneGraph的iter
函数在深度优先遍历中返回父节点值和当前节点值的一个元组。SceneGraph主要设计用于Transform树,其iter
是遍历这些Transform以将局部变换的场景图转换为世界空间变换的最佳方式。
分离节点
可以通过调用detach
来分离场景图中的节点,这将返回一个新的SceneGraph<T>
,其根是提供的节点。可以通过SceneGraph::attach_graph
将SceneGraph<T>
附加到另一个SceneGraph<T>
上。如果不需要此功能,用户可以使用remove
简单地删除节点并完全丢弃它。
在不删除节点的情况下分离节点的子节点也很简单 —— iter_detach
将返回一个迭代器,该迭代器将分离节点的每个后代。
与petgraph
的比较
SceneGraph类似于petgraph::stable_graph::StableGraph
,但有一些区别。
在M1 Mac上,SceneGraph在遍历节点方面比petgraph略快,但创建节点的延迟略高。
benches | 场景图 |
petgraph |
---|---|---|
添加和删除节点 | 52ns |
8.56ns |
遍历50k个节点 | 217µs |
299.49µs |
遍历64个节点 | 311ns |
456.49ns |
然而,这并不是scene-graph真正发光的地方 —— scene-graph的编写目标是快速迭代,与petgraph不同,petgraph是一个通用图形工具。例如,在petgraph中没有与iter函数简单等价的函数。
// in `scene-graph`
for (parent, child) in sg.iter() {
todo!();
}
// in `petgraph`
petgraph::visit::depth_first_search(&petgraph_sg, Some(root_idx), |event| match event {
petgraph::visit::DfsEvent::Discover(_, _) => todo!(),
petgraph::visit::DfsEvent::TreeEdge(_, _) => todo!(),
petgraph::visit::DfsEvent::BackEdge(_, _) => todo!(),
petgraph::visit::DfsEvent::CrossForwardEdge(_, _) => todo!(),
petgraph::visit::DfsEvent::Finish(_, _) => todo!(),
});
然而,petgraph
提供了许多 scene-graph
完全缺乏的算法。例如,在 petgraph
中查找图中两个节点之间的距离很简单,而在 scene-graph
中完全由用户控制。
依赖项
此包依赖于 thiserror
以提供便利,并依赖 thunderdome
的支持 Arena 分配器。实验证明 thunderdome
是选项中最容易使用且速度最快的。
MSRV
此包目前还没有 MSRV。如果它得到良好的采用,将决定一个 MSRV 政策。
许可证
双许可 MIT 或 APACHE 2.0。
依赖项
~0.4–0.8MB
~19K SLoC