mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
prevent crash when sprite particle renderer is flattened accidentally
This commit is contained in:
parent
3e66211e38
commit
168d499af6
@ -895,11 +895,12 @@ finish_decal() {
|
||||
// are ok, false to abort this group of primitives.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
begin_draw_primitives(const Geom *, const GeomMunger *munger,
|
||||
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
const GeomVertexData *data) {
|
||||
_munger = munger;
|
||||
_vertex_data = data;
|
||||
|
||||
nassertr(geom->check_valid(data), false);
|
||||
return _vertex_data->has_vertex();
|
||||
}
|
||||
|
||||
|
@ -593,7 +593,7 @@ get_num_bytes() const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::transform_vertices
|
||||
// Access: Published, Virtual
|
||||
// Access: Published
|
||||
// Description: Applies the indicated transform to all of the
|
||||
// vertices in the Geom. If the Geom happens to share a
|
||||
// vertex table with another Geom, this operation will
|
||||
@ -652,6 +652,30 @@ check_valid() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::check_valid
|
||||
// Access: Published
|
||||
// Description: Verifies that the all of the primitives within the
|
||||
// geom reference vertices that actually exist within
|
||||
// the indicated GeomVertexData. Returns true if the
|
||||
// geom appears to be valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Geom::
|
||||
check_valid(const GeomVertexData *vertex_data) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
if (!(*pi)->check_valid(vertex_data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::output
|
||||
// Access: Published, Virtual
|
||||
|
@ -96,11 +96,9 @@ PUBLISHED:
|
||||
int get_num_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
// Temporarily virtual.
|
||||
virtual void transform_vertices(const LMatrix4f &mat);
|
||||
|
||||
// Temporarily virtual.
|
||||
virtual bool check_valid() const;
|
||||
bool check_valid(const GeomVertexData *vertex_data) const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
@ -530,6 +530,8 @@ init_geoms() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nassertv(render_node->check_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -726,9 +728,21 @@ render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
|
||||
}
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
GeomNode *render_node = get_render_node();
|
||||
|
||||
for (i = 0; i < anim_count; ++i) {
|
||||
for (j = 0; j < _anim_size[i]; ++j) {
|
||||
_sprites[i][j]->clear_vertices();
|
||||
|
||||
// We have to reassign the GeomVertexData and GeomPrimitive to
|
||||
// the Geom, and the Geom to the GeomNode, in case it got
|
||||
// flattened away.
|
||||
_sprite_primitive[i][j]->set_primitive(0, _sprites[i][j]);
|
||||
_sprite_primitive[i][j]->set_vertex_data(_vdata[i][j]);
|
||||
|
||||
render_node->set_geom(n, _sprite_primitive[i][j]);
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,11 +764,13 @@ render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
|
||||
|
||||
for (i = 0; i < anim_count; ++i) {
|
||||
for (j = 0; j < _anim_size[i]; ++j) {
|
||||
nassertv(_sprite_primitive[i][j]->check_valid());
|
||||
_sprite_primitive[i][j]->set_bound(BoundingSphere(aabb_center, radius));
|
||||
}
|
||||
}
|
||||
|
||||
get_render_node()->mark_bound_stale();
|
||||
nassertv(render_node->check_valid());
|
||||
_animation_removed = false;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
||||
if (_geom != (Geom *)NULL) {
|
||||
_munger = munger;
|
||||
_munged_data = _geom->get_vertex_data();
|
||||
nassertv(_geom->check_valid(_munged_data));
|
||||
|
||||
int geom_rendering = _geom->get_geom_rendering();
|
||||
geom_rendering = _state->get_geom_rendering(geom_rendering);
|
||||
@ -305,9 +306,10 @@ munge_points_to_quads(const CullTraverser *traverser) {
|
||||
int num_primitives = _geom->get_num_primitives();
|
||||
for (int pi = 0; pi < num_primitives; ++pi) {
|
||||
const GeomPrimitive *primitive = _geom->get_primitive(pi);
|
||||
|
||||
if (primitive->get_num_vertices() != 0) {
|
||||
// We must first convert all of the points to eye space.
|
||||
int num_points = primitive->get_max_vertex() + 1;
|
||||
|
||||
int num_vertices = primitive->get_num_vertices();
|
||||
PointData *points = (PointData *)alloca(num_points * sizeof(PointData));
|
||||
unsigned int *vertices = (unsigned int *)alloca(num_vertices * sizeof(unsigned int));
|
||||
@ -331,7 +333,7 @@ munge_points_to_quads(const CullTraverser *traverser) {
|
||||
unsigned int v = i + first_vertex;
|
||||
nassertv(v < (unsigned int)num_points);
|
||||
vertices[i] = v;
|
||||
vertex.set_row(i + first_vertex);
|
||||
vertex.set_row(v);
|
||||
points[v]._eye = modelview.xform_point(vertex.get_data3f());
|
||||
points[v]._dist = gsg->compute_distance_to(points[v]._eye);
|
||||
}
|
||||
@ -459,6 +461,7 @@ munge_points_to_quads(const CullTraverser *traverser) {
|
||||
|
||||
new_geom->add_primitive(new_primitive);
|
||||
}
|
||||
}
|
||||
|
||||
_geom = new_geom.p();
|
||||
_munged_data = new_data;
|
||||
|
@ -420,6 +420,45 @@ add_geoms_from(const GeomNode *other) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::set_geom
|
||||
// Access: Public
|
||||
// Description: Replaces the nth Geom of the node with a new pointer.
|
||||
// There must already be a Geom in this slot.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomNode::
|
||||
set_geom(int n, Geom *geom) {
|
||||
nassertv(geom != (Geom *)NULL);
|
||||
nassertv(geom->check_valid());
|
||||
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(n >= 0 && n < (int)cdata->_geoms.size());
|
||||
cdata->_geoms[n]._geom = geom;
|
||||
|
||||
mark_bound_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::check_valid
|
||||
// Access: Published
|
||||
// Description: Verifies that the each Geom within the GeomNode
|
||||
// reference vertices that actually exist within its
|
||||
// GeomVertexData. Returns true if the GeomNode appears
|
||||
// to be valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomNode::
|
||||
check_valid() const {
|
||||
int num_geoms = get_num_geoms();
|
||||
for (int i = 0; i < num_geoms; i++) {
|
||||
const Geom *geom = get_geom(i);
|
||||
if (!geom->check_valid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::unify
|
||||
// Access: Published
|
||||
|
@ -65,8 +65,10 @@ PUBLISHED:
|
||||
|
||||
int add_geom(Geom *geom, const RenderState *state = RenderState::make_empty());
|
||||
void add_geoms_from(const GeomNode *other);
|
||||
void set_geom(int n, Geom *geom);
|
||||
INLINE void remove_geom(int n);
|
||||
INLINE void remove_all_geoms();
|
||||
bool check_valid() const;
|
||||
|
||||
void unify();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user