impl<A> BspSplitter<A> where
A: Copy + fmt::Debug + Default,
{ /// Put the splitter back in it initial state. /// /// Call this at the beginning of every frame when reusing the splitter. pubfn reset(&mutself) { self.polygons.clear(); self.nodes.clear(); self.nodes.push(BspNode::new());
}
/// Add a polygon to the plane splitter. /// /// This is where most of the expensive computation happens. pubfn add(&mutself, poly: Polygon<A>) { let root = NodeIdx(0); self.insert(root, &poly);
}
/// Sort the added and split polygons against the view vector. /// /// Call this towards the end of the frame after having added all polygons. pubfn sort(&mutself, view: Vector3D<f64>) -> &[Polygon<A>] { //debug!("\t\ttree before sorting {:?}", self.tree); let poly = Polygon {
points: [Point3D::origin(); 4],
plane: Plane {
normal: -view, //Note: BSP `order()` is back to front
offset: 0.0,
},
anchor: A::default(),
};
let root = NodeIdx(0); letmut result = std::mem::take(&mutself.result);
result.clear(); self.order(root, &poly, &mut result); self.result = result;
&self.result
}
/// Process a set of polygons at once. pubfn solve(&mutself, input: &[Polygon<A>], view: Vector3D<f64>) -> &[Polygon<A>] where
A: Copy,
{ self.reset(); for p in input { self.add(p.clone());
} self.sort(view)
}
/// Insert a value into the sub-tree starting with this node. /// This operation may spawn additional leafs/branches of the tree. fn insert(&mutself, node_idx: NodeIdx, value: &Polygon<A>) { let node = &mutself.nodes[node_idx.0]; if node.values.is_empty() {
node.values.push(add_polygon(&mutself.polygons, value)); return;
}
letmut front: SmallVec<[Polygon<A>; 2]> = SmallVec::new(); letmut back: SmallVec<[Polygon<A>; 2]> = SmallVec::new(); let first = node.values[0].0; matchself.polygons[first].cut(value, &mut front, &mut back) {
PlaneCut::Sibling => {
node.values.push(add_polygon(&mutself.polygons, value));
}
PlaneCut::Cut => { if front.len() != 0 { ifself.nodes[node_idx.0].front.is_none() { self.nodes[node_idx.0].front = Some(add_node(&mutself.nodes));
} let node_front = self.nodes[node_idx.0].front.unwrap(); for p in &front { self.insert(node_front, p)
}
} if back.len() != 0 { ifself.nodes[node_idx.0].back.is_none() { self.nodes[node_idx.0].back = Some(add_node(&mutself.nodes));
} let node_back = self.nodes[node_idx.0].back.unwrap(); for p in &back { self.insert(node_back, p)
}
}
}
}
}
/// Build the draw order of this sub-tree into an `out` vector, /// so that the contained planes are sorted back to front according /// to the view vector defined as the `base` plane front direction. pubfn order(&self, node: NodeIdx, base: &Polygon<A>, out: &mut Vec<Polygon<A>>) { let node = &self.nodes[node.0]; let (former, latter) = match node.values.first() {
None => return,
Some(first) => { if base.is_aligned(&self.polygons[first.0]) {
(node.front, node.back)
} else {
(node.back, node.front)
}
}
};
iflet Some(node) = former { self.order(node, base, out);
}
out.reserve(node.values.len()); for poly_idx in &node.values {
out.push(self.polygons[poly_idx.0].clone());
}
pubfn add_polygon<A: Copy>(polygons: &mut Vec<Polygon<A>>, poly: &Polygon<A>) -> PolygonIdx { let index = PolygonIdx(polygons.len());
polygons.push(poly.clone());
index
}
pubfn add_node(nodes: &mut Vec<BspNode>) -> NodeIdx { let index = NodeIdx(nodes.len());
nodes.push(BspNode::new());
index
}
/// A node in the `BspTree`, which can be considered a tree itself. #[derive(Clone, Debug)] pubstruct BspNode {
values: SmallVec<[PolygonIdx; 4]>,
front: Option<NodeIdx>,
back: Option<NodeIdx>,
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.