diff --git a/pandatool/src/egg-palettize-old/Sources.pp b/pandatool/src/egg-palettize-old/Sources.pp index 54a0035cf6..b0de94a466 100644 --- a/pandatool/src/egg-palettize-old/Sources.pp +++ b/pandatool/src/egg-palettize-old/Sources.pp @@ -1,22 +1,22 @@ -// #begin bin_target -// #define TARGET egg-palettize-new -// #define LOCAL_LIBS \ -// eggbase progbase -// #define OTHER_LIBS \ -// egg:c linmath:c putil:c express:c pnmimage:c pnmimagetypes:c \ -// pandaegg:m panda:m pandaexpress:m \ -// dtoolutil:c dconfig:c dtool:m pystub +#begin bin_target + #define TARGET egg-palettize-new + #define LOCAL_LIBS \ + eggbase progbase + #define OTHER_LIBS \ + egg:c linmath:c putil:c express:c pnmimage:c pnmimagetypes:c \ + pandaegg:m panda:m pandaexpress:m \ + dtoolutil:c dconfig:c dtool:m pystub -// #define SOURCES \ -// attribFile.cxx attribFile.h config_egg_palettize.cxx \ -// eggPalettize.cxx eggPalettize.h \ -// palette.cxx palette.h paletteGroup.cxx \ -// paletteGroup.h pTexture.cxx pTexture.h sourceEgg.cxx \ -// sourceEgg.h string_utils.cxx string_utils.h \ -// textureEggRef.cxx textureEggRef.h textureOmitReason.h \ -// texturePacking.cxx \ -// texturePacking.h userAttribLine.cxx userAttribLine.h + #define SOURCES \ + attribFile.cxx attribFile.h config_egg_palettize.cxx \ + eggPalettize.cxx eggPalettize.h \ + palette.cxx palette.h paletteGroup.cxx \ + paletteGroup.h pTexture.cxx pTexture.h sourceEgg.cxx \ + sourceEgg.h string_utils.cxx string_utils.h \ + textureEggRef.cxx textureEggRef.h textureOmitReason.h \ + texturePacking.cxx \ + texturePacking.h userAttribLine.cxx userAttribLine.h -// #define INSTALL_HEADERS + #define INSTALL_HEADERS -// #end bin_target +#end bin_target diff --git a/pandatool/src/egg-palettize-old/texturePacking.cxx b/pandatool/src/egg-palettize-old/texturePacking.cxx index 5ddb7d9e16..5a0fb8dc70 100644 --- a/pandatool/src/egg-palettize-old/texturePacking.cxx +++ b/pandatool/src/egg-palettize-old/texturePacking.cxx @@ -573,7 +573,7 @@ transfer() { } else { // Should we scale it? - if (nx != image->get_x_size() && ny != image->get_y_size()) { + if (nx != image->get_x_size() || ny != image->get_y_size()) { nout << "Resizing " << new_filename << " to " << nx << " " << ny << "\n"; PNMImage *new_image = diff --git a/pandatool/src/egg-palettize/Sources.pp b/pandatool/src/egg-palettize/Sources.pp index 4c59f103db..1016dd4c46 100644 --- a/pandatool/src/egg-palettize/Sources.pp +++ b/pandatool/src/egg-palettize/Sources.pp @@ -1,30 +1,30 @@ -#begin bin_target - #define TARGET egg-palettize - #define LOCAL_LIBS \ - eggbase progbase - #define OTHER_LIBS \ - egg:c loader:c linmath:c putil:c express:c pnmimage:c pnmimagetypes:c \ - pandaegg:m panda:m pandaexpress:m \ - dtoolutil:c dconfig:c dtool:m pystub +// #begin bin_target +// #define TARGET egg-palettize +// #define LOCAL_LIBS \ +// eggbase progbase +// #define OTHER_LIBS \ +// egg:c loader:c linmath:c putil:c express:c pnmimage:c pnmimagetypes:c \ +// pandaegg:m panda:m pandaexpress:m \ +// dtoolutil:c dconfig:c dtool:m pystub - #define SOURCES \ - config_egg_palettize.cxx config_egg_palettize.h \ - destTextureImage.cxx destTextureImage.h \ - eggFile.cxx eggFile.h eggPalettize.cxx eggPalettize.h \ - filenameUnifier.cxx filenameUnifier.h \ - imageFile.cxx imageFile.h omitReason.cxx omitReason.h \ - paletteGroup.h paletteGroup.cxx \ - paletteGroups.h paletteGroups.cxx paletteImage.h paletteImage.cxx \ - palettePage.cxx palettePage.h \ - palettizer.cxx palettizer.h \ - sourceTextureImage.cxx sourceTextureImage.h string_utils.cxx \ - string_utils.h textureImage.cxx textureImage.h \ - texturePlacement.cxx texturePlacement.h \ - texturePosition.cxx texturePosition.h \ - textureProperties.cxx textureProperties.h textureReference.cxx \ - textureReference.h textureRequest.h textureRequest.cxx \ - txaFile.cxx txaFile.h \ - txaLine.cxx txaLine.h +// #define SOURCES \ +// config_egg_palettize.cxx config_egg_palettize.h \ +// destTextureImage.cxx destTextureImage.h \ +// eggFile.cxx eggFile.h eggPalettize.cxx eggPalettize.h \ +// filenameUnifier.cxx filenameUnifier.h \ +// imageFile.cxx imageFile.h omitReason.cxx omitReason.h \ +// paletteGroup.h paletteGroup.cxx \ +// paletteGroups.h paletteGroups.cxx paletteImage.h paletteImage.cxx \ +// palettePage.cxx palettePage.h \ +// palettizer.cxx palettizer.h \ +// sourceTextureImage.cxx sourceTextureImage.h string_utils.cxx \ +// string_utils.h textureImage.cxx textureImage.h \ +// texturePlacement.cxx texturePlacement.h \ +// texturePosition.cxx texturePosition.h \ +// textureProperties.cxx textureProperties.h textureReference.cxx \ +// textureReference.h textureRequest.h textureRequest.cxx \ +// txaFile.cxx txaFile.h \ +// txaLine.cxx txaLine.h -#end bin_target +// #end bin_target diff --git a/pandatool/src/egg-palettize/eggPalettize.cxx b/pandatool/src/egg-palettize/eggPalettize.cxx index 21235c6a56..938f43b79b 100644 --- a/pandatool/src/egg-palettize/eggPalettize.cxx +++ b/pandatool/src/egg-palettize/eggPalettize.cxx @@ -340,6 +340,12 @@ run() { pal->process_command_line_eggs(); } + if (_force_optimal) { + // If we're asking for optimal packing, this also implies we want + // to resize the big empty palette images down. + pal->optimal_resize(); + } + if (_redo_eggs) { if (!pal->read_stale_eggs(_redo_all)) { okflag = false; diff --git a/pandatool/src/egg-palettize/paletteGroup.cxx b/pandatool/src/egg-palettize/paletteGroup.cxx index 401d92827f..87cff46926 100644 --- a/pandatool/src/egg-palettize/paletteGroup.cxx +++ b/pandatool/src/egg-palettize/paletteGroup.cxx @@ -306,6 +306,21 @@ write_image_info(ostream &out, int indent_level) const { } } +//////////////////////////////////////////////////////////////////// +// Function: PaletteGroup::optimal_resize +// Access: Public +// Description: Attempts to resize each PalettteImage down to its +// smallest possible size. +//////////////////////////////////////////////////////////////////// +void PaletteGroup:: +optimal_resize() { + Pages::iterator pai; + for (pai = _pages.begin(); pai != _pages.end(); ++pai) { + PalettePage *page = (*pai).second; + page->optimal_resize(); + } +} + //////////////////////////////////////////////////////////////////// // Function: PaletteGroup::reset_images // Access: Public diff --git a/pandatool/src/egg-palettize/paletteGroup.h b/pandatool/src/egg-palettize/paletteGroup.h index ad1e1f4ab4..984d3adc89 100644 --- a/pandatool/src/egg-palettize/paletteGroup.h +++ b/pandatool/src/egg-palettize/paletteGroup.h @@ -59,6 +59,7 @@ public: void place_all(); void write_image_info(ostream &out, int indent_level = 0) const; + void optimal_resize(); void reset_images(); void update_images(bool redo_all); diff --git a/pandatool/src/egg-palettize/paletteImage.cxx b/pandatool/src/egg-palettize/paletteImage.cxx index d56168a344..c934c6c98b 100644 --- a/pandatool/src/egg-palettize/paletteImage.cxx +++ b/pandatool/src/egg-palettize/paletteImage.cxx @@ -257,6 +257,113 @@ check_solitary() { } } +//////////////////////////////////////////////////////////////////// +// Function: PaletteImage::optimal_resize +// Access: Public +// Description: Attempts to resize the palette image to as small as +// it can go. +//////////////////////////////////////////////////////////////////// +void PaletteImage:: +optimal_resize() { + if (is_empty()) { + return; + } + + bool resized_any = false; + bool success; + do { + success = false; + nassertv(_x_size > 0 && _y_size > 0); + + // Try to cut it in half in both dimensions, one at a time. + if (resize_image(_x_size, _y_size / 2)) { + success = true; + resized_any = true; + } + if (resize_image(_x_size / 2, _y_size)) { + success = true; + resized_any = true; + } + } while (success); + + if (resized_any) { + nout << "Resizing " + << FilenameUnifier::make_user_filename(get_filename()) << " to " + << _x_size << " " << _y_size << "\n"; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PaletteImage::resize_image +// Access: Public +// Description: Attempts to resize the palette image, and repack all +// of the textures within the new size. Returns true if +// successful, false otherwise. If this fails, it will +// still result in repacking all the textures in the +// original size. +//////////////////////////////////////////////////////////////////// +bool PaletteImage:: +resize_image(int x_size, int y_size) { + // We already know we're going to be generating a new image from + // scratch after this. + _cleared_regions.clear(); + unlink(); + _new_image = true; + + // First, Save the current placement list, while simultaneously + // clearing it. + Placements saved; + saved.swap(_placements); + + // Also save our current size. + int saved_x_size = _x_size; + int saved_y_size = _y_size; + + // Then, sort the textures to in order from biggest to smallest, as + // an aid to optimal packing. + sort(saved.begin(), saved.end(), SortPlacementBySize()); + + // And while we're at it, we need to officially unplace each of + // these. + Placements::iterator pi; + for (pi = saved.begin(); pi != saved.end(); ++pi) { + (*pi)->force_replace(); + } + + // Finally, apply the new size and try to fit all the textures. + _x_size = x_size; + _y_size = y_size; + + bool packed = true; + for (pi = saved.begin(); pi != saved.end() && packed; ++pi) { + if (!place(*pi)) { + packed = false; + } + } + + if (!packed) { + // If it didn't work, phooey. Put 'em all back. + _x_size = saved_x_size; + _y_size = saved_y_size; + + Placements remove; + remove.swap(_placements); + for (pi = remove.begin(); pi != remove.end(); ++pi) { + (*pi)->force_replace(); + } + + bool all_packed = true; + for (pi = saved.begin(); pi != saved.end(); ++pi) { + if (!place(*pi)) { + all_packed = false; + } + } + nassertr(all_packed, false); + } + + return packed; +} + //////////////////////////////////////////////////////////////////// // Function: PaletteImage::write_placements // Access: Public diff --git a/pandatool/src/egg-palettize/paletteImage.h b/pandatool/src/egg-palettize/paletteImage.h index c06104330c..2e29607acd 100644 --- a/pandatool/src/egg-palettize/paletteImage.h +++ b/pandatool/src/egg-palettize/paletteImage.h @@ -39,6 +39,9 @@ public: void unplace(TexturePlacement *placement); void check_solitary(); + void optimal_resize(); + bool resize_image(int x_size, int y_size); + void write_placements(ostream &out, int indent_level = 0) const; void reset_image(); void update_image(bool redo_all); diff --git a/pandatool/src/egg-palettize/palettePage.cxx b/pandatool/src/egg-palettize/palettePage.cxx index 045f389e13..7abaed9a7e 100644 --- a/pandatool/src/egg-palettize/palettePage.cxx +++ b/pandatool/src/egg-palettize/palettePage.cxx @@ -19,27 +19,6 @@ TypeHandle PalettePage::_type_handle; -// This is an STL object to sort an array of TexturePlacement pointers -// in order from biggest to smallest. -class SortPlacementBySize { -public: - bool operator ()(TexturePlacement *a, TexturePlacement *b) const { - if (a->get_y_size() < b->get_y_size()) { - return false; - - } else if (b->get_y_size() < a->get_y_size()) { - return true; - - } else if (a->get_x_size() < b->get_x_size()) { - return false; - - } else if (b->get_x_size() < a->get_x_size()) { - return true; - } - return false; - } -}; - //////////////////////////////////////////////////////////////////// // Function: PalettePage::Default Constructor // Access: Private @@ -190,6 +169,21 @@ write_image_info(ostream &out, int indent_level) const { } } +//////////////////////////////////////////////////////////////////// +// Function: PalettePage::optimal_resize +// Access: Public +// Description: Attempts to resize each PalettteImage down to its +// smallest possible size. +//////////////////////////////////////////////////////////////////// +void PalettePage:: +optimal_resize() { + Images::iterator ii; + for (ii = _images.begin(); ii != _images.end(); ++ii) { + PaletteImage *image = (*ii); + image->optimal_resize(); + } +} + //////////////////////////////////////////////////////////////////// // Function: PalettePage::reset_images // Access: Public diff --git a/pandatool/src/egg-palettize/palettePage.h b/pandatool/src/egg-palettize/palettePage.h index beb9799af3..78069c1adf 100644 --- a/pandatool/src/egg-palettize/palettePage.h +++ b/pandatool/src/egg-palettize/palettePage.h @@ -41,6 +41,7 @@ public: void unplace(TexturePlacement *placement); void write_image_info(ostream &out, int indent_level = 0) const; + void optimal_resize(); void reset_images(); void update_images(bool redo_all); diff --git a/pandatool/src/egg-palettize/palettizer.cxx b/pandatool/src/egg-palettize/palettizer.cxx index 0d9296cb4f..4232725d03 100644 --- a/pandatool/src/egg-palettize/palettizer.cxx +++ b/pandatool/src/egg-palettize/palettizer.cxx @@ -345,6 +345,21 @@ process_all() { } } +//////////////////////////////////////////////////////////////////// +// Function: Palettizer::optimal_resize +// Access: Public +// Description: Attempts to resize each PalettteImage down to its +// smallest possible size. +//////////////////////////////////////////////////////////////////// +void Palettizer:: +optimal_resize() { + Groups::iterator gi; + for (gi = _groups.begin(); gi != _groups.end(); ++gi) { + PaletteGroup *group = (*gi).second; + group->optimal_resize(); + } +} + //////////////////////////////////////////////////////////////////// // Function: Palettizer::reset_images // Access: Public diff --git a/pandatool/src/egg-palettize/palettizer.h b/pandatool/src/egg-palettize/palettizer.h index a1ccdfd51c..59526b5e25 100644 --- a/pandatool/src/egg-palettize/palettizer.h +++ b/pandatool/src/egg-palettize/palettizer.h @@ -37,6 +37,7 @@ public: void read_txa_file(const Filename &txa_filename); void process_command_line_eggs(); void process_all(); + void optimal_resize(); void reset_images(); void generate_images(bool redo_all); bool read_stale_eggs(bool redo_all); diff --git a/pandatool/src/egg-palettize/texturePlacement.cxx b/pandatool/src/egg-palettize/texturePlacement.cxx index 65aa7ffb5d..11f87a8d07 100644 --- a/pandatool/src/egg-palettize/texturePlacement.cxx +++ b/pandatool/src/egg-palettize/texturePlacement.cxx @@ -968,3 +968,28 @@ fillin(DatagramIterator &scan, BamReader *manager) { _num_references = scan.get_int32(); manager->read_pointers(scan, this, _num_references); } + + +//////////////////////////////////////////////////////////////////// +// Function: SortPlacementBySize::Function Operator +// Access: Public +// Description: Compares two TexturePlacement objects and returns +// true if the first one is bigger than the second one, +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool SortPlacementBySize:: +operator ()(TexturePlacement *a, TexturePlacement *b) const { + if (a->get_y_size() < b->get_y_size()) { + return false; + + } else if (b->get_y_size() < a->get_y_size()) { + return true; + + } else if (a->get_x_size() < b->get_x_size()) { + return false; + + } else if (b->get_x_size() < a->get_x_size()) { + return true; + } + return false; +} diff --git a/pandatool/src/egg-palettize/texturePlacement.h b/pandatool/src/egg-palettize/texturePlacement.h index 2eff5ac42d..62264dcef8 100644 --- a/pandatool/src/egg-palettize/texturePlacement.h +++ b/pandatool/src/egg-palettize/texturePlacement.h @@ -133,5 +133,13 @@ private: static TypeHandle _type_handle; }; + +// This is an STL object to sort an array of TexturePlacement pointers +// in order from biggest to smallest. +class SortPlacementBySize { +public: + bool operator ()(TexturePlacement *a, TexturePlacement *b) const; +}; + #endif