Browse Source

add :cutout

David Rose 19 years ago
parent
commit
7b5bc71597

+ 11 - 1
pandatool/src/palettizer/palettizer.cxx

@@ -41,7 +41,7 @@ Palettizer *pal = (Palettizer *)NULL;
 // allows us to easily update egg-palettize to write out additional
 // information to its pi file, without having it increment the bam
 // version number for all bam and boo files anywhere in the world.
-int Palettizer::_pi_version = 15;
+int Palettizer::_pi_version = 16;
 // 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 10 on 4/15/03 to add _alpha_file_channel.
@@ -50,6 +50,7 @@ int Palettizer::_pi_version = 15;
 // Updated to version 13 on 9/13/03 to add _keep_format and _background.
 // Updated to version 14 on 7/26/05 to add _omit_everything.
 // Updated to version 15 on 8/01/05 to make TextureImages be case-insensitive.
+// Updated to version 16 on 4/03/06 to add Palettizer::_cutout_mode et al.
 
 int Palettizer::_min_pi_version = 8;
 // Dropped support for versions 7 and below on 7/14/03.
@@ -121,6 +122,8 @@ Palettizer() {
   _shadow_alpha_type = (PNMFileType *)NULL;
   _pal_x_size = _pal_y_size = 512;
   _background.set(0.0, 0.0, 0.0, 1.0);
+  _cutout_mode = EggRenderMode::AM_dual;
+  _cutout_ratio = 0.3;
 
   _round_uvs = true;
   _round_unit = 0.1;
@@ -210,6 +213,7 @@ report_pi() const {
   }
   cout << "  remap UV's: " << _remap_uv << "\n"
        << "  remap UV's for characters: " << _remap_char_uv << "\n";
+  cout << "  alpha cutouts: " << _cutout_mode << " " << _cutout_ratio << "\n";
 
   if (_color_type != (PNMFileType *)NULL) {
     cout << "  generate image files of type: "
@@ -1019,6 +1023,8 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
   datagram.add_float64(_round_fuzz);
   datagram.add_int32((int)_remap_uv);
   datagram.add_int32((int)_remap_char_uv);
+  datagram.add_uint8((int)_cutout_mode);
+  datagram.add_float64(_cutout_ratio);
 
   writer->write_pointer(datagram, _color_type);
   writer->write_pointer(datagram, _alpha_type);
@@ -1237,6 +1243,10 @@ fillin(DatagramIterator &scan, BamReader *manager) {
   _round_fuzz = scan.get_float64();
   _remap_uv = (RemapUV)scan.get_int32();
   _remap_char_uv = (RemapUV)scan.get_int32();
+  if (_read_pi_version >= 16) {
+    _cutout_mode = (EggRenderMode::AlphaMode)scan.get_uint8();
+    _cutout_ratio = scan.get_float64();
+  }
 
   manager->read_pointer(scan);  // _color_type
   manager->read_pointer(scan);  // _alpha_type

+ 3 - 1
pandatool/src/palettizer/palettizer.h

@@ -24,7 +24,7 @@
 #include "txaFile.h"
 
 #include "typedWritable.h"
-
+#include "eggRenderMode.h"
 #include "pvector.h"
 #include "pset.h"
 #include "pmap.h"
@@ -124,6 +124,8 @@ public:
   PNMFileType *_alpha_type;
   PNMFileType *_shadow_color_type;
   PNMFileType *_shadow_alpha_type;
+  EggRenderMode::AlphaMode _cutout_mode;
+  double _cutout_ratio;
 
 private:
   typedef pvector<TexturePlacement *> Placements;

+ 29 - 11
pandatool/src/palettizer/textureImage.cxx

@@ -854,6 +854,11 @@ write_source_pathnames(ostream &out, int indent_level) const {
     }
   }
 
+  if (_is_cutout) {
+    indent(out, indent_level)
+      << "Cutout image (ratio " << _mid_pixel_ratio << ")";
+  }
+
   // Now write out the group assignments.
   if (!_egg_files.empty()) {
     // Sort the egg files into order by name for output.
@@ -898,9 +903,8 @@ write_source_pathnames(ostream &out, int indent_level) const {
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureImage::write_scale_info
 //       Access: Public
-//  Description: Writes the list of source pathnames that might
-//               contribute to this texture to the indicated output
-//               stream, one per line.
+//  Description: Writes the information about the texture's size and
+//               placement.
 ////////////////////////////////////////////////////////////////////
 void TextureImage::
 write_scale_info(ostream &out, int indent_level) {
@@ -1136,6 +1140,7 @@ consider_alpha() {
   // file that didn't define these bits.
   if (_read_source_image || !_ever_read_image || _alpha_bits == -1) {
     _alpha_bits = 0;
+    int num_mid_pixels = 0;
 
     const PNMImage &source = read_source_image();
     if (source.is_valid() && source.has_alpha()) {
@@ -1149,17 +1154,17 @@ consider_alpha() {
             _alpha_bits |= AB_one;
           } else {
             _alpha_bits |= AB_mid;
-          }
-          if (_alpha_bits == AB_all) {
-            // Once we've found a sample of everything, we can stop
-            // searching.
-            break;
+            ++num_mid_pixels;
           }
         }
       }
     }
+
+    _mid_pixel_ratio = (double)num_mid_pixels / (double)(source.get_x_size() * source.get_y_size());
   }
 
+  _is_cutout = false;
+
   if (_alpha_bits != 0) {
     if (_alpha_bits == AB_one) {
       // All alpha pixels are white; drop the alpha channel.
@@ -1180,9 +1185,11 @@ consider_alpha() {
         // No middle range bits: a binary alpha image.
         _alpha_mode = EggRenderMode::AM_binary;
 
-      } else if ((_alpha_bits & AB_one) != 0) {
-        // At least some opaque bits: a dual alpha image.
-        _alpha_mode = EggRenderMode::AM_dual;
+      } else if ((_alpha_bits & AB_one) != 0 && _mid_pixel_ratio < pal->_cutout_ratio) {
+        // At least some opaque bits, and relatively few middle range
+        // bits: a cutout image.
+        _alpha_mode = pal->_cutout_mode;
+        _is_cutout = true;
 
       } else {
         // No opaque bits; just use regular alpha blending.
@@ -1327,6 +1334,8 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
   datagram.add_bool(_forced_grayscale);
   datagram.add_uint8(_alpha_bits);
   datagram.add_int16((int)_alpha_mode);
+  datagram.add_float64(_mid_pixel_ratio);
+  datagram.add_bool(_is_cutout);
 
   // We don't write out _explicitly_assigned_groups; this is re-read
   // from the .txa file each time.
@@ -1442,6 +1451,15 @@ fillin(DatagramIterator &scan, BamReader *manager) {
   _forced_grayscale = scan.get_bool();
   _alpha_bits = scan.get_uint8();
   _alpha_mode = (EggRenderMode::AlphaMode)scan.get_int16();
+  if (pal->_read_pi_version >= 16) {
+    _mid_pixel_ratio = scan.get_float64();
+    _is_cutout = scan.get_bool();
+  } else {
+    // Force a re-read of the image if we are upgrading to pi version 16.
+    _ever_read_image = false;
+    _mid_pixel_ratio = 0.0;
+    _is_cutout = false;
+  }
 
   _actual_assigned_groups.fillin(scan, manager);
 

+ 2 - 0
pandatool/src/palettizer/textureImage.h

@@ -136,6 +136,8 @@ private:
     AB_all   = 0x07 // == AB_zero | AB_mid | AB_one
   };
   int _alpha_bits;
+  double _mid_pixel_ratio;
+  bool _is_cutout;
   EggRenderMode::AlphaMode _alpha_mode;
 
   PaletteGroups _explicitly_assigned_groups;

+ 35 - 0
pandatool/src/palettizer/txaFile.cxx

@@ -89,6 +89,9 @@ read(istream &in, const string &filename) {
       } else if (words[0] == ":remap") {
         okflag = parse_remap_line(words);
 
+      } else if (words[0] == ":cutout") {
+        okflag = parse_cutout_line(words);
+
       } else {
         nout << "Invalid keyword " << words[0] << "\n";
         okflag = false;
@@ -530,3 +533,35 @@ parse_remap_line(const vector_string &words) {
 
   return true;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: TxaFile::parse_cutout_line
+//       Access: Private
+//  Description: Handles the line in a .txa file that begins with the
+//               keyword ":cutout" and indicates how to handle
+//               alpha-cutout textures: those textures that appear to
+//               be mostly solid parts and invisible parts, with a
+//               thin border of antialiased alpha along the boundary.
+////////////////////////////////////////////////////////////////////
+bool TxaFile::
+parse_cutout_line(const vector_string &words) {
+  if (words.size() < 2 || words.size() > 3) {
+    nout << ":cutout alpha-mode [ratio]\n";
+    return false;
+  }
+
+  EggRenderMode::AlphaMode am = EggRenderMode::string_alpha_mode(words[1]);
+  if (am == EggRenderMode::AM_unspecified) {
+    nout << "Invalid cutout keyword: " << words[1] << "\n";
+    return false;
+  }
+  pal->_cutout_mode = am;
+
+  if (words.size() >= 3) {
+    if (!string_to_double(words[2], pal->_cutout_ratio)) {
+      nout << "Invalid cutout ratio: " << words[2] << "\n";
+    }
+  }
+
+  return true;
+}

+ 1 - 1
pandatool/src/palettizer/txaFile.h

@@ -57,7 +57,7 @@ private:
   bool parse_shadowtype_line(const vector_string &words);
   bool parse_round_line(const vector_string &words);
   bool parse_remap_line(const vector_string &words);
-  bool parse_remapchar_line(const vector_string &words);
+  bool parse_cutout_line(const vector_string &words);
 
   typedef pvector<TxaLine> Lines;
   Lines _lines;