motiontrail: Calculate bounding volume much more efficiently

A lot of time was going into updating the bounding volume.
This commit is contained in:
rdb 2022-12-16 20:15:13 +01:00
parent 833c3d37f7
commit e08a502c88
3 changed files with 41 additions and 3 deletions

View File

@ -141,6 +141,7 @@ class MotionTrail(NodePath, DirectObject):
## parented to the MotionTrail itself, but can be reparented elsewhere
## if necessary.
self.geom_node = GeomNode("motion_trail")
self.geom_node.setBoundsType(BoundingVolume.BT_box)
self.geom_node_path = self.attachNewNode(self.geom_node)
node_path = self.geom_node_path

View File

@ -14,6 +14,7 @@
#include "directbase.h"
#include "cMotionTrail.h"
#include "renderState.h"
#include "boundingBox.h"
#include "colorAttrib.h"
#include "cmath.h"
@ -73,6 +74,10 @@ add_vertex(const LVector4 &vertex, const LVector4 &start_color,
motion_trail_vertex._v = v;
motion_trail_vertex._nurbs_curve_evaluator = new NurbsCurveEvaluator();
_vertex_list.push_back(std::move(motion_trail_vertex));
// Store the maximum distance from the origin, so we can calculate the bounds
// of the trail efficiently.
_vertex_bounds_radius = std::max(_vertex_bounds_radius, vertex.length());
}
/**
@ -230,7 +235,7 @@ add_geometry_quad(
*
*/
void CMotionTrail::
end_geometry() {
end_geometry(const LPoint3 &min_vertex, const LPoint3 &max_vertex) {
static CPT(RenderState) state;
if (state == nullptr) {
state = RenderState::make(ColorAttrib::make_vertex());
@ -240,7 +245,12 @@ end_geometry() {
_color_writer.clear();
_texture_writer.clear();
PT(BoundingBox) bounds = new BoundingBox(
min_vertex - LVector3(_vertex_bounds_radius * 2),
max_vertex + LVector3(_vertex_bounds_radius * 2));
PT(Geom) geometry = new Geom(_vertex_data);
geometry->set_bounds(bounds);
geometry->add_primitive(_triangles);
if (_geom_node) {
@ -319,6 +329,8 @@ update_motion_trail(PN_stdfloat current_time, const LMatrix4 &transform) {
PN_stdfloat delta_time;
CMotionTrailFrame last_motion_trail_frame;
LPoint3 min_vertex, max_vertex;
VertexList::iterator vertex_iterator;
// convert vertex list to vertex array
@ -383,6 +395,18 @@ update_motion_trail(PN_stdfloat current_time, const LMatrix4 &transform) {
nurbs_curve_evaluator = motion_trail_vertex_start->_nurbs_curve_evaluator;
nurbs_curve_evaluator->set_vertex(segment_index, v0);
// For efficiency, calculate this only for the first vertex, we add the
// diameter of the cross-section to this later.
if (segment_index == 0) {
min_vertex = v0.get_xyz();
max_vertex = min_vertex;
} else {
min_vertex = min_vertex.fmin(v0.get_xyz());
max_vertex = max_vertex.fmax(v0.get_xyz());
}
min_vertex = min_vertex.fmin(v2.get_xyz());
max_vertex = max_vertex.fmax(v2.get_xyz());
for (int vertex_segment_index = 0;
vertex_segment_index < total_vertex_segments;
++vertex_segment_index) {
@ -575,6 +599,18 @@ update_motion_trail(PN_stdfloat current_time, const LMatrix4 &transform) {
t0.set(st, motion_trail_vertex_start->_v);
t2.set(et, motion_trail_vertex_start->_v);
// For efficiency, calculate this only for the first vertex, we add the
// diameter of the cross-section to this later.
if (segment_index == 0) {
min_vertex = v0.get_xyz();
max_vertex = min_vertex;
} else {
min_vertex = min_vertex.fmin(v0.get_xyz());
max_vertex = max_vertex.fmax(v0.get_xyz());
}
min_vertex = min_vertex.fmin(v2.get_xyz());
max_vertex = max_vertex.fmax(v2.get_xyz());
for (int vertex_segment_index = 0;
vertex_segment_index < total_vertex_segments;
++vertex_segment_index) {
@ -611,7 +647,7 @@ update_motion_trail(PN_stdfloat current_time, const LMatrix4 &transform) {
}
}
end_geometry();
end_geometry(min_vertex, max_vertex);
delete[] vertex_array;
}

View File

@ -94,7 +94,7 @@ public:
const LPoint3 &v0, const LPoint3 &v1, const LPoint3 &v2, const LPoint3 &v3,
const LVector4 &c0, const LVector4 &c1, const LVector4 &c2, const LVector4 &c3,
const LVector2 &t0, const LVector2 &t1, const LVector2 &t2, const LVector2 &t3);
void end_geometry();
void end_geometry(const LPoint3 &min_vertex, const LPoint3 &max_vertex);
bool _active = true;
bool _enable = true;
@ -114,6 +114,7 @@ public:
VertexList _vertex_list;
typedef pdeque<CMotionTrailFrame> FrameList;
FrameList _frame_list;
PN_stdfloat _vertex_bounds_radius = 0.0f;
// parameters
PN_stdfloat _color_scale = 1.0f;