fix crashes

This commit is contained in:
David Rose 2005-03-14 21:41:24 +00:00
parent 3b7565e025
commit 6b54ff8fb9
28 changed files with 915 additions and 877 deletions

View File

@ -73,7 +73,7 @@
eggTriangleStrip.cxx \
eggUserData.cxx \
eggUtilities.cxx eggVertex.cxx eggVertexPool.cxx eggVertexUV.cxx \
eggXfmAnimData.cxx eggXfmSAnim.cxx xx xx pt_EggMaterial.cxx \
eggXfmAnimData.cxx eggXfmSAnim.cxx pt_EggMaterial.cxx \
vector_PT_EggMaterial.cxx pt_EggTexture.cxx \
vector_PT_EggTexture.cxx pt_EggVertex.cxx \
vector_PT_EggVertex.cxx

View File

@ -17,6 +17,7 @@
////////////////////////////////////////////////////////////////////
#include "eggCompositePrimitive.h"
#include "eggGroupNode.h"
TypeHandle EggCompositePrimitive::_type_handle;
@ -113,10 +114,10 @@ write_body(ostream &out, int indent_level) const {
for (int i = 0; i < get_num_components(); i++) {
const EggAttributes *attrib = get_component(i);
if (attrib->compare_to(*this) != 0) {
indent(out, indent_level + 2)
indent(out, indent_level)
<< "<Component> " << i << " {\n";
attrib->write(out, indent_level + 4);
indent(out, indent_level + 2) << "}\n";
attrib->write(out, indent_level + 2);
indent(out, indent_level) << "}\n";
}
}
}

View File

@ -305,8 +305,8 @@ set_coordinate_system(CoordinateSystem new_coordsys) {
////////////////////////////////////////////////////////////////////
void EggData::
write(ostream &out, int indent_level) const {
EggCoordinateSystem ecs(_coordsys);
ecs.write(out, indent_level);
PT(EggCoordinateSystem) ecs = new EggCoordinateSystem(_coordsys);
ecs->write(out, indent_level);
EggGroupNode::write(out, indent_level);
out << flush;
}

View File

@ -25,6 +25,7 @@
#include "indent.h"
#include "string_utils.h"
#include "lmatrix.h"
#include "dcast.h"
TypeHandle EggGroup::_type_handle;
@ -61,14 +62,14 @@ operator = (const EggGroup &copy) {
EggTransform3d::operator = (copy);
_flags = copy._flags;
_flags2 = copy._flags2;
_collide_mask = copy._collide_mask;
_from_collide_mask = copy._from_collide_mask;
_into_collide_mask = copy._into_collide_mask;
_billboard_center = copy._billboard_center;
// _collide_mask = copy._collide_mask;
// _from_collide_mask = copy._from_collide_mask;
// _into_collide_mask = copy._into_collide_mask;
// _billboard_center = copy._billboard_center;
_object_types = copy._object_types;
_collision_name = copy._collision_name;
_fps = copy._fps;
_lod = copy._lod;
// _lod = copy._lod;
_tag_data = copy._tag_data;

View File

@ -35,6 +35,7 @@
#include "dSearchPath.h"
#include "deg_2_rad.h"
#include "dcast.h"
#include <algorithm>
@ -282,6 +283,7 @@ get_next_child() {
////////////////////////////////////////////////////////////////////
EggNode *EggGroupNode::
add_child(EggNode *node) {
test_ref_count_integrity();
PT(EggNode) ptnode = node;
if (node->_parent != NULL) {
node->_parent->remove_child(node);

View File

@ -22,6 +22,7 @@
#include "eggMaterial.h"
#include "nameUniquifier.h"
#include "dcast.h"
#include <algorithm>

View File

@ -21,6 +21,8 @@
#include "eggCompositePrimitive.h"
#include "eggTriangleStrip.h"
#include "config_egg.h"
#include "eggGroupNode.h"
#include "dcast.h"
#include <stdlib.h>

View File

@ -17,6 +17,7 @@
////////////////////////////////////////////////////////////////////
#include "eggMesherEdge.h"
#include "eggMesherStrip.h"
////////////////////////////////////////////////////////////////////
// Function: EggMesherEdge::remove

View File

@ -19,7 +19,10 @@
#include "eggMesherStrip.h"
#include "eggMesherEdge.h"
#include "eggPrimitive.h"
#include "eggTriangleStrip.h"
#include "eggPolygon.h"
#include "dcast.h"
#include "config_egg.h"
////////////////////////////////////////////////////////////////////
// Function: EggMesherStrip::Constructor
@ -118,8 +121,6 @@ make_prim(const EggVertexPool *vertex_pool) {
prim = new EggTriangleStrip;
prim->copy_attributes(*_prims.front());
PrimType type = dest_type;
// Now store all the vertices. Each individual triangle's
// attributes, if any, get applied to the third vertex of each
// triangle.
@ -140,7 +141,7 @@ make_prim(const EggVertexPool *vertex_pool) {
// with the third completes a triangle.
const EggAttributes *attrib = (*pi);
++pi;
// prim->set_component(count - 2, *attrib);
DCAST(EggCompositePrimitive, prim)->set_component(count - 3, attrib);
}
}

View File

@ -21,16 +21,18 @@
#include "pandabase.h"
#include "eggVertexPool.h"
#include "eggPrimitive.h"
#include "eggMesherEdge.h"
#include "plist.h"
class EggMesherEdge;
///////////////////////////////////////////////////////////////////
// Class : EggMesherStrip
// Description : Represents a triangle strip in progress, as assembled
// by the mesher. It might also represent a single
// polygon such as a triangle or quad, since that's how
// all triangle strips start out.
// Description : Represents a triangle strip or quad strip in
// progress, as assembled by the mesher. It might also
// represent a single polygon such as a triangle or
// quad, since that's how strips generally start out.
////////////////////////////////////////////////////////////////////
class EggMesherStrip {
public:

View File

@ -68,7 +68,7 @@ INLINE EggMorphList<MorphType>::
template<class MorphType>
INLINE bool EggMorphList<MorphType>::
operator == (const EggMorphList<MorphType> &other) const {
return compare_to(other) == 0;
return (_morphs == other._morphs);
}
////////////////////////////////////////////////////////////////////
@ -79,7 +79,7 @@ operator == (const EggMorphList<MorphType> &other) const {
template<class MorphType>
INLINE bool EggMorphList<MorphType>::
operator != (const EggMorphList<MorphType> &other) const {
return compare_to(other) != 0;
return (_morphs != other._morphs);
}
////////////////////////////////////////////////////////////////////
@ -90,18 +90,20 @@ operator != (const EggMorphList<MorphType> &other) const {
template<class MorphType>
INLINE bool EggMorphList<MorphType>::
operator < (const EggMorphList<MorphType> &other) const {
return compare_to(other) < 0;
return (_morphs < other._morphs);
}
////////////////////////////////////////////////////////////////////
// Function: EggMorphList::compare_to
// Access: Public
// Description:
// Description: compare_to() compares a different space than the
// operator methods, which only check the morph's name.
// compare_to() compares the name and the value as well.
////////////////////////////////////////////////////////////////////
template<class MorphType>
int EggMorphList<MorphType>::
compare_to(const EggMorphList<MorphType> &other) const {
if (_morphs.size() < other._morphs.size()) {
if (_morphs.size() != other._morphs.size()) {
return (int)_morphs.size() - (int)other._morphs.size();
}
for (size_t i = 0; i < _morphs.size(); i++) {

View File

@ -19,6 +19,8 @@
#include "eggNameUniquifier.h"
#include "eggNode.h"
#include "eggGroupNode.h"
#include "config_egg.h"
#include "dcast.h"
#include "notify.h"

View File

@ -20,6 +20,7 @@
#include "eggGroupNode.h"
#include "config_egg.h"
#include "eggTextureCollection.h"
#include "dcast.h"
#include <algorithm>
@ -309,6 +310,7 @@ update_under(int depth_offset) {
_vertex_to_node = NULL;
_node_to_vertex = NULL;
} else {
_parent->test_ref_count_integrity();
depth = _parent->_depth + 1;
_under_flags = _parent->_under_flags;
_vertex_frame = _parent->_vertex_frame;

View File

@ -16,149 +16,3 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggObject::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggObject::
EggObject() {
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::Copy constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggObject::
EggObject(const EggObject &copy) :
TypedReferenceCount(copy),
_user_data(copy._user_data),
_default_user_data(copy._default_user_data)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::Copy assignment operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggObject &EggObject::
operator = (const EggObject &copy) {
TypedReferenceCount::operator = (copy);
_user_data = copy._user_data;
_default_user_data = copy._default_user_data;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::set_user_data
// Access: Public
// Description: Sets the user data associated with this object. This
// may be any EggUserData-derived object. The egg
// library will do nothing with this pointer, except to
// hold its reference count and return the pointer on
// request.
//
// The EggObject maintains multiple different
// EggUserData pointers, one for each unique type (as
// reported by get_type()). If you know that only one
// type of EggUserData object will be added in your
// application, you may use the query functions that
// accept no parameters, but it is recommended that in
// general you pass in the type of your particular user
// data, to allow multiple applications to coexist in
// the same egg data.
//
// This pointer is also copied by the copy assignment
// operator and copy constructor.
////////////////////////////////////////////////////////////////////
INLINE void EggObject::
set_user_data(EggUserData *user_data) {
_user_data[user_data->get_type()] = user_data;
_default_user_data = user_data;
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::get_user_data
// Access: Public
// Description: Returns the user data pointer most recently stored on
// this object, or NULL if nothing was previously
// stored.
////////////////////////////////////////////////////////////////////
INLINE EggUserData *EggObject::
get_user_data() const {
return _default_user_data;
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::get_user_data
// Access: Public
// Description: Returns the user data pointer of the indicated type,
// if it exists, or NULL if it does not.
////////////////////////////////////////////////////////////////////
INLINE EggUserData *EggObject::
get_user_data(TypeHandle type) const {
UserData::const_iterator ui;
ui = _user_data.find(type);
if (ui != _user_data.end()) {
return (*ui).second;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::has_user_data
// Access: Public
// Description: Returns true if a generic user data pointer has
// recently been set and not yet cleared, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool EggObject::
has_user_data() const {
return !_default_user_data.is_null();
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::has_user_data
// Access: Public
// Description: Returns true if the user data pointer of the
// indicated type has been set, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool EggObject::
has_user_data(TypeHandle type) const {
UserData::const_iterator ui;
ui = _user_data.find(type);
return (ui != _user_data.end());
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::clear_user_data
// Access: Public
// Description: Removes *all* user data pointers from the node.
////////////////////////////////////////////////////////////////////
INLINE void EggObject::
clear_user_data() {
_user_data.clear();
_default_user_data.clear();
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::clear_user_data
// Access: Public
// Description: Removes the user data pointer of the indicated type.
////////////////////////////////////////////////////////////////////
INLINE void EggObject::
clear_user_data(TypeHandle type) {
UserData::iterator ui;
ui = _user_data.find(type);
if (ui != _user_data.end()) {
if ((*ui).second == _default_user_data) {
_default_user_data.clear();
}
_user_data.erase(ui);
}
}

View File

@ -21,11 +21,157 @@
TypeHandle EggObject::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggObject::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
EggObject::
EggObject() {
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::Copy constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
EggObject::
EggObject(const EggObject &copy) :
TypedReferenceCount(copy),
_user_data(copy._user_data),
_default_user_data(copy._default_user_data)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::Copy assignment operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
EggObject &EggObject::
operator = (const EggObject &copy) {
TypedReferenceCount::operator = (copy);
_user_data = copy._user_data;
_default_user_data = copy._default_user_data;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::Destructor
// Access: Public, Virtual
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
EggObject::
~EggObject() {
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::set_user_data
// Access: Published
// Description: Sets the user data associated with this object. This
// may be any EggUserData-derived object. The egg
// library will do nothing with this pointer, except to
// hold its reference count and return the pointer on
// request.
//
// The EggObject maintains multiple different
// EggUserData pointers, one for each unique type (as
// reported by get_type()). If you know that only one
// type of EggUserData object will be added in your
// application, you may use the query functions that
// accept no parameters, but it is recommended that in
// general you pass in the type of your particular user
// data, to allow multiple applications to coexist in
// the same egg data.
//
// This pointer is also copied by the copy assignment
// operator and copy constructor.
////////////////////////////////////////////////////////////////////
void EggObject::
set_user_data(EggUserData *user_data) {
_user_data[user_data->get_type()] = user_data;
_default_user_data = user_data;
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::get_user_data
// Access: Published
// Description: Returns the user data pointer most recently stored on
// this object, or NULL if nothing was previously
// stored.
////////////////////////////////////////////////////////////////////
EggUserData *EggObject::
get_user_data() const {
return _default_user_data;
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::get_user_data
// Access: Published
// Description: Returns the user data pointer of the indicated type,
// if it exists, or NULL if it does not.
////////////////////////////////////////////////////////////////////
EggUserData *EggObject::
get_user_data(TypeHandle type) const {
UserData::const_iterator ui;
ui = _user_data.find(type);
if (ui != _user_data.end()) {
return (*ui).second;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::has_user_data
// Access: Published
// Description: Returns true if a generic user data pointer has
// recently been set and not yet cleared, false
// otherwise.
////////////////////////////////////////////////////////////////////
bool EggObject::
has_user_data() const {
return !_default_user_data.is_null();
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::has_user_data
// Access: Published
// Description: Returns true if the user data pointer of the
// indicated type has been set, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggObject::
has_user_data(TypeHandle type) const {
UserData::const_iterator ui;
ui = _user_data.find(type);
return (ui != _user_data.end());
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::clear_user_data
// Access: Published
// Description: Removes *all* user data pointers from the node.
////////////////////////////////////////////////////////////////////
void EggObject::
clear_user_data() {
_user_data.clear();
_default_user_data.clear();
}
////////////////////////////////////////////////////////////////////
// Function: EggObject::clear_user_data
// Access: Published
// Description: Removes the user data pointer of the indicated type.
////////////////////////////////////////////////////////////////////
void EggObject::
clear_user_data(TypeHandle type) {
UserData::iterator ui;
ui = _user_data.find(type);
if (ui != _user_data.end()) {
if ((*ui).second == _default_user_data) {
_default_user_data.clear();
}
_user_data.erase(ui);
}
}

View File

@ -32,19 +32,19 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEGG EggObject : public TypedReferenceCount {
PUBLISHED:
INLINE EggObject();
INLINE EggObject(const EggObject &copy);
INLINE EggObject &operator = (const EggObject &copy);
EggObject();
EggObject(const EggObject &copy);
EggObject &operator = (const EggObject &copy);
virtual ~EggObject();
INLINE void set_user_data(EggUserData *user_data);
INLINE EggUserData *get_user_data() const;
INLINE EggUserData *get_user_data(TypeHandle type) const;
INLINE bool has_user_data() const;
INLINE bool has_user_data(TypeHandle type) const;
INLINE void clear_user_data();
INLINE void clear_user_data(TypeHandle type);
void set_user_data(EggUserData *user_data);
EggUserData *get_user_data() const;
EggUserData *get_user_data(TypeHandle type) const;
bool has_user_data() const;
bool has_user_data(TypeHandle type) const;
void clear_user_data();
void clear_user_data(TypeHandle type);
private:
typedef pmap<TypeHandle, PT(EggUserData) > UserData;

View File

@ -21,6 +21,7 @@
#include "eggPrimitive.h"
#include "eggTexture.h"
#include "pt_EggTexture.h"
#include "dcast.h"
#include "nameUniquifier.h"

View File

@ -20,6 +20,7 @@
#include "eggPrimitive.h"
#include "eggGroupNode.h"
#include "pt_EggTexture.h"
#include "dcast.h"
////////////////////////////////////////////////////////////////////

View File

@ -26,6 +26,7 @@
#include "luse.h"
#include "lmatrix.h"
#include "compose_matrix.h"
#include "dcast.h"
TypeHandle EggXfmAnimData::_type_handle;

View File

@ -24,6 +24,7 @@
#include "indent.h"
#include "compose_matrix.h"
#include "dcast.h"
#include <math.h>

File diff suppressed because it is too large Load Diff

View File

@ -228,6 +228,7 @@ egg:
empty
| egg node
{
assert(!egg_stack.empty());
DCAST(EggData, egg_stack.back())->add_child(DCAST(EggNode, $2));
}
;
@ -1713,7 +1714,6 @@ primitive_component_body:
*/
primitive_body:
empty
| primitive_body COMPONENT '{' primitive_component_body '}'
| primitive_body COMPONENT integer '{'
{
if (!egg_stack.back()->is_of_type(EggCompositePrimitive::get_class_type())) {
@ -1723,17 +1723,17 @@ primitive_body:
if ($3 < 0 || $3 >= comp->get_num_components()) {
eggyyerror("Invalid component number");
}
// We temporarily add an EggPolygon to the stack, just to receive
// the component attributes.
egg_stack.push_back(new EggPolygon);
}
// We temporarily add an EggPolygon to the stack, just to receive
// the component attributes.
egg_stack.push_back(new EggPolygon);
}
primitive_component_body '}'
{
PT(EggPrimitive) prim = DCAST(EggPrimitive, egg_stack.back());
egg_stack.pop_back();
PT(EggCompositePrimitive) comp = DCAST(EggCompositePrimitive, egg_stack.back());
comp->set_component($3, prim);
comp->set_component((int)$3, prim);
}
| primitive_body TREF '{' primitive_tref_body '}'
| primitive_body TEXTURE '{' primitive_texture_body '}'

View File

@ -126,7 +126,8 @@ LODInstance(EggNode *egg_node) {
EggLoader::
EggLoader() {
// We need to enforce whatever coordinate system the user asked for.
_data.set_coordinate_system(egg_coordinate_system);
_data = new EggData;
_data->set_coordinate_system(egg_coordinate_system);
_error = false;
}
@ -137,7 +138,7 @@ EggLoader() {
////////////////////////////////////////////////////////////////////
EggLoader::
EggLoader(const EggData &data) :
_data(data)
_data(new EggData(data))
{
_error = false;
}
@ -157,11 +158,11 @@ build_graph() {
// Then bin up the polysets and LOD nodes.
EggBinner binner(*this);
binner.make_bins(&_data);
binner.make_bins(_data);
// Now build up the scene graph.
_root = new ModelRoot(_data.get_egg_filename().get_basename());
make_node(&_data, _root);
_root = new ModelRoot(_data->get_egg_filename().get_basename());
make_node(_data, _root);
_builder.build();
reparent_decals();
@ -735,7 +736,7 @@ void EggLoader::
load_textures() {
// First, collect all the textures that are referenced.
EggTextureCollection tc;
tc.find_used_textures(&_data);
tc.find_used_textures(_data);
EggTextureCollection::iterator ti;
for (ti = tc.begin(); ti != tc.end(); ++ti) {

View File

@ -210,7 +210,7 @@ private:
public:
PT(PandaNode) _root;
EggData _data;
PT(EggData) _data;
bool _error;
friend class EggRenderState;

View File

@ -25,7 +25,7 @@
static PT(PandaNode)
load_from_loader(EggLoader &loader) {
loader._data.load_externals();
loader._data->load_externals();
loader.build_graph();
@ -85,9 +85,9 @@ load_egg_file(const string &filename, CoordinateSystem cs) {
EggLoader loader;
loader._data.set_egg_filename(egg_filename);
loader._data.set_auto_resolve_externals(true);
loader._data.set_coordinate_system(cs);
loader._data->set_egg_filename(egg_filename);
loader._data->set_auto_resolve_externals(true);
loader._data->set_coordinate_system(cs);
bool okflag;
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
@ -97,7 +97,7 @@ load_egg_file(const string &filename, CoordinateSystem cs) {
<< "Could not open " << egg_filename << " for reading.\n";
return NULL;
}
okflag = loader._data.read(*istr);
okflag = loader._data->read(*istr);
vfs->close_read_file(istr);
if (!okflag) {
@ -124,10 +124,10 @@ load_egg_data(EggData &data, CoordinateSystem cs) {
children_holder.steal_children(data);
EggLoader loader(data);
loader._data.steal_children(children_holder);
loader._data->steal_children(children_holder);
loader._data.set_auto_resolve_externals(true);
loader._data.set_coordinate_system(cs);
loader._data->set_auto_resolve_externals(true);
loader._data->set_coordinate_system(cs);
return load_from_loader(loader);
}

View File

@ -499,6 +499,7 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
express_cat.error()
<< "Attempt to update type to " << type << " for unrecorded pointer "
<< (void *)ptr << "!\n";
nassertv(false);
return;
}

View File

@ -141,9 +141,10 @@ close_primitive() {
if (num_vertices_per_primitive == 0) {
// This is a complex primitive type like a triangle strip: each
// primitive uses a different number of vertices.
if (cdata->_lengths.empty() ||
cdata->_lengths.back() != (int)cdata->_vertices.size()) {
if (cdata->_lengths.empty()) {
cdata->_lengths.push_back((int)cdata->_vertices.size());
} else if (cdata->_lengths.back() != (int)cdata->_vertices.size()) {
cdata->_lengths.push_back((int)cdata->_vertices.size() - cdata->_lengths.back());
}
} else {

View File

@ -86,12 +86,17 @@ decompose_impl() {
CPTA_ushort::const_iterator vi;
vi = vertices.begin();
cerr << "starting vertices, size = " << vertices.size() << "\n";
CPTA_int::const_iterator li;
for (li = lengths.begin(); li != lengths.end(); ++li) {
int length = (*li);
cerr << "length = " << length << "\n";
nassertr(length >= 2, triangles.p());
nassertr(vi != vertices.end(), this);
int v0 = (*vi);
++vi;
nassertr(vi != vertices.end(), this);
int v1 = (*vi);
++vi;
bool reversed = false;
@ -107,6 +112,7 @@ decompose_impl() {
}
triangles->add_vertex(*vi);
v0 = v1;
nassertr(vi != vertices.end(), this);
v1 = *vi;
triangles->close_primitive();
++vi;