Browse Source

prevent egg files from being marked stale every time they re-scan textures

David Rose 22 years ago
parent
commit
fed6868843

+ 88 - 8
pandatool/src/egg-palettize/eggFile.cxx

@@ -35,6 +35,9 @@
 #include "bamWriter.h"
 #include "bamWriter.h"
 #include "executionEnvironment.h"
 #include "executionEnvironment.h"
 #include "dSearchPath.h"
 #include "dSearchPath.h"
+#include "indirectLess.h"
+
+#include <algorithm>
 
 
 TypeHandle EggFile::_type_handle;
 TypeHandle EggFile::_type_handle;
 
 
@@ -99,15 +102,16 @@ void EggFile::
 scan_textures() {
 scan_textures() {
   nassertv(_data != (EggData *)NULL);
   nassertv(_data != (EggData *)NULL);
 
 
+  // Extract the set of textures referenced by this egg file.
   EggTextureCollection tc;
   EggTextureCollection tc;
   tc.find_used_textures(_data);
   tc.find_used_textures(_data);
+  
+  // Make sure each tref name is unique within a given file.
+  tc.uniquify_trefs();
 
 
-  // Remove the old TextureReference objects.
-  Textures::iterator ti;
-  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
-    delete (*ti);
-  }
-  _textures.clear();
+  // Now build up a list of new TextureReference objects that
+  // represent the textures actually used and their uv range, etc.
+  Textures new_textures;
 
 
   EggTextureCollection::iterator eti;
   EggTextureCollection::iterator eti;
   for (eti = tc.begin(); eti != tc.end(); ++eti) {
   for (eti = tc.begin(); eti != tc.end(); ++eti) {
@@ -123,9 +127,77 @@ scan_textures() {
       delete ref;
       delete ref;
 
 
     } else {
     } else {
-      _textures.push_back(ref);
+      new_textures.push_back(ref);
+    }
+  }
+
+  // Sort the new references into order so we can compare them with
+  // the original references.
+  sort(new_textures.begin(), new_textures.end(), 
+       IndirectLess<TextureReference>());
+  
+  // Sort the original references too.  This should already be sorted
+  // from the previous run, but we might as well be neurotic about it.
+  sort(_textures.begin(), _textures.end(), 
+       IndirectLess<TextureReference>());
+
+  // Now go through and merge the lists.
+  Textures combined_textures;
+  Textures::const_iterator ai = _textures.begin();
+  Textures::const_iterator bi = new_textures.begin();
+
+  while (ai != _textures.end() && bi != new_textures.end()) {
+    TextureReference *aref = (*ai);
+    TextureReference *bref = (*bi);
+
+    if ((*aref) < (*bref)) {
+      // Here's a texture reference in the original list, but not in
+      // the new list.  Remove it.
+      delete aref;
+      ++ai;
+
+    } else if ((*bref) < (*aref)) {
+      // Here's a texture reference in the new list, but not in the
+      // original list.  Add it.
+      combined_textures.push_back(bref);
+      ++bi;
+
+    } else { // (*bref) == (*aref)
+      // Here's a texture reference that was in both lists.  Compare it.
+      if (aref->is_equivalent(*bref)) {
+        // It hasn't changed substantially, so keep the original
+        // (which still has the placement references from a previous
+        // pass).
+        combined_textures.push_back(aref);
+        delete bref;
+
+      } else {
+        // It has changed, so drop the original and keep the new one.
+        combined_textures.push_back(bref);
+        delete aref;
+      }
+      ++ai;
+      ++bi;
     }
     }
   }
   }
+
+  while (bi != new_textures.end()) {
+    TextureReference *bref = (*bi);
+    // Here's a texture reference in the new list, but not in the
+    // original list.  Add it.
+    combined_textures.push_back(bref);
+    ++bi;
+  }
+
+  while (ai != _textures.end()) {
+    TextureReference *aref = (*ai);
+    // Here's a texture reference in the original list, but not in
+    // the new list.  Remove it.
+    delete aref;
+    ++ai;
+  }
+
+  _textures.swap(combined_textures);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -306,7 +378,7 @@ build_cross_links() {
 
 
     // Actually, this may count the same egg file multiple times for a
     // Actually, this may count the same egg file multiple times for a
     // particular SourceTextureImage, since a given texture may be
     // particular SourceTextureImage, since a given texture may be
-    // reference multiples times within an egg file.  No harm done,
+    // referenced multiples times within an egg file.  No harm done,
     // however.
     // however.
     reference->get_source()->increment_egg_count();
     reference->get_source()->increment_egg_count();
   }
   }
@@ -706,4 +778,12 @@ fillin(DatagramIterator &scan, BamReader *manager) {
 
 
   _is_surprise = scan.get_bool();
   _is_surprise = scan.get_bool();
   _is_stale = scan.get_bool();
   _is_stale = scan.get_bool();
+
+  if (Palettizer::_read_pi_version < 11) {
+    // If this file was written by a version of egg-palettize prior to
+    // 11, we didn't store the tref names on the texture references.
+    // Since we need that information now, it follows that every egg
+    // file is stale.
+    _is_stale = true;
+  }
 }
 }

+ 2 - 1
pandatool/src/egg-palettize/palettizer.cxx

@@ -41,10 +41,11 @@ Palettizer *pal = (Palettizer *)NULL;
 // allows us to easily update egg-palettize to write out additional
 // allows us to easily update egg-palettize to write out additional
 // information to its pi file, without having it increment the bam
 // information to its pi file, without having it increment the bam
 // version number for all bam and boo files anywhere in the world.
 // version number for all bam and boo files anywhere in the world.
-int Palettizer::_pi_version = 10;
+int Palettizer::_pi_version = 11;
 // Updated to version 8 on 3/20/03 to remove extensions from texture key names.
 // Updated to version 8 on 3/20/03 to remove extensions from texture key names.
 // Updated to version 9 on 4/13/03 to add a few properties in various places.
 // Updated to version 9 on 4/13/03 to add a few properties in various places.
 // Updated to version 10 on 4/15/03 to add _alpha_file_channel.
 // Updated to version 10 on 4/15/03 to add _alpha_file_channel.
+// Updated to version 11 on 4/30/03 to add TextureReference::_tref_name
 
 
 int Palettizer::_min_pi_version = 8;
 int Palettizer::_min_pi_version = 8;
 // Dropped support for versions 7 and below on 7/14/03.
 // Dropped support for versions 7 and below on 7/14/03.

+ 71 - 0
pandatool/src/egg-palettize/textureReference.cxx

@@ -84,6 +84,7 @@ from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex) {
   _egg_file = egg_file;
   _egg_file = egg_file;
   _egg_tex = egg_tex;
   _egg_tex = egg_tex;
   _egg_data = data;
   _egg_data = data;
+  _tref_name = egg_tex->get_name();
 
 
   if (_egg_tex->has_transform()) {
   if (_egg_tex->has_transform()) {
     _tex_mat = _egg_tex->get_transform();
     _tex_mat = _egg_tex->get_transform();
@@ -166,6 +167,28 @@ get_texture() const {
   return _source_texture->get_texture();
   return _source_texture->get_texture();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: TextureReference::get_tref_name
+//       Access: Public
+//  Description: Returns the name of the EggTexture entry that
+//               references this texture.
+////////////////////////////////////////////////////////////////////
+const string &TextureReference::
+get_tref_name() const {
+  return _tref_name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextureReference::operator <
+//       Access: Public
+//  Description: Defines an ordering of TextureReference pointers in
+//               alphabetical order by their tref name.
+////////////////////////////////////////////////////////////////////
+bool TextureReference::
+operator < (const TextureReference &other) const {
+  return _tref_name < other._tref_name;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureReference::has_uvs
 //     Function: TextureReference::has_uvs
 //       Access: Public
 //       Access: Public
@@ -225,6 +248,48 @@ get_wrap_v() const {
   return _wrap_v;
   return _wrap_v;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: TextureReference::is_equivalent
+//       Access: Public
+//  Description: Returns true if all essential properties of this
+//               TextureReference are the same as that of the other,
+//               or false if any of them differ.  This is useful when
+//               reading a new egg file and comparing its references
+//               to its previously-defined references.
+////////////////////////////////////////////////////////////////////
+bool TextureReference::
+is_equivalent(const TextureReference &other) const {
+  if (_source_texture != other._source_texture) {
+    return false;
+  }
+  if (!_properties.egg_properties_match(other._properties)) {
+    return false;
+  }
+  if (_uses_alpha != other._uses_alpha) {
+    return false;
+  }
+  if (_any_uvs != other._any_uvs) {
+    return false;
+  }
+  if (_wrap_u != other._wrap_u ||
+      _wrap_v != other._wrap_v) {
+    return false;
+  }
+  if (_any_uvs) {
+    if (!_min_uv.almost_equal(other._min_uv, 0.00001)) {
+      return false;
+    }
+    if (!_max_uv.almost_equal(other._max_uv, 0.00001)) {
+      return false;
+    }
+  }
+  if (!_tex_mat.almost_equal(other._tex_mat, 0.00001)) {
+    return false;
+  }
+
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureReference::set_placement
 //     Function: TextureReference::set_placement
 //       Access: Public
 //       Access: Public
@@ -734,6 +799,8 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
   // We don't write _egg_tex or _egg_data; that's specific to the
   // We don't write _egg_tex or _egg_data; that's specific to the
   // session.
   // session.
 
 
+  datagram.add_string(_tref_name);
+
   _tex_mat.write_datagram(datagram);
   _tex_mat.write_datagram(datagram);
   _inv_tex_mat.write_datagram(datagram);
   _inv_tex_mat.write_datagram(datagram);
 
 
@@ -815,6 +882,10 @@ fillin(DatagramIterator &scan, BamReader *manager) {
   TypedWritable::fillin(scan, manager);
   TypedWritable::fillin(scan, manager);
   manager->read_pointer(scan);  // _egg_file
   manager->read_pointer(scan);  // _egg_file
 
 
+  if (Palettizer::_read_pi_version >= 11) {
+    _tref_name = scan.get_string();
+  }
+
   _tex_mat.read_datagram(scan);
   _tex_mat.read_datagram(scan);
   _inv_tex_mat.read_datagram(scan);
   _inv_tex_mat.read_datagram(scan);
 
 

+ 6 - 0
pandatool/src/egg-palettize/textureReference.h

@@ -54,6 +54,9 @@ public:
   EggFile *get_egg_file() const;
   EggFile *get_egg_file() const;
   SourceTextureImage *get_source() const;
   SourceTextureImage *get_source() const;
   TextureImage *get_texture() const;
   TextureImage *get_texture() const;
+  const string &get_tref_name() const;
+
+  bool operator < (const TextureReference &other) const;
 
 
   bool has_uvs() const;
   bool has_uvs() const;
   const TexCoordd &get_min_uv() const;
   const TexCoordd &get_min_uv() const;
@@ -62,6 +65,8 @@ public:
   EggTexture::WrapMode get_wrap_u() const;
   EggTexture::WrapMode get_wrap_u() const;
   EggTexture::WrapMode get_wrap_v() const;
   EggTexture::WrapMode get_wrap_v() const;
 
 
+  bool is_equivalent(const TextureReference &other) const;
+
   void set_placement(TexturePlacement *placement);
   void set_placement(TexturePlacement *placement);
   void clear_placement();
   void clear_placement();
   TexturePlacement *get_placement() const;
   TexturePlacement *get_placement() const;
@@ -90,6 +95,7 @@ private:
   EggTexture *_egg_tex;
   EggTexture *_egg_tex;
   EggData *_egg_data;
   EggData *_egg_data;
 
 
+  string _tref_name;
   LMatrix3d _tex_mat, _inv_tex_mat;
   LMatrix3d _tex_mat, _inv_tex_mat;
   SourceTextureImage *_source_texture;
   SourceTextureImage *_source_texture;
   TexturePlacement *_placement;
   TexturePlacement *_placement;