diff --git a/pandatool/src/egg-palettize/eggPalettize.cxx b/pandatool/src/egg-palettize/eggPalettize.cxx index ee1b000909..3c4f472c83 100644 --- a/pandatool/src/egg-palettize/eggPalettize.cxx +++ b/pandatool/src/egg-palettize/eggPalettize.cxx @@ -378,7 +378,15 @@ describe_input_file() { "but possibly at the expense of triangle strips in the resulting " "model (since some vertices can no longer be shared).\n\n" - "The default if this is unspecified is 'poly'.\n\n"); + "Sometimes, it may be necessary to be more restrictive on " + "character geometry than on non-character geometry, because " + "the cost of adding additional vertices on characters is " + "greater. You can specify a different kind of remapping for " + "characters only, by using the keyword 'char' on the same line, " + "e.g. ':remap group char never'.\n\n" + + "The default remap mode for all geometry, character or otherwise, " + "if no remap mode is specified is 'poly'.\n\n"); show_text(" :imagetype type[,alpha_type]", 10, "This specifies the default type of image file that should be " diff --git a/pandatool/src/egg-palettize/palettizer.cxx b/pandatool/src/egg-palettize/palettizer.cxx index 09a6112feb..ec9e312963 100644 --- a/pandatool/src/egg-palettize/palettizer.cxx +++ b/pandatool/src/egg-palettize/palettizer.cxx @@ -23,6 +23,24 @@ Palettizer *pal = (Palettizer *)NULL; TypeHandle Palettizer::_type_handle; +ostream &operator << (ostream &out, Palettizer::RemapUV remap) { + switch (remap) { + case Palettizer::RU_never: + return out << "never"; + + case Palettizer::RU_group: + return out << "per group"; + + case Palettizer::RU_poly: + return out << "per polygon"; + + case Palettizer::RU_invalid: + return out << "(invalid)"; + } + + return out << "**invalid**(" << (int)remap << ")"; +} + //////////////////////////////////////////////////////////////////// // Function: Palettizer::Constructor // Access: Public @@ -35,7 +53,11 @@ Palettizer() { // 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. - _pi_version = 0; + + _pi_version = 1; + // Updated to version 1 on 12/11/00 to add _remap_char_uv. + + _read_pi_version = _pi_version; _map_dirname = "%g"; _shadow_dirname = "shadow"; @@ -54,6 +76,7 @@ Palettizer() { _round_unit = 0.1; _round_fuzz = 0.01; _remap_uv = RU_poly; + _remap_char_uv = RU_poly; } //////////////////////////////////////////////////////////////////// @@ -83,20 +106,8 @@ report_pi() const { cout << " round UV area to nearest " << _round_unit << " with fuzz " << _round_fuzz << "\n"; } - cout << " remap UV's: "; - switch (_remap_uv) { - case RU_never: - cout << "never\n"; - break; - - case RU_group: - cout << "per group\n"; - break; - - case RU_poly: - cout << "per polygon\n"; - break; - } + cout << " remap UV's: " << _remap_uv << "\n" + << " remap UV's for characters: " << _remap_char_uv << "\n"; if (_color_type != (PNMFileType *)NULL) { cout << " generate image files of type: " @@ -606,6 +617,29 @@ get_texture(const string &name) { return image; } +//////////////////////////////////////////////////////////////////// +// Function: Palettizer::string_remap +// Access: Public, Static +// Description: Returns the RemapUV code corresponding to the +// indicated string, or RU_invalid if the string is +// invalid. +//////////////////////////////////////////////////////////////////// +Palettizer::RemapUV Palettizer:: +string_remap(const string &str) { + if (str == "never") { + return RU_never; + + } else if (str == "group") { + return RU_group; + + } else if (str == "poly") { + return RU_poly; + + } else { + return RU_invalid; + } +} + //////////////////////////////////////////////////////////////////// // Function: Palettizer::yesno // Access: Private, Static @@ -653,6 +687,8 @@ write_datagram(BamWriter *writer, Datagram &datagram) { datagram.add_float64(_round_unit); datagram.add_float64(_round_fuzz); datagram.add_int32((int)_remap_uv); + datagram.add_int32((int)_remap_char_uv); + writer->write_pointer(datagram, _color_type); writer->write_pointer(datagram, _alpha_type); writer->write_pointer(datagram, _shadow_color_type); @@ -769,7 +805,7 @@ make_Palettizer(const FactoryParams ¶ms) { //////////////////////////////////////////////////////////////////// void Palettizer:: fillin(DatagramIterator &scan, BamReader *manager) { - _pi_version = scan.get_int32(); + _read_pi_version = scan.get_int32(); _map_dirname = scan.get_string(); _shadow_dirname = FilenameUnifier::get_bam_filename(scan.get_string()); _rel_dirname = FilenameUnifier::get_bam_filename(scan.get_string()); @@ -785,6 +821,12 @@ fillin(DatagramIterator &scan, BamReader *manager) { _round_unit = scan.get_float64(); _round_fuzz = scan.get_float64(); _remap_uv = (RemapUV)scan.get_int32(); + if (_read_pi_version < 1) { + _remap_char_uv = _remap_uv; + } else { + _remap_char_uv = (RemapUV)scan.get_int32(); + } + manager->read_pointer(scan, this); // _color_type manager->read_pointer(scan, this); // _alpha_type manager->read_pointer(scan, this); // _shadow_color_type diff --git a/pandatool/src/egg-palettize/palettizer.h b/pandatool/src/egg-palettize/palettizer.h index 78b2e88d3a..d0ac14b8c5 100644 --- a/pandatool/src/egg-palettize/palettizer.h +++ b/pandatool/src/egg-palettize/palettizer.h @@ -55,13 +55,17 @@ private: public: int _pi_version; + int _read_pi_version; enum RemapUV { RU_never, RU_group, - RU_poly + RU_poly, + RU_invalid }; + static RemapUV string_remap(const string &str); + // These values are not stored in the bam file, but are specific to // each session. TxaFile _txa_file; @@ -83,7 +87,7 @@ public: bool _round_uvs; double _round_unit; double _round_fuzz; - RemapUV _remap_uv; + RemapUV _remap_uv, _remap_char_uv; PNMFileType *_color_type; PNMFileType *_alpha_type; PNMFileType *_shadow_color_type; diff --git a/pandatool/src/egg-palettize/textureReference.cxx b/pandatool/src/egg-palettize/textureReference.cxx index 3e38c31b79..1627b20116 100644 --- a/pandatool/src/egg-palettize/textureReference.cxx +++ b/pandatool/src/egg-palettize/textureReference.cxx @@ -112,7 +112,7 @@ from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex) { _uses_alpha = true; } - get_uv_range(_egg_data); + get_uv_range(_egg_data, pal->_remap_uv); _wrap_u = egg_tex->determine_wrap_u(); _wrap_v = egg_tex->determine_wrap_v(); @@ -319,9 +319,7 @@ update_egg() { // Finally, go back and actually adjust the UV's to match what we // claimed they could be. - if (pal->_remap_uv != Palettizer::RU_never) { - update_uv_range(_egg_data); - } + update_uv_range(_egg_data, pal->_remap_uv); } //////////////////////////////////////////////////////////////////// @@ -396,7 +394,7 @@ write(ostream &out, int indent_level) const { // later. //////////////////////////////////////////////////////////////////// void TextureReference:: -get_uv_range(EggGroupNode *group) { +get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) { if (group->is_of_type(EggGroup::get_class_type())) { EggGroup *egg_group; DCAST_INTO_V(egg_group, group); @@ -406,6 +404,12 @@ get_uv_range(EggGroupNode *group) { // ignore it and everything under it. return; } + + if (egg_group->get_dart_type() != EggGroup::DT_none) { + // If it's a character, we might change the kind of remapping we + // do. + remap = pal->_remap_char_uv; + } } bool group_any_uvs = false; @@ -452,7 +456,7 @@ get_uv_range(EggGroupNode *group) { TexCoordd geom_min_uv, geom_max_uv; if (get_geom_uvs(geom, geom_min_uv, geom_max_uv)) { - if (pal->_remap_uv == Palettizer::RU_poly) { + if (remap == Palettizer::RU_poly) { LVector2d trans = translate_uv(geom_min_uv, geom_max_uv); geom_min_uv += trans; geom_max_uv += trans; @@ -464,12 +468,12 @@ get_uv_range(EggGroupNode *group) { } else if (child->is_of_type(EggGroupNode::get_class_type())) { EggGroupNode *cg = DCAST(EggGroupNode, child); - get_uv_range(cg); + get_uv_range(cg, remap); } } if (group_any_uvs) { - if (pal->_remap_uv == Palettizer::RU_group) { + if (remap == Palettizer::RU_group) { LVector2d trans = translate_uv(group_min_uv, group_max_uv); group_min_uv += trans; group_max_uv += trans; @@ -485,7 +489,7 @@ get_uv_range(EggGroupNode *group) { // in the previous call to get_uv_range(). //////////////////////////////////////////////////////////////////// void TextureReference:: -update_uv_range(EggGroupNode *group) { +update_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) { if (group->is_of_type(EggGroup::get_class_type())) { EggGroup *egg_group; DCAST_INTO_V(egg_group, group); @@ -495,6 +499,12 @@ update_uv_range(EggGroupNode *group) { // ignore it and everything under it. return; } + + if (egg_group->get_dart_type() != EggGroup::DT_none) { + // If it's a character, we might change the kind of remapping we + // do. + remap = pal->_remap_char_uv; + } } bool group_any_uvs = false; @@ -508,31 +518,33 @@ update_uv_range(EggGroupNode *group) { // about these things. } else if (child->is_of_type(EggPrimitive::get_class_type())) { - EggPrimitive *geom = DCAST(EggPrimitive, child); - if (geom->has_texture() && geom->get_texture() == _egg_tex) { - TexCoordd geom_min_uv, geom_max_uv; - - if (get_geom_uvs(geom, geom_min_uv, geom_max_uv)) { - if (pal->_remap_uv == Palettizer::RU_poly) { - LVector2d trans = translate_uv(geom_min_uv, geom_max_uv); - trans = trans * _inv_tex_mat; - if (!trans.almost_equal(LVector2d::zero())) { - translate_geom_uvs(geom, trans); - } - } else { - collect_uv(group_any_uvs, group_min_uv, group_max_uv, + if (remap != Palettizer::RU_never) { + EggPrimitive *geom = DCAST(EggPrimitive, child); + if (geom->has_texture() && geom->get_texture() == _egg_tex) { + TexCoordd geom_min_uv, geom_max_uv; + + if (get_geom_uvs(geom, geom_min_uv, geom_max_uv)) { + if (remap == Palettizer::RU_poly) { + LVector2d trans = translate_uv(geom_min_uv, geom_max_uv); + trans = trans * _inv_tex_mat; + if (!trans.almost_equal(LVector2d::zero())) { + translate_geom_uvs(geom, trans); + } + } else { + collect_uv(group_any_uvs, group_min_uv, group_max_uv, geom_min_uv, geom_max_uv); + } } } } } else if (child->is_of_type(EggGroupNode::get_class_type())) { EggGroupNode *cg = DCAST(EggGroupNode, child); - update_uv_range(cg); + update_uv_range(cg, remap); } } - if (group_any_uvs && pal->_remap_uv == Palettizer::RU_group) { + if (group_any_uvs && remap == Palettizer::RU_group) { LVector2d trans = translate_uv(group_min_uv, group_max_uv); trans = trans * _inv_tex_mat; if (!trans.almost_equal(LVector2d::zero())) { @@ -587,7 +599,13 @@ translate_geom_uvs(EggPrimitive *geom, const TexCoordd &trans) const { if (vtx->has_uv()) { EggVertex vtx_copy(*vtx); vtx_copy.set_uv(vtx_copy.get_uv() + trans); - geom->replace(pi, vtx->get_pool()->create_unique_vertex(vtx_copy)); + EggVertex *new_vtx = vtx->get_pool()->create_unique_vertex(vtx_copy); + + if (new_vtx->gref_size() != vtx->gref_size()) { + new_vtx->copy_grefs_from(*vtx); + } + + geom->replace(pi, new_vtx); } } } diff --git a/pandatool/src/egg-palettize/textureReference.h b/pandatool/src/egg-palettize/textureReference.h index 8cb43542af..9eed5f2f0f 100644 --- a/pandatool/src/egg-palettize/textureReference.h +++ b/pandatool/src/egg-palettize/textureReference.h @@ -9,6 +9,7 @@ #include #include "textureProperties.h" +#include "palettizer.h" #include #include @@ -59,8 +60,8 @@ public: void write(ostream &out, int indent_level = 0) const; private: - void get_uv_range(EggGroupNode *group); - void update_uv_range(EggGroupNode *group); + void get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap); + void update_uv_range(EggGroupNode *group, Palettizer::RemapUV remap); bool get_geom_uvs(EggPrimitive *geom, TexCoordd &geom_min_uv, TexCoordd &geom_max_uv); diff --git a/pandatool/src/egg-palettize/txaFile.cxx b/pandatool/src/egg-palettize/txaFile.cxx index 5c0bd312d6..0c6cd1e4b7 100644 --- a/pandatool/src/egg-palettize/txaFile.cxx +++ b/pandatool/src/egg-palettize/txaFile.cxx @@ -411,24 +411,34 @@ parse_round_line(const vector_string &words) { //////////////////////////////////////////////////////////////////// bool TxaFile:: parse_remap_line(const vector_string &words) { - if (words.size() != 2) { - nout << "Exactly one parameter required for :remap.\n"; - return false; - } + int i = 1; + while (i < (int)words.size()) { + const string &keyword = words[i]; + if (keyword == "char") { + // Defining how to remap UV's for characters. + i++; + if (i == (int)words.size()) { + nout << "Keyword expected following 'char'\n"; + return false; + } + pal->_remap_char_uv = Palettizer::string_remap(words[i]); + if (pal->_remap_char_uv == Palettizer::RU_invalid) { + nout << "Invalid remap keyword: " << words[i] << "\n"; + return false; + } - const string &keyword = words[1]; - if (keyword == "never") { - pal->_remap_uv = Palettizer::RU_never; + } else { + // Defining how to remap UV's in general. + pal->_remap_uv = Palettizer::string_remap(words[i]); + if (pal->_remap_uv == Palettizer::RU_invalid) { + nout << "Invalid remap keyword: " << words[i] << "\n"; + return false; + } - } else if (keyword == "group") { - pal->_remap_uv = Palettizer::RU_group; + pal->_remap_char_uv = pal->_remap_uv; + } - } else if (keyword == "poly") { - pal->_remap_uv = Palettizer::RU_poly; - - } else { - nout << "Invalid remap keyword: " << keyword << "\n"; - return false; + i++; } return true; diff --git a/pandatool/src/egg-palettize/txaFile.h b/pandatool/src/egg-palettize/txaFile.h index 9eba2dfda0..ce4925adfb 100644 --- a/pandatool/src/egg-palettize/txaFile.h +++ b/pandatool/src/egg-palettize/txaFile.h @@ -41,6 +41,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); typedef vector Lines; Lines _lines;