![](/img/trans.png)
[英]How can I make tree-like structure where the nodes are trait objects in Rust?
[英]How can I turn a Vec of trait objects into a tree structure?
我正在尝试在我的 Rust 光线追踪器中实现 BVH 算法,但我在生命周期和所有权方面遇到了问题。 我有一个特征Hittable
可以实现一堆不同的东西—— Sphere
、 Triangle
、 Mesh
等。所以我有一个Vec<Box<dyn Hittable>>
,我想把它变成这个结构的树:
pub struct BvhNode {
bounding_box: BoundingBox,
left: Box<dyn Hittable>,
right: Box<dyn Hittable>,
}
所以我有这个递归算法几乎可以工作,如果不是生命周期问题的话。 我的 function 看起来像
pub fn new(objects: Vec<Box<dyn Hittable>>, start: usize, end: usize, t0: f64, t1: f64) -> Self {
let r = util::rand();
let comp = if r < 1. / 3. {
util::box_x_compare
} else if r < 2. / 3. {
util::box_y_compare
} else {
util::box_z_compare
}; // which axis to compare along (random for now)
let num_obj = end - start;
let mut left: Box<dyn Hittable>;
let mut right: Box<dyn Hittable>;
if num_obj == 1 {
left = objects[start];
right = objects[start];
} else if num_obj == 2 {
if comp(&&objects[start], &&objects[start + 1]) != Ordering::Greater {
left = objects[start];
right = objects[start + 1];
} else {
left = objects[start + 1];
right = objects[start];
}
} else {
let mut slice: Vec<&Box<dyn Hittable>> = Vec::new();
for i in start..end { // make a copy to sort
slice.push(&objects[i]);
}
slice.sort_by(comp);
let mid = start + num_obj / 2;
let l = BvhNode::new(objects, start, mid, t0, t1);
let r = BvhNode::new(objects, mid, end, t0, t1);
left = Box::new(l.clone());
right = Box::new(r.clone());
}
let left_box = left.get_bounding_box(t0, t1);
let right_box = right.get_bounding_box(t0, t1);
if left_box.is_none() || right_box.is_none() {
println!("Error: No bounding box in Bvh Node");
panic!();
}
Self { left, right, bounding_box: BoundingBox::new(Point3::origin(), Point3::origin()) }
}
首先,我在尝试“移出 vec”时遇到了一些问题,这是我做不到的,因此我尝试在所有实现Hittable
的类型上实现Clone
。 它适用于几乎所有人,但我的Triangle
结构
pub struct Triangle <'b> {
mat: &'b Box<dyn Material>,
bounding_box: Option<BoundingBox>,
p: Vec<Point3<f64>>,
n: Vec<Vector3<f64>>,
uv: Vec<Vector2<f64>>,
}
包含对其关联网格的材质的引用,这是克隆不喜欢的。 我可以复制材质本身,但它可能非常大,我不希望网格中的每个三角形都有数千个副本。
我觉得必须有更好的方法来设计我的系统,比如去掉Triangle
中的引用,以便可以轻松复制它。 创建此结构后,我将不再需要Vec
,因此能够move
对象移出其中并复制它们也可以,但我也没有办法做到这一点。
如果有帮助,完整文件在GitHub上
我能够通过将objects
Vec 更改为&mut Vec<Box<dyn Hittable>>
然后使用objects.remove()
而不是对其进行索引来解决此问题。 我不得不稍微改变算法来处理新的方式,但它应该可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.