diff --git a/pandatool/src/palettizer/palettizer.cxx b/pandatool/src/palettizer/palettizer.cxx index 34b3a28cf2..b85e3c9007 100644 --- a/pandatool/src/palettizer/palettizer.cxx +++ b/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 diff --git a/pandatool/src/palettizer/palettizer.h b/pandatool/src/palettizer/palettizer.h index 32c6ae5bd4..d04de5772c 100644 --- a/pandatool/src/palettizer/palettizer.h +++ b/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 Placements; diff --git a/pandatool/src/palettizer/textureImage.cxx b/pandatool/src/palettizer/textureImage.cxx index 21af35ce6c..093087e8b5 100644 --- a/pandatool/src/palettizer/textureImage.cxx +++ b/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); diff --git a/pandatool/src/palettizer/textureImage.h b/pandatool/src/palettizer/textureImage.h index 532d53b235..9bd69cc165 100644 --- a/pandatool/src/palettizer/textureImage.h +++ b/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; diff --git a/pandatool/src/palettizer/txaFile.cxx b/pandatool/src/palettizer/txaFile.cxx index def3285725..5533e3b4ba 100644 --- a/pandatool/src/palettizer/txaFile.cxx +++ b/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; +} diff --git a/pandatool/src/palettizer/txaFile.h b/pandatool/src/palettizer/txaFile.h index 6f55852d67..9bad135f87 100644 --- a/pandatool/src/palettizer/txaFile.h +++ b/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 Lines; Lines _lines;