mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -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.
|
// are ok, false to abort this group of primitives.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool GraphicsStateGuardian::
|
bool GraphicsStateGuardian::
|
||||||
begin_draw_primitives(const Geom *, const GeomMunger *munger,
|
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||||
const GeomVertexData *data) {
|
const GeomVertexData *data) {
|
||||||
_munger = munger;
|
_munger = munger;
|
||||||
_vertex_data = data;
|
_vertex_data = data;
|
||||||
|
|
||||||
|
nassertr(geom->check_valid(data), false);
|
||||||
return _vertex_data->has_vertex();
|
return _vertex_data->has_vertex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ get_num_bytes() const {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Geom::transform_vertices
|
// Function: Geom::transform_vertices
|
||||||
// Access: Published, Virtual
|
// Access: Published
|
||||||
// Description: Applies the indicated transform to all of the
|
// Description: Applies the indicated transform to all of the
|
||||||
// vertices in the Geom. If the Geom happens to share a
|
// vertices in the Geom. If the Geom happens to share a
|
||||||
// vertex table with another Geom, this operation will
|
// vertex table with another Geom, this operation will
|
||||||
@ -652,6 +652,30 @@ check_valid() const {
|
|||||||
return true;
|
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
|
// Function: Geom::output
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
|
@ -96,11 +96,9 @@ PUBLISHED:
|
|||||||
int get_num_bytes() const;
|
int get_num_bytes() const;
|
||||||
INLINE UpdateSeq get_modified() const;
|
INLINE UpdateSeq get_modified() const;
|
||||||
|
|
||||||
// Temporarily virtual.
|
|
||||||
virtual void transform_vertices(const LMatrix4f &mat);
|
virtual void transform_vertices(const LMatrix4f &mat);
|
||||||
|
|
||||||
// Temporarily virtual.
|
|
||||||
virtual bool check_valid() const;
|
virtual bool check_valid() const;
|
||||||
|
bool check_valid(const GeomVertexData *vertex_data) const;
|
||||||
|
|
||||||
virtual void output(ostream &out) const;
|
virtual void output(ostream &out) const;
|
||||||
virtual void write(ostream &out, int indent_level = 0) 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 (i = 0; i < anim_count; ++i) {
|
||||||
for (j = 0; j < _anim_size[i]; ++j) {
|
for (j = 0; j < _anim_size[i]; ++j) {
|
||||||
_sprites[i][j]->clear_vertices();
|
_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 (i = 0; i < anim_count; ++i) {
|
||||||
for (j = 0; j < _anim_size[i]; ++j) {
|
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));
|
_sprite_primitive[i][j]->set_bound(BoundingSphere(aabb_center, radius));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_render_node()->mark_bound_stale();
|
get_render_node()->mark_bound_stale();
|
||||||
|
nassertv(render_node->check_valid());
|
||||||
_animation_removed = false;
|
_animation_removed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
|||||||
if (_geom != (Geom *)NULL) {
|
if (_geom != (Geom *)NULL) {
|
||||||
_munger = munger;
|
_munger = munger;
|
||||||
_munged_data = _geom->get_vertex_data();
|
_munged_data = _geom->get_vertex_data();
|
||||||
|
nassertv(_geom->check_valid(_munged_data));
|
||||||
|
|
||||||
int geom_rendering = _geom->get_geom_rendering();
|
int geom_rendering = _geom->get_geom_rendering();
|
||||||
geom_rendering = _state->get_geom_rendering(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();
|
int num_primitives = _geom->get_num_primitives();
|
||||||
for (int pi = 0; pi < num_primitives; ++pi) {
|
for (int pi = 0; pi < num_primitives; ++pi) {
|
||||||
const GeomPrimitive *primitive = _geom->get_primitive(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.
|
// We must first convert all of the points to eye space.
|
||||||
int num_points = primitive->get_max_vertex() + 1;
|
int num_points = primitive->get_max_vertex() + 1;
|
||||||
|
|
||||||
int num_vertices = primitive->get_num_vertices();
|
int num_vertices = primitive->get_num_vertices();
|
||||||
PointData *points = (PointData *)alloca(num_points * sizeof(PointData));
|
PointData *points = (PointData *)alloca(num_points * sizeof(PointData));
|
||||||
unsigned int *vertices = (unsigned int *)alloca(num_vertices * sizeof(unsigned int));
|
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;
|
unsigned int v = i + first_vertex;
|
||||||
nassertv(v < (unsigned int)num_points);
|
nassertv(v < (unsigned int)num_points);
|
||||||
vertices[i] = v;
|
vertices[i] = v;
|
||||||
vertex.set_row(i + first_vertex);
|
vertex.set_row(v);
|
||||||
points[v]._eye = modelview.xform_point(vertex.get_data3f());
|
points[v]._eye = modelview.xform_point(vertex.get_data3f());
|
||||||
points[v]._dist = gsg->compute_distance_to(points[v]._eye);
|
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);
|
new_geom->add_primitive(new_primitive);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_geom = new_geom.p();
|
_geom = new_geom.p();
|
||||||
_munged_data = new_data;
|
_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
|
// Function: GeomNode::unify
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -65,8 +65,10 @@ PUBLISHED:
|
|||||||
|
|
||||||
int add_geom(Geom *geom, const RenderState *state = RenderState::make_empty());
|
int add_geom(Geom *geom, const RenderState *state = RenderState::make_empty());
|
||||||
void add_geoms_from(const GeomNode *other);
|
void add_geoms_from(const GeomNode *other);
|
||||||
|
void set_geom(int n, Geom *geom);
|
||||||
INLINE void remove_geom(int n);
|
INLINE void remove_geom(int n);
|
||||||
INLINE void remove_all_geoms();
|
INLINE void remove_all_geoms();
|
||||||
|
bool check_valid() const;
|
||||||
|
|
||||||
void unify();
|
void unify();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user