add :cutout

This commit is contained in:
David Rose 2006-04-06 21:31:44 +00:00
parent d415ff755f
commit 7b5bc71597
6 changed files with 81 additions and 14 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;