fix calc_tight_bounds(), add NodePath::show_tight_bounds()
This commit is contained in:
parent
9946ffe1ab
commit
5e8855ebc8
|
|
@ -1142,7 +1142,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
|||
if (got_mat) {
|
||||
for (int i = 0; i < cdata->_num_vertices; i++) {
|
||||
reader.set_row(cdata->_first_vertex + i);
|
||||
const LVecBase3f &vertex = reader.get_data3f();
|
||||
LPoint3f vertex = mat.xform_point(reader.get_data3f());
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
|
|
@ -1160,7 +1160,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
|||
} else {
|
||||
for (int i = 0; i < cdata->_num_vertices; i++) {
|
||||
reader.set_row(cdata->_first_vertex + i);
|
||||
LPoint3f vertex = mat.xform_point(reader.get_data3f());
|
||||
const LVecBase3f &vertex = reader.get_data3f();
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
|
|
@ -1184,7 +1184,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
|||
if (got_mat) {
|
||||
while (!index.is_at_end()) {
|
||||
reader.set_row(index.get_data1i());
|
||||
const LVecBase3f &vertex = reader.get_data3f();
|
||||
LPoint3f vertex = mat.xform_point(reader.get_data3f());
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
|
|
@ -1202,7 +1202,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
|||
} else {
|
||||
while (!index.is_at_end()) {
|
||||
reader.set_row(index.get_data1i());
|
||||
LPoint3f vertex = mat.xform_point(reader.get_data3f());
|
||||
const LVecBase3f &vertex = reader.get_data3f();
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "portalClipper.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomLinestrips.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
|
||||
PStatCollector CullTraverser::_nodes_pcollector("Nodes");
|
||||
|
|
@ -166,7 +167,7 @@ traverse(CullTraverserData &data) {
|
|||
if (node_effects->has_show_bounds()) {
|
||||
// If we should show the bounding volume for this node, make it
|
||||
// up now.
|
||||
show_bounds(data);
|
||||
show_bounds(data, node_effects->has_show_tight_bounds());
|
||||
}
|
||||
|
||||
data.apply_transform_and_state(this);
|
||||
|
|
@ -267,21 +268,35 @@ traverse_below(CullTraverserData &data) {
|
|||
// external bounding volume.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullTraverser::
|
||||
show_bounds(CullTraverserData &data) {
|
||||
show_bounds(CullTraverserData &data, bool tight) {
|
||||
PandaNode *node = data.node();
|
||||
|
||||
PT(Geom) bounds_viz = make_bounds_viz(node->get_bound());
|
||||
if (bounds_viz != (Geom *)NULL) {
|
||||
_geoms_pcollector.add_level(2);
|
||||
CullableObject *outer_viz =
|
||||
new CullableObject(bounds_viz, get_bounds_outer_viz_state(),
|
||||
data._render_transform);
|
||||
_cull_handler->record_object(outer_viz, this);
|
||||
if (tight) {
|
||||
PT(Geom) bounds_viz = make_tight_bounds_viz(node);
|
||||
|
||||
CullableObject *inner_viz =
|
||||
new CullableObject(bounds_viz, get_bounds_inner_viz_state(),
|
||||
data._render_transform);
|
||||
_cull_handler->record_object(inner_viz, this);
|
||||
if (bounds_viz != (Geom *)NULL) {
|
||||
_geoms_pcollector.add_level(1);
|
||||
CullableObject *outer_viz =
|
||||
new CullableObject(bounds_viz, get_bounds_outer_viz_state(),
|
||||
data._render_transform);
|
||||
_cull_handler->record_object(outer_viz, this);
|
||||
}
|
||||
|
||||
} else {
|
||||
PT(Geom) bounds_viz = make_bounds_viz(node->get_bound());
|
||||
|
||||
if (bounds_viz != (Geom *)NULL) {
|
||||
_geoms_pcollector.add_level(2);
|
||||
CullableObject *outer_viz =
|
||||
new CullableObject(bounds_viz, get_bounds_outer_viz_state(),
|
||||
data._render_transform);
|
||||
_cull_handler->record_object(outer_viz, this);
|
||||
|
||||
CullableObject *inner_viz =
|
||||
new CullableObject(bounds_viz, get_bounds_inner_viz_state(),
|
||||
data._render_transform);
|
||||
_cull_handler->record_object(inner_viz, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -305,7 +320,7 @@ make_bounds_viz(const BoundingVolume &vol) {
|
|||
static const int num_stacks = 8;
|
||||
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("collision", qpGeomVertexFormat::get_v3(),
|
||||
("bounds", qpGeomVertexFormat::get_v3(),
|
||||
qpGeom::UH_stream);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
|
|
@ -350,6 +365,67 @@ make_bounds_viz(const BoundingVolume &vol) {
|
|||
return geom;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::make_tight_bounds_viz
|
||||
// Access: Private
|
||||
// Description: Returns a bounding-box visualization of the indicated
|
||||
// node's "tight" bounding volume.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Geom) CullTraverser::
|
||||
make_tight_bounds_viz(PandaNode *node) {
|
||||
PT(Geom) geom;
|
||||
|
||||
NodePath np = NodePath::any_path(node);
|
||||
|
||||
LPoint3f n, x;
|
||||
bool found_any = false;
|
||||
node->calc_tight_bounds(n, x, found_any, TransformState::make_identity());
|
||||
if (found_any) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("bounds", qpGeomVertexFormat::get_v3(),
|
||||
qpGeom::UH_stream);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
vertex.add_data3f(n[0], n[1], n[2]);
|
||||
vertex.add_data3f(n[0], n[1], x[2]);
|
||||
vertex.add_data3f(n[0], x[1], n[2]);
|
||||
vertex.add_data3f(n[0], x[1], x[2]);
|
||||
vertex.add_data3f(x[0], n[1], n[2]);
|
||||
vertex.add_data3f(x[0], n[1], x[2]);
|
||||
vertex.add_data3f(x[0], x[1], n[2]);
|
||||
vertex.add_data3f(x[0], x[1], x[2]);
|
||||
|
||||
PT(qpGeomLinestrips) strip = new qpGeomLinestrips(qpGeom::UH_stream);
|
||||
|
||||
// We wind one long linestrip around the wireframe cube. This
|
||||
// does require backtracking a few times here and there.
|
||||
strip->add_vertex(0);
|
||||
strip->add_vertex(1);
|
||||
strip->add_vertex(3);
|
||||
strip->add_vertex(2);
|
||||
strip->add_vertex(0);
|
||||
strip->add_vertex(4);
|
||||
strip->add_vertex(5);
|
||||
strip->add_vertex(7);
|
||||
strip->add_vertex(6);
|
||||
strip->add_vertex(4);
|
||||
strip->add_vertex(6);
|
||||
strip->add_vertex(2);
|
||||
strip->add_vertex(3);
|
||||
strip->add_vertex(7);
|
||||
strip->add_vertex(5);
|
||||
strip->add_vertex(1);
|
||||
strip->close_primitive();
|
||||
|
||||
PT(qpGeom) qpgeom = new qpGeom;
|
||||
qpgeom->set_vertex_data(vdata);
|
||||
qpgeom->add_primitive(strip);
|
||||
geom = qpgeom.p();
|
||||
}
|
||||
|
||||
return geom;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::compute_point
|
||||
// Access: Private, Static
|
||||
|
|
@ -508,7 +584,7 @@ r_get_decals(CullTraverserData &data, CullableObject *decals) {
|
|||
if (node_effects->has_show_bounds()) {
|
||||
// If we should show the bounding volume for this node, make it
|
||||
// up now.
|
||||
show_bounds(data);
|
||||
show_bounds(data, node_effects->has_show_tight_bounds());
|
||||
}
|
||||
|
||||
data.apply_transform_and_state(this);
|
||||
|
|
|
|||
|
|
@ -95,8 +95,9 @@ public:
|
|||
static PStatCollector _geoms_pcollector;
|
||||
|
||||
private:
|
||||
void show_bounds(CullTraverserData &data);
|
||||
void show_bounds(CullTraverserData &data, bool tight);
|
||||
PT(Geom) make_bounds_viz(const BoundingVolume &vol);
|
||||
PT(Geom) make_tight_bounds_viz(PandaNode *node);
|
||||
static Vertexf compute_point(const BoundingSphere *sphere,
|
||||
float latitude, float longitude);
|
||||
CPT(RenderState) get_bounds_outer_viz_state();
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any,
|
|||
const qpGeom *qpgeom = DCAST(qpGeom, geom);
|
||||
qpgeom->calc_tight_bounds(min_point, max_point, found_any,
|
||||
qpgeom->get_vertex_data()->animate_vertices(),
|
||||
!transform->is_identity(), mat);
|
||||
!next_transform->is_identity(), mat);
|
||||
|
||||
} else {
|
||||
Geom::VertexIterator vi = geom->make_vertex_iterator();
|
||||
|
|
|
|||
|
|
@ -4710,7 +4710,23 @@ prepare_scene(GraphicsStateGuardianBase *gsg) {
|
|||
void NodePath::
|
||||
show_bounds() {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_effect(ShowBoundsEffect::make());
|
||||
node()->set_effect(ShowBoundsEffect::make(false));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::show_tight_bounds
|
||||
// Access: Published
|
||||
// Description: Similar to show_bounds(), this draws a bounding box
|
||||
// representing the "tight" bounds of this node and all
|
||||
// of its descendants. The bounding box is recomputed
|
||||
// every frame by reexamining all of the vertices; this
|
||||
// is far from efficient, but this is intended for
|
||||
// debugging.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
show_tight_bounds() {
|
||||
nassertv_always(!is_empty());
|
||||
node()->set_effect(ShowBoundsEffect::make(true));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -703,6 +703,7 @@ PUBLISHED:
|
|||
void prepare_scene(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
void show_bounds();
|
||||
void show_tight_bounds();
|
||||
void hide_bounds();
|
||||
PT(BoundingVolume) get_bounds() const;
|
||||
void force_recompute_bounds();
|
||||
|
|
|
|||
|
|
@ -183,6 +183,23 @@ has_show_bounds() const {
|
|||
return ((_flags & F_has_show_bounds) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderEffects::has_show_tight_bounds
|
||||
// Access: Public
|
||||
// Description: If has_show_bounds() returns true, this will return
|
||||
// true if the ShowBoundsEffect in question requests
|
||||
// showing a "tight" bound.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool RenderEffects::
|
||||
has_show_tight_bounds() const {
|
||||
if ((_flags & F_checked_show_bounds) == 0) {
|
||||
// We pretend this function is const, even though it transparently
|
||||
// modifies the internal show_bounds cache.
|
||||
((RenderEffects *)this)->determine_show_bounds();
|
||||
}
|
||||
return ((_flags & F_has_show_tight_bounds) != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderEffects::has_cull_callback
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -592,6 +592,10 @@ determine_show_bounds() {
|
|||
const RenderEffect *effect = get_effect(ShowBoundsEffect::get_class_type());
|
||||
if (effect != (const RenderEffect *)NULL) {
|
||||
_flags |= F_has_show_bounds;
|
||||
const ShowBoundsEffect *sba = DCAST(ShowBoundsEffect, effect);
|
||||
if (sba->get_tight()) {
|
||||
_flags |= F_has_show_tight_bounds;
|
||||
}
|
||||
}
|
||||
_flags |= F_checked_show_bounds;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ PUBLISHED:
|
|||
public:
|
||||
INLINE bool has_decal() const;
|
||||
INLINE bool has_show_bounds() const;
|
||||
INLINE bool has_show_tight_bounds() const;
|
||||
|
||||
INLINE bool has_cull_callback() const;
|
||||
void cull_callback(CullTraverser *trav, CullTraverserData &data,
|
||||
|
|
@ -148,10 +149,11 @@ private:
|
|||
F_has_decal = 0x0002,
|
||||
F_checked_show_bounds = 0x0004,
|
||||
F_has_show_bounds = 0x0008,
|
||||
F_checked_cull_callback = 0x0010,
|
||||
F_has_cull_callback = 0x0020,
|
||||
F_checked_adjust_transform = 0x0040,
|
||||
F_has_adjust_transform = 0x0080,
|
||||
F_has_show_tight_bounds = 0x0010,
|
||||
F_checked_cull_callback = 0x0020,
|
||||
F_has_cull_callback = 0x0040,
|
||||
F_checked_adjust_transform = 0x0080,
|
||||
F_has_adjust_transform = 0x0100,
|
||||
};
|
||||
int _flags;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,5 +24,19 @@
|
|||
// ShowBoundsEffect object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ShowBoundsEffect::
|
||||
ShowBoundsEffect() {
|
||||
ShowBoundsEffect() :
|
||||
_tight(false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShowBoundsEffect::get_tight
|
||||
// Access: Published
|
||||
// Description: Returns true if the "tight" flag was set, meaning the
|
||||
// effect should compute and draw the tight bounding-box
|
||||
// of the node's vertices every frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ShowBoundsEffect::
|
||||
get_tight() const {
|
||||
return _tight;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,9 @@ TypeHandle ShowBoundsEffect::_type_handle;
|
|||
// Description: Constructs a new ShowBoundsEffect object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderEffect) ShowBoundsEffect::
|
||||
make() {
|
||||
make(bool tight) {
|
||||
ShowBoundsEffect *effect = new ShowBoundsEffect;
|
||||
effect->_tight = tight;
|
||||
return return_new(effect);
|
||||
}
|
||||
|
||||
|
|
@ -64,25 +65,10 @@ safe_to_combine() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int ShowBoundsEffect::
|
||||
compare_to_impl(const RenderEffect *other) const {
|
||||
// All ShowBoundsEffects are equivalent--there are no properties to
|
||||
// store.
|
||||
return 0;
|
||||
}
|
||||
const ShowBoundsEffect *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShowBoundsEffect::make_default_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Intended to be overridden by derived ShowBoundsEffect
|
||||
// types to specify what the default property for a
|
||||
// ShowBoundsEffect of this type should be.
|
||||
//
|
||||
// This should return a newly-allocated ShowBoundsEffect of
|
||||
// the same type that corresponds to whatever the
|
||||
// standard default for this kind of ShowBoundsEffect is.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderEffect *ShowBoundsEffect::
|
||||
make_default_impl() const {
|
||||
return new ShowBoundsEffect;
|
||||
return (int)_tight - (int)ta->_tight;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -105,6 +91,7 @@ register_with_read_factory() {
|
|||
void ShowBoundsEffect::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderEffect::write_datagram(manager, dg);
|
||||
dg.add_bool(_tight);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -137,4 +124,5 @@ make_from_bam(const FactoryParams ¶ms) {
|
|||
void ShowBoundsEffect::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderEffect::fillin(scan, manager);
|
||||
_tight = scan.get_bool();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,12 +37,16 @@ private:
|
|||
INLINE ShowBoundsEffect();
|
||||
|
||||
PUBLISHED:
|
||||
static CPT(RenderEffect) make();
|
||||
static CPT(RenderEffect) make(bool tight = false);
|
||||
|
||||
INLINE bool get_tight() const;
|
||||
|
||||
protected:
|
||||
virtual bool safe_to_combine() const;
|
||||
virtual int compare_to_impl(const RenderEffect *other) const;
|
||||
virtual RenderEffect *make_default_impl() const;
|
||||
|
||||
private:
|
||||
bool _tight;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
|
|
|||
Loading…
Reference in New Issue