*** empty log message ***
This commit is contained in:
parent
60f7913ab9
commit
07a1bca3a0
|
|
@ -102,11 +102,13 @@ write_data(xel *array, xelval *) {
|
|||
*/
|
||||
cinfo.image_width = _x_size; /* image width and height, in pixels */
|
||||
cinfo.image_height = _y_size;
|
||||
if (is_grayscale())
|
||||
if (is_grayscale()) {
|
||||
cinfo.input_components = 1;
|
||||
else
|
||||
cinfo.in_color_space = JCS_GRAYSCALE;
|
||||
} else {
|
||||
cinfo.input_components = 3;
|
||||
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
}
|
||||
/* Now use the library's routine to set default compression parameters.
|
||||
* (You must set at least cinfo.in_color_space before calling this,
|
||||
* since the defaults depend on the source color space.)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@
|
|||
|
||||
#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 \
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "textureProperties.h"
|
||||
#include "imageFile.h"
|
||||
#include "sourceTextureImage.h"
|
||||
#include "destTextureImage.h"
|
||||
#include "textureImage.h"
|
||||
#include "paletteImage.h"
|
||||
#include "texturePlacement.h"
|
||||
|
|
@ -31,6 +32,7 @@ ConfigureFn(config_egg_palettize) {
|
|||
TextureProperties::init_type();
|
||||
ImageFile::init_type();
|
||||
SourceTextureImage::init_type();
|
||||
DestTextureImage::init_type();
|
||||
TextureImage::init_type();
|
||||
PaletteImage::init_type();
|
||||
TexturePlacement::init_type();
|
||||
|
|
@ -46,6 +48,7 @@ ConfigureFn(config_egg_palettize) {
|
|||
TextureReference::register_with_read_factory();
|
||||
TextureProperties::register_with_read_factory();
|
||||
SourceTextureImage::register_with_read_factory();
|
||||
DestTextureImage::register_with_read_factory();
|
||||
TextureImage::register_with_read_factory();
|
||||
PaletteImage::register_with_read_factory();
|
||||
TexturePlacement::register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
// Filename: destTextureImage.cxx
|
||||
// Created by: drose (05Dec00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "destTextureImage.h"
|
||||
#include "texturePlacement.h"
|
||||
#include "textureImage.h"
|
||||
|
||||
#include <datagram.h>
|
||||
#include <datagramIterator.h>
|
||||
#include <bamReader.h>
|
||||
#include <bamWriter.h>
|
||||
|
||||
TypeHandle DestTextureImage::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DestTextureImage::Default Constructor
|
||||
// Access: Private
|
||||
// Description: The default constructor is only for the convenience
|
||||
// of the Bam reader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DestTextureImage::
|
||||
DestTextureImage() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DestTextureImage::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DestTextureImage::
|
||||
DestTextureImage(TexturePlacement *placement) {
|
||||
TextureImage *texture = placement->get_texture();
|
||||
_properties = texture->get_properties();
|
||||
_size_known = true;
|
||||
_x_size = texture->get_x_size();
|
||||
_y_size = texture->get_y_size();
|
||||
set_filename(placement->get_group(), texture->get_name());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DestTextureImage::copy
|
||||
// Access: Public
|
||||
// Description: Unconditionally copies the source texture into the
|
||||
// appropriate filename.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DestTextureImage::
|
||||
copy(TextureImage *texture) {
|
||||
PNMImage image = texture->get_dest_image();
|
||||
write(image);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DestTextureImage::copy_if_stale
|
||||
// Access: Public
|
||||
// Description: Copies the source texture into the appropriate
|
||||
// filename only if the indicated old reference, which
|
||||
// represents the way it was last copied, is now
|
||||
// out-of-date.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DestTextureImage::
|
||||
copy_if_stale(const DestTextureImage *other, TextureImage *texture) {
|
||||
if (other->get_x_size() != get_x_size() ||
|
||||
other->get_y_size() != get_y_size() ||
|
||||
other->get_num_channels() != get_num_channels()) {
|
||||
copy(texture);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DestTextureImage::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Registers the current object as something that can be
|
||||
// read from a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DestTextureImage::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->
|
||||
register_factory(get_class_type(), make_DestTextureImage);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DestTextureImage::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Fills the indicated datagram up with a binary
|
||||
// representation of the current object, in preparation
|
||||
// for writing to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DestTextureImage::
|
||||
write_datagram(BamWriter *writer, Datagram &datagram) {
|
||||
ImageFile::write_datagram(writer, datagram);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DestTextureImage::make_DestTextureImage
|
||||
// Access: Protected
|
||||
// Description: This method is called by the BamReader when an object
|
||||
// of this type is encountered in a Bam file; it should
|
||||
// allocate and return a new object with all the data
|
||||
// read.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWriteable* DestTextureImage::
|
||||
make_DestTextureImage(const FactoryParams ¶ms) {
|
||||
DestTextureImage *me = new DestTextureImage;
|
||||
BamReader *manager;
|
||||
Datagram packet;
|
||||
|
||||
parse_params(params, manager, packet);
|
||||
DatagramIterator scan(packet);
|
||||
|
||||
me->fillin(scan, manager);
|
||||
return me;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DestTextureImage::fillin
|
||||
// Access: Protected
|
||||
// Description: Reads the binary data from the given datagram
|
||||
// iterator, which was written by a previous call to
|
||||
// write_datagram().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DestTextureImage::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
ImageFile::fillin(scan, manager);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// Filename: destTextureImage.h
|
||||
// Created by: drose (05Dec00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DESTTEXTUREIMAGE_H
|
||||
#define DESTTEXTUREIMAGE_H
|
||||
|
||||
#include <pandatoolbase.h>
|
||||
|
||||
#include "imageFile.h"
|
||||
|
||||
class TexturePlacement;
|
||||
class TextureImage;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DestTextureImage
|
||||
// Description : This represents a texture filename as it has been
|
||||
// resized and copied to the map directory (e.g. for an
|
||||
// unplaced texture).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class DestTextureImage : public ImageFile {
|
||||
private:
|
||||
DestTextureImage();
|
||||
|
||||
public:
|
||||
DestTextureImage(TexturePlacement *placement);
|
||||
|
||||
void copy(TextureImage *texture);
|
||||
void copy_if_stale(const DestTextureImage *other, TextureImage *texture);
|
||||
|
||||
// The TypedWriteable interface follows.
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *writer, Datagram &datagram);
|
||||
|
||||
protected:
|
||||
static TypedWriteable *make_DestTextureImage(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
ImageFile::init_type();
|
||||
register_type(_type_handle, "DestTextureImage",
|
||||
ImageFile::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const DestTextureImage &dest) {
|
||||
dest.output_filename(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include "paletteGroup.h"
|
||||
#include "texturePlacement.h"
|
||||
#include "palettizer.h"
|
||||
#include "filenameUnifier.h"
|
||||
|
||||
#include <eggData.h>
|
||||
#include <eggTextureCollection.h>
|
||||
|
|
@ -26,6 +27,10 @@ TypeHandle EggFile::_type_handle;
|
|||
EggFile::
|
||||
EggFile() {
|
||||
_data = (EggData *)NULL;
|
||||
_default_group = (PaletteGroup *)NULL;
|
||||
_is_surprise = true;
|
||||
_is_stale = true;
|
||||
_first_txa_match = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -41,6 +46,11 @@ from_command_line(EggData *data,
|
|||
_data = data;
|
||||
_source_filename = source_filename;
|
||||
_dest_filename = dest_filename;
|
||||
|
||||
// We save the default PaletteGroup at this point, because the egg
|
||||
// file inherits the default group that was in effect when it was
|
||||
// specified on the command line.
|
||||
_default_group = pal->get_default_group();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -70,7 +80,7 @@ scan_textures() {
|
|||
EggTexture *egg_tex = (*eti);
|
||||
|
||||
TextureReference *ref = new TextureReference;
|
||||
ref->from_egg(_data, egg_tex);
|
||||
ref->from_egg(this, _data, egg_tex);
|
||||
|
||||
_textures.push_back(ref);
|
||||
}
|
||||
|
|
@ -93,6 +103,39 @@ get_textures(set<TextureImage *> &result) const {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::pre_txa_file
|
||||
// Access: Public
|
||||
// Description: Does some processing prior to scanning the .txa file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggFile::
|
||||
pre_txa_file() {
|
||||
_is_surprise = true;
|
||||
_first_txa_match = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::match_txa_groups
|
||||
// Access: Public
|
||||
// Description: Adds the indicated set of groups, read from the .txa
|
||||
// file, to the set of groups to which the egg file is
|
||||
// assigned.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggFile::
|
||||
match_txa_groups(const PaletteGroups &groups) {
|
||||
if (_first_txa_match) {
|
||||
// If this is the first line we matched in the .txa file, clear
|
||||
// the set of groups we'd matched from before. We don't clear
|
||||
// until we match a line in the .txa file, because if we don't
|
||||
// match any lines we still want to remember what groups we used
|
||||
// to be assigned to.
|
||||
_explicitly_assigned_groups.clear();
|
||||
_first_txa_match = false;
|
||||
}
|
||||
|
||||
_explicitly_assigned_groups.make_union(_explicitly_assigned_groups, groups);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::post_txa_file
|
||||
// Access: Public
|
||||
|
|
@ -102,22 +145,90 @@ get_textures(set<TextureImage *> &result) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void EggFile::
|
||||
post_txa_file() {
|
||||
if (_assigned_groups.empty()) {
|
||||
// If the egg file has been assigned to no groups, we have to
|
||||
// assign it to something.
|
||||
_assigned_groups.insert(pal->get_default_group());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::get_groups
|
||||
// Function: EggFile::get_explicit_groups
|
||||
// Access: Public
|
||||
// Description: Returns the set of PaletteGroups that the egg file
|
||||
// has been explicitly assigned to in the .txa file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const PaletteGroups &EggFile::
|
||||
get_groups() const {
|
||||
return _assigned_groups;
|
||||
get_explicit_groups() const {
|
||||
return _explicitly_assigned_groups;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::get_default_group
|
||||
// Access: Public
|
||||
// Description: Returns the PaletteGroup that was specified as the
|
||||
// default group on the command line at the time the egg
|
||||
// file last appeared on the command line.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PaletteGroup *EggFile::
|
||||
get_default_group() const {
|
||||
return _default_group;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::get_complete_groups
|
||||
// Access: Public
|
||||
// Description: Returns the complete set of PaletteGroups that the
|
||||
// egg file is assigned to. This is the set of all the
|
||||
// groups it is explicitly assigned to, plus all the
|
||||
// groups that these groups depend on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const PaletteGroups &EggFile::
|
||||
get_complete_groups() const {
|
||||
return _complete_groups;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::clear_surprise
|
||||
// Access: Public
|
||||
// Description: Removes the 'surprise' flag; this file has been
|
||||
// successfully matched against a line in the .txa file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggFile::
|
||||
clear_surprise() {
|
||||
_is_surprise = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::is_surprise
|
||||
// Access: Public
|
||||
// Description: Returns true if this particular egg file is a
|
||||
// 'surprise', i.e. it wasn't matched by a line in the
|
||||
// .txa file that didn't include the keyword 'cont'.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggFile::
|
||||
is_surprise() const {
|
||||
return _is_surprise;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::mark_stale
|
||||
// Access: Public
|
||||
// Description: Marks this particular egg file as stale, meaning that
|
||||
// something has changed, such as the location of a
|
||||
// texture within its palette, which causes the egg file
|
||||
// to need to be regenerated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggFile::
|
||||
mark_stale() {
|
||||
_is_stale = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::is_stale
|
||||
// Access: Public
|
||||
// Description: Returns true if the egg file needs to be updated,
|
||||
// i.e. some palettizations have changed affecting it,
|
||||
// or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggFile::
|
||||
is_stale() const {
|
||||
return _is_stale;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -132,16 +243,25 @@ get_groups() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void EggFile::
|
||||
build_cross_links() {
|
||||
if (_explicitly_assigned_groups.empty()) {
|
||||
// If the egg file has been assigned to no groups, we have to
|
||||
// assign it to something.
|
||||
_complete_groups.clear();
|
||||
_complete_groups.insert(_default_group);
|
||||
_complete_groups.make_complete(_complete_groups);
|
||||
|
||||
} else {
|
||||
_complete_groups.make_complete(_explicitly_assigned_groups);
|
||||
}
|
||||
|
||||
Textures::const_iterator ti;
|
||||
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
|
||||
(*ti)->get_texture()->note_egg_file(this);
|
||||
}
|
||||
|
||||
_assigned_groups.make_complete(_assigned_groups);
|
||||
|
||||
PaletteGroups::const_iterator gi;
|
||||
for (gi = _assigned_groups.begin();
|
||||
gi != _assigned_groups.end();
|
||||
for (gi = _complete_groups.begin();
|
||||
gi != _complete_groups.end();
|
||||
++gi) {
|
||||
(*gi)->increment_egg_count();
|
||||
}
|
||||
|
|
@ -174,7 +294,7 @@ choose_placements() {
|
|||
} else {
|
||||
// We need to select a new TexturePlacement.
|
||||
PaletteGroups groups;
|
||||
groups.make_intersection(get_groups(), texture->get_groups());
|
||||
groups.make_intersection(get_complete_groups(), texture->get_groups());
|
||||
|
||||
// Now groups is the set of groups that the egg file requires,
|
||||
// which also happen to include the texture. It better not be
|
||||
|
|
@ -195,6 +315,17 @@ choose_placements() {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::has_data
|
||||
// Access: Public
|
||||
// Description: Returns true if the EggData for this EggFile has ever
|
||||
// been loaded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggFile::
|
||||
has_data() const {
|
||||
return (_data != (EggData *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::update_egg
|
||||
// Access: Public
|
||||
|
|
@ -211,6 +342,88 @@ update_egg() {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::read_egg
|
||||
// Access: Public
|
||||
// Description: Reads in the egg file from its _source_filename. It
|
||||
// is only valid to call this if it has not already been
|
||||
// read in, e.g. from the command line. Returns true if
|
||||
// successful, false if there is an error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggFile::
|
||||
read_egg() {
|
||||
nassertr(_data == (EggData *)NULL, false);
|
||||
nassertr(!_source_filename.empty(), false);
|
||||
|
||||
if (!_source_filename.exists()) {
|
||||
nout << _source_filename << " does not exist.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
EggData *data = new EggData;
|
||||
if (!data->read(_source_filename)) {
|
||||
// Failure reading.
|
||||
delete data;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data->resolve_externals()) {
|
||||
// Failure reading an external.
|
||||
delete data;
|
||||
return false;
|
||||
}
|
||||
|
||||
_data = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::write_egg
|
||||
// Access: Public
|
||||
// Description: Writes out the egg file to its _dest_filename.
|
||||
// Returns true if successful, false if there is an
|
||||
// error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggFile::
|
||||
write_egg() {
|
||||
nassertr(_data != (EggData *)NULL, false);
|
||||
nassertr(!_dest_filename.empty(), false);
|
||||
|
||||
_dest_filename.make_dir();
|
||||
nout << "Writing " << _dest_filename << "\n";
|
||||
if (!_data->write_egg(_dest_filename)) {
|
||||
// Some error while writing. Most unusual.
|
||||
_is_stale = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
_is_stale = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::write_description
|
||||
// Access: Public
|
||||
// Description: Writes a one-line description of the egg file and its
|
||||
// group assignments to the indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggFile::
|
||||
write_description(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << get_name() << ": ";
|
||||
if (_explicitly_assigned_groups.empty()) {
|
||||
if (_default_group != (PaletteGroup *)NULL) {
|
||||
out << _default_group->get_name();
|
||||
}
|
||||
} else {
|
||||
out << _explicitly_assigned_groups;
|
||||
}
|
||||
|
||||
if (is_stale()) {
|
||||
out << " (needs update)";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggFile::write_texture_refs
|
||||
// Access: Public
|
||||
|
|
@ -251,8 +464,8 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
|
||||
// We don't write out _data; that needs to be reread each session.
|
||||
|
||||
datagram.add_string(_source_filename);
|
||||
datagram.add_string(_dest_filename);
|
||||
datagram.add_string(FilenameUnifier::make_bam_filename(_source_filename));
|
||||
datagram.add_string(FilenameUnifier::make_bam_filename(_dest_filename));
|
||||
|
||||
datagram.add_uint32(_textures.size());
|
||||
Textures::iterator ti;
|
||||
|
|
@ -260,7 +473,14 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
writer->write_pointer(datagram, (*ti));
|
||||
}
|
||||
|
||||
_assigned_groups.write_datagram(writer, datagram);
|
||||
_explicitly_assigned_groups.write_datagram(writer, datagram);
|
||||
writer->write_pointer(datagram, _default_group);
|
||||
|
||||
// We don't write out _complete_groups; that is recomputed each
|
||||
// session.
|
||||
|
||||
datagram.add_bool(_is_surprise);
|
||||
datagram.add_bool(_is_stale);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -274,7 +494,7 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int EggFile::
|
||||
complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
|
||||
nassertr((int)plist.size() >= _num_textures, 0);
|
||||
nassertr((int)plist.size() >= _num_textures + 1, 0);
|
||||
int index = 0;
|
||||
|
||||
int i;
|
||||
|
|
@ -286,6 +506,11 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
|
|||
index++;
|
||||
}
|
||||
|
||||
if (plist[index] != (TypedWriteable *)NULL) {
|
||||
DCAST_INTO_R(_default_group, plist[index], index);
|
||||
}
|
||||
index++;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
|
@ -320,11 +545,15 @@ make_EggFile(const FactoryParams ¶ms) {
|
|||
void EggFile::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
set_name(scan.get_string());
|
||||
_source_filename = scan.get_string();
|
||||
_dest_filename = scan.get_string();
|
||||
_source_filename = FilenameUnifier::get_bam_filename(scan.get_string());
|
||||
_dest_filename = FilenameUnifier::get_bam_filename(scan.get_string());
|
||||
|
||||
_num_textures = scan.get_uint32();
|
||||
manager->read_pointers(scan, this, _num_textures);
|
||||
|
||||
_assigned_groups.fillin(scan, manager);
|
||||
_explicitly_assigned_groups.fillin(scan, manager);
|
||||
manager->read_pointer(scan, this); // _default_group
|
||||
|
||||
_is_surprise = scan.get_bool();
|
||||
_is_stale = scan.get_bool();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,15 +40,29 @@ public:
|
|||
void scan_textures();
|
||||
void get_textures(set<TextureImage *> &result) const;
|
||||
|
||||
void pre_txa_file();
|
||||
void match_txa_groups(const PaletteGroups &groups);
|
||||
void post_txa_file();
|
||||
|
||||
const PaletteGroups &get_groups() const;
|
||||
const PaletteGroups &get_explicit_groups() const;
|
||||
PaletteGroup *get_default_group() const;
|
||||
const PaletteGroups &get_complete_groups() const;
|
||||
void clear_surprise();
|
||||
bool is_surprise() const;
|
||||
|
||||
void mark_stale();
|
||||
bool is_stale() const;
|
||||
|
||||
void build_cross_links();
|
||||
void choose_placements();
|
||||
|
||||
bool has_data() const;
|
||||
|
||||
void update_egg();
|
||||
bool read_egg();
|
||||
bool write_egg();
|
||||
|
||||
void write_description(ostream &out, int indent_level = 0) const;
|
||||
void write_texture_refs(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
|
|
@ -59,7 +73,12 @@ private:
|
|||
typedef vector<TextureReference *> Textures;
|
||||
Textures _textures;
|
||||
|
||||
PaletteGroups _assigned_groups;
|
||||
bool _first_txa_match;
|
||||
PaletteGroups _explicitly_assigned_groups;
|
||||
PaletteGroup *_default_group;
|
||||
PaletteGroups _complete_groups;
|
||||
bool _is_surprise;
|
||||
bool _is_stale;
|
||||
|
||||
|
||||
// The TypedWriteable interface follows.
|
||||
|
|
@ -95,8 +114,6 @@ public:
|
|||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class TxaLine;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "palettizer.h"
|
||||
#include "eggFile.h"
|
||||
#include "string_utils.h"
|
||||
#include "filenameUnifier.h"
|
||||
|
||||
#include <eggData.h>
|
||||
#include <bamFile.h>
|
||||
|
|
@ -76,7 +77,7 @@ EggPalettize() : EggMultiFilter(true) {
|
|||
("dm", "dirname", 0,
|
||||
"The directory in which to place all maps: generated palettes, "
|
||||
"as well as images which were not placed on palettes "
|
||||
"(but may have been resized). If this contains the string %s, "
|
||||
"(but may have been resized). If this contains the string %g, "
|
||||
"this will be replaced with the \"dir\" string associated with a "
|
||||
"palette group.",
|
||||
&EggPalettize::dispatch_string, &_got_map_dirname, &_map_dirname);
|
||||
|
|
@ -97,7 +98,13 @@ EggPalettize() : EggMultiFilter(true) {
|
|||
&EggPalettize::dispatch_string, &_got_default_groupdir, &_default_groupdir);
|
||||
|
||||
add_option
|
||||
("f", "", 0,
|
||||
("all", "", 0,
|
||||
"Consider all the textures referenced in all egg files that have "
|
||||
"ever been palettized, not just the egg files that appear on "
|
||||
"the command line.",
|
||||
&EggPalettize::dispatch_none, &_all_textures);
|
||||
add_option
|
||||
("opt", "", 0,
|
||||
"Force an optimal packing. By default, textures are added to "
|
||||
"existing palettes without disturbing them, which can lead to "
|
||||
"suboptimal packing. Including this switch forces the palettes "
|
||||
|
|
@ -105,7 +112,7 @@ EggPalettize() : EggMultiFilter(true) {
|
|||
"may invalidate other egg files which share this palette.",
|
||||
&EggPalettize::dispatch_none, &_force_optimal);
|
||||
add_option
|
||||
("F", "", 0,
|
||||
("redo", "", 0,
|
||||
"Force a redo of everything. This is useful in case something "
|
||||
"has gotten out of sync and the old palettes are just bad.",
|
||||
&EggPalettize::dispatch_none, &_force_redo_all);
|
||||
|
|
@ -114,12 +121,10 @@ EggPalettize() : EggMultiFilter(true) {
|
|||
"Resize mostly-empty palettes to their minimal size.",
|
||||
&EggPalettize::dispatch_none, &_optimal_resize);
|
||||
add_option
|
||||
("t", "", 0,
|
||||
"Touch any additional egg files that share this palette and will "
|
||||
"need to be refreshed, but were not included on the command "
|
||||
"line. Presumably a future make pass will cause them to be run "
|
||||
"through egg-palettize again.",
|
||||
&EggPalettize::dispatch_none, &_touch_eggs);
|
||||
("egg", "", 0,
|
||||
"Regenerate all egg files that need modification, even those that "
|
||||
"aren't named on the command line.",
|
||||
&EggPalettize::dispatch_none, &_redo_eggs);
|
||||
|
||||
add_option
|
||||
("nolock", "", 0,
|
||||
|
|
@ -244,38 +249,40 @@ run() {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
Filename pi_filename = _txa_filename;
|
||||
pi_filename.set_extension("boo");
|
||||
FilenameUnifier::set_txa_filename(_txa_filename);
|
||||
|
||||
BamFile pi_file;
|
||||
Filename state_filename = _txa_filename;
|
||||
state_filename.set_extension("boo");
|
||||
|
||||
if (!pi_filename.exists()) {
|
||||
nout << pi_filename << " does not exist; starting palettization from scratch.\n";
|
||||
BamFile state_file;
|
||||
|
||||
if (!state_filename.exists()) {
|
||||
nout << state_filename << " does not exist; starting palettization from scratch.\n";
|
||||
pal = new Palettizer;
|
||||
|
||||
} else {
|
||||
// Read the Palettizer object from the Bam file written
|
||||
// previously. This will recover all of the state saved from the
|
||||
// past session.
|
||||
if (!pi_file.open_read(pi_filename)) {
|
||||
nout << pi_filename << " exists, but cannot be read. Perhaps you should remove it so a new one can be created.\n";
|
||||
if (!state_file.open_read(state_filename)) {
|
||||
nout << state_filename << " exists, but cannot be read. Perhaps you should remove it so a new one can be created.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
TypedWriteable *obj = pi_file.read_object();
|
||||
if (obj == (TypedWriteable *)NULL || !pi_file.resolve()) {
|
||||
nout << pi_filename << " exists, but appears to be corrupt. Perhaps you should remove it so a new one can be created.\n";
|
||||
TypedWriteable *obj = state_file.read_object();
|
||||
if (obj == (TypedWriteable *)NULL || !state_file.resolve()) {
|
||||
nout << state_filename << " exists, but appears to be corrupt. Perhaps you should remove it so a new one can be created.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!obj->is_of_type(Palettizer::get_class_type())) {
|
||||
nout << pi_filename << " exists, but does not appear to be "
|
||||
nout << state_filename << " exists, but does not appear to be "
|
||||
<< "an egg-palettize output file. Perhaps you "
|
||||
<< "should remove it so a new one can be created.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pi_file.close();
|
||||
state_file.close();
|
||||
|
||||
pal = DCAST(Palettizer, obj);
|
||||
}
|
||||
|
|
@ -285,15 +292,26 @@ run() {
|
|||
exit(0);
|
||||
}
|
||||
|
||||
bool okflag = true;
|
||||
|
||||
pal->read_txa_file(_txa_filename);
|
||||
|
||||
if (_got_default_groupname) {
|
||||
pal->_default_groupname = _default_groupname;
|
||||
} else {
|
||||
pal->_default_groupname = _txa_filename.get_basename_wo_extension();
|
||||
}
|
||||
|
||||
TxaFile txa_file;
|
||||
if (!txa_file.read(_txa_filename)) {
|
||||
exit(1);
|
||||
if (_got_default_groupdir) {
|
||||
pal->_default_groupdir = _default_groupdir;
|
||||
}
|
||||
|
||||
if (_got_map_dirname) {
|
||||
pal->_map_dirname = _map_dirname;
|
||||
}
|
||||
if (_got_rel_dirname) {
|
||||
pal->_rel_dirname = _rel_dirname;
|
||||
FilenameUnifier::set_rel_dirname(_rel_dirname);
|
||||
}
|
||||
|
||||
Eggs::const_iterator ei;
|
||||
|
|
@ -309,18 +327,36 @@ run() {
|
|||
pal->_command_line_eggs.push_back(egg_file);
|
||||
}
|
||||
|
||||
pal->run(txa_file);
|
||||
if (_all_textures) {
|
||||
pal->process_all();
|
||||
} else {
|
||||
pal->process_command_line_eggs();
|
||||
}
|
||||
|
||||
if (!pi_file.open_write(pi_filename) ||
|
||||
!pi_file.write_object(pal)) {
|
||||
nout << "Unable to write palettization information to " << pi_filename
|
||||
if (_redo_eggs) {
|
||||
if (!pal->read_stale_eggs()) {
|
||||
okflag = false;
|
||||
}
|
||||
}
|
||||
|
||||
pal->generate_images();
|
||||
|
||||
if (!pal->write_eggs()) {
|
||||
okflag = false;
|
||||
}
|
||||
|
||||
if (!state_file.open_write(state_filename) ||
|
||||
!state_file.write_object(pal)) {
|
||||
nout << "Unable to write palettization information to " << state_filename
|
||||
<< "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pi_file.close();
|
||||
state_file.close();
|
||||
|
||||
write_eggs();
|
||||
if (!okflag) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -43,10 +43,11 @@ private:
|
|||
// They're not saved for future sessions.
|
||||
bool _report_pi;
|
||||
bool _statistics_only;
|
||||
bool _all_textures;
|
||||
bool _force_optimal;
|
||||
bool _force_redo_all;
|
||||
bool _optimal_resize;
|
||||
bool _touch_eggs;
|
||||
bool _redo_eggs;
|
||||
bool _dont_lock_pi;
|
||||
|
||||
bool _describe_input_file;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
// Filename: filenameUnifier.cxx
|
||||
// Created by: drose (05Dec00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "filenameUnifier.h"
|
||||
|
||||
#include <executionEnvironment.h>
|
||||
|
||||
Filename FilenameUnifier::_txa_filename;
|
||||
Filename FilenameUnifier::_txa_dir;
|
||||
Filename FilenameUnifier::_rel_dirname;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FilenameUnifier::set_txa_filename
|
||||
// Access: Public, Static
|
||||
// Description: Notes the filename the .txa file was found in. This
|
||||
// may have come from the command line, or it may have
|
||||
// been implicitly located. This has other implications
|
||||
// for the FilenameUnifier, particularly in locating the bam
|
||||
// file that saves the filenameUnifier state from last
|
||||
// session.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FilenameUnifier::
|
||||
set_txa_filename(const Filename &txa_filename) {
|
||||
_txa_filename = txa_filename;
|
||||
_txa_dir = txa_filename.get_dirname();
|
||||
_txa_dir.make_canonical();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FilenameUnifier::set_rel_dirname
|
||||
// Access: Public, Static
|
||||
// Description: Sets the name of the directory that texture filenames
|
||||
// will be written relative to, when generating egg
|
||||
// files. This is not the directory the textures are
|
||||
// actually written to (see set_map_dirname()), but
|
||||
// rather is the name of some directory above that,
|
||||
// which will be the starting point for the pathnames
|
||||
// written to the egg files. If this is empty, the full
|
||||
// pathnames will be written to the egg files.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FilenameUnifier::
|
||||
set_rel_dirname(const Filename &rel_dirname) {
|
||||
_rel_dirname = rel_dirname;
|
||||
if (!_rel_dirname.empty()) {
|
||||
_rel_dirname.make_canonical();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FilenameUnifier::make_bam_filename
|
||||
// Access: Public, Static
|
||||
// Description: Returns a new filename that's made relative to the
|
||||
// bam file itself, suitable for writing to the bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Filename FilenameUnifier::
|
||||
make_bam_filename(Filename filename) {
|
||||
filename.make_canonical();
|
||||
filename.make_relative_to(_txa_dir);
|
||||
return filename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FilenameUnifier::get_bam_filename
|
||||
// Access: Public, Static
|
||||
// Description: Returns an absolute pathname based on the given
|
||||
// relative pathname, presumably read from the bam file
|
||||
// and relative to the bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Filename FilenameUnifier::
|
||||
get_bam_filename(Filename filename) {
|
||||
if (!filename.empty()) {
|
||||
filename.make_absolute(_txa_dir);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FilenameUnifier::make_egg_filename
|
||||
// Access: Public, Static
|
||||
// Description: Returns a new filename that's made relative to the
|
||||
// rel_directory, suitable for writing out within egg
|
||||
// files.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Filename FilenameUnifier::
|
||||
make_egg_filename(Filename filename) {
|
||||
if (!filename.empty()) {
|
||||
filename.make_canonical();
|
||||
filename.make_relative_to(_rel_dirname);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FilenameUnifier::make_user_filename
|
||||
// Access: Public, Static
|
||||
// Description: Returns a new filename that's made relative to the
|
||||
// current directory, suitable for reporting to the
|
||||
// user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Filename FilenameUnifier::
|
||||
make_user_filename(Filename filename) {
|
||||
if (!filename.empty()) {
|
||||
filename.make_canonical();
|
||||
filename.make_relative_to(ExecutionEnvironment::get_cwd());
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Filename: filenameUnifier.h
|
||||
// Created by: drose (05Dec00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FILENAMEUNIFIER_H
|
||||
#define FILENAMEUNIFIER_H
|
||||
|
||||
#include <pandatoolbase.h>
|
||||
|
||||
#include <filename.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : FilenameUnifier
|
||||
// Description : This static class does the job of converting
|
||||
// filenames from relative to absolute to canonical or
|
||||
// whatever is appropriate. Its main purpose is to
|
||||
// allow us to write relative pathnames to the bam file
|
||||
// and turn them back into absolute pathnames on read,
|
||||
// so that a given bam file does not get tied to
|
||||
// absolute pathnames.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class FilenameUnifier {
|
||||
public:
|
||||
static void set_txa_filename(const Filename &txa_filename);
|
||||
static void set_rel_dirname(const Filename &rel_dirname);
|
||||
|
||||
static Filename make_bam_filename(Filename filename);
|
||||
static Filename get_bam_filename(Filename filename);
|
||||
static Filename make_egg_filename(Filename filename);
|
||||
static Filename make_user_filename(Filename filename);
|
||||
|
||||
private:
|
||||
static Filename _txa_filename;
|
||||
static Filename _txa_dir;
|
||||
static Filename _rel_dirname;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -4,6 +4,9 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "imageFile.h"
|
||||
#include "palettizer.h"
|
||||
#include "filenameUnifier.h"
|
||||
#include "paletteGroup.h"
|
||||
|
||||
#include <pnmImage.h>
|
||||
#include <pnmFileType.h>
|
||||
|
|
@ -118,8 +121,33 @@ update_properties(const TextureProperties &properties) {
|
|||
// automatically applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ImageFile::
|
||||
set_filename(const string &basename) {
|
||||
_filename = basename;
|
||||
set_filename(PaletteGroup *group, const string &basename) {
|
||||
// Synthesize the directory name based on the map_dirname set to the
|
||||
// palettizer, and the group's dirname.
|
||||
string dirname;
|
||||
string::iterator pi;
|
||||
pi = pal->_map_dirname.begin();
|
||||
while (pi != pal->_map_dirname.end()) {
|
||||
if (*pi == '%') {
|
||||
++pi;
|
||||
switch (*pi) {
|
||||
case '%':
|
||||
dirname += '%';
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if (group != (PaletteGroup *)NULL) {
|
||||
dirname += group->get_dirname();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
dirname += *pi;
|
||||
}
|
||||
++pi;
|
||||
}
|
||||
|
||||
_filename = Filename(dirname, basename);
|
||||
|
||||
if (_properties._color_type != (PNMFileType *)NULL) {
|
||||
_filename.set_extension
|
||||
|
|
@ -189,17 +217,17 @@ read(PNMImage &image) const {
|
|||
nassertr(!_filename.empty(), false);
|
||||
|
||||
image.set_type(_properties._color_type);
|
||||
nout << "Reading " << _filename << "\n";
|
||||
nout << "Reading " << FilenameUnifier::make_user_filename(_filename) << "\n";
|
||||
if (!image.read(_filename)) {
|
||||
nout << "Unable to read.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_alpha_filename.empty()) {
|
||||
if (!_alpha_filename.empty() && _alpha_filename.exists()) {
|
||||
// Read in a separate color image and an alpha channel image.
|
||||
PNMImage alpha_image;
|
||||
alpha_image.set_type(_properties._alpha_type);
|
||||
nout << "Reading " << _alpha_filename << "\n";
|
||||
nout << "Reading " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
|
||||
if (!alpha_image.read(_alpha_filename)) {
|
||||
nout << "Unable to read.\n";
|
||||
return false;
|
||||
|
|
@ -236,9 +264,11 @@ write(PNMImage &image) const {
|
|||
if (!image.has_alpha() ||
|
||||
_properties._alpha_type == (PNMFileType *)NULL) {
|
||||
if (!_alpha_filename.empty() && _alpha_filename.exists()) {
|
||||
nout << "Deleting " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
|
||||
_alpha_filename.unlink();
|
||||
}
|
||||
nout << "Writing " << _filename << "\n";
|
||||
nout << "Writing " << FilenameUnifier::make_user_filename(_filename) << "\n";
|
||||
_filename.make_dir();
|
||||
if (!image.write(_filename, _properties._color_type)) {
|
||||
nout << "Unable to write.\n";
|
||||
return false;
|
||||
|
|
@ -256,12 +286,14 @@ write(PNMImage &image) const {
|
|||
}
|
||||
|
||||
image.remove_alpha();
|
||||
nout << "Writing " << _filename << "\n";
|
||||
nout << "Writing " << FilenameUnifier::make_user_filename(_filename) << "\n";
|
||||
_filename.make_dir();
|
||||
if (!image.write(_filename, _properties._color_type)) {
|
||||
nout << "Unable to write.\n";
|
||||
return false;
|
||||
}
|
||||
nout << "Writing " << _alpha_filename << "\n";
|
||||
nout << "Writing " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
|
||||
_alpha_filename.make_dir();
|
||||
if (!alpha_image.write(_alpha_filename, _properties._alpha_type)) {
|
||||
nout << "Unable to write.\n";
|
||||
return false;
|
||||
|
|
@ -277,11 +309,11 @@ write(PNMImage &image) const {
|
|||
void ImageFile::
|
||||
unlink() {
|
||||
if (!_filename.empty() && _filename.exists()) {
|
||||
nout << "Deleting " << _filename << "\n";
|
||||
nout << "Deleting " << FilenameUnifier::make_user_filename(_filename) << "\n";
|
||||
_filename.unlink();
|
||||
}
|
||||
if (!_alpha_filename.empty() && _alpha_filename.exists()) {
|
||||
nout << "Deleting " << _alpha_filename << "\n";
|
||||
nout << "Deleting " << FilenameUnifier::make_user_filename(_alpha_filename) << "\n";
|
||||
_alpha_filename.unlink();
|
||||
}
|
||||
}
|
||||
|
|
@ -298,6 +330,7 @@ update_egg_tex(EggTexture *egg_tex) const {
|
|||
egg_tex->set_filename(_filename);
|
||||
|
||||
if (_properties._alpha_type != (PNMFileType *)NULL &&
|
||||
_properties.uses_alpha() &&
|
||||
!_alpha_filename.empty()) {
|
||||
egg_tex->set_alpha_file(_alpha_filename);
|
||||
} else {
|
||||
|
|
@ -315,10 +348,11 @@ update_egg_tex(EggTexture *egg_tex) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ImageFile::
|
||||
output_filename(ostream &out) const {
|
||||
out << _filename;
|
||||
out << FilenameUnifier::make_user_filename(_filename);
|
||||
if (_properties._alpha_type != (PNMFileType *)NULL &&
|
||||
_properties.uses_alpha() &&
|
||||
!_alpha_filename.empty()) {
|
||||
out << " " << _alpha_filename;
|
||||
out << " " << FilenameUnifier::make_user_filename(_alpha_filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -332,8 +366,8 @@ output_filename(ostream &out) const {
|
|||
void ImageFile::
|
||||
write_datagram(BamWriter *writer, Datagram &datagram) {
|
||||
_properties.write_datagram(writer, datagram);
|
||||
datagram.add_string(_filename);
|
||||
datagram.add_string(_alpha_filename);
|
||||
datagram.add_string(FilenameUnifier::make_bam_filename(_filename));
|
||||
datagram.add_string(FilenameUnifier::make_bam_filename(_alpha_filename));
|
||||
datagram.add_bool(_size_known);
|
||||
datagram.add_int32(_x_size);
|
||||
datagram.add_int32(_y_size);
|
||||
|
|
@ -349,8 +383,8 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
void ImageFile::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_properties.fillin(scan, manager);
|
||||
_filename = scan.get_string();
|
||||
_alpha_filename = scan.get_string();
|
||||
_filename = FilenameUnifier::get_bam_filename(scan.get_string());
|
||||
_alpha_filename = FilenameUnifier::get_bam_filename(scan.get_string());
|
||||
_size_known = scan.get_bool();
|
||||
_x_size = scan.get_int32();
|
||||
_y_size = scan.get_int32();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
class PNMImage;
|
||||
class EggTexture;
|
||||
class PaletteGroup;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ImageFile
|
||||
|
|
@ -36,7 +37,7 @@ public:
|
|||
const TextureProperties &get_properties() const;
|
||||
void update_properties(const TextureProperties &properties);
|
||||
|
||||
void set_filename(const string &basename);
|
||||
void set_filename(PaletteGroup *group, const string &basename);
|
||||
const Filename &get_filename() const;
|
||||
const Filename &get_alpha_filename() const;
|
||||
bool exists() const;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ TypeHandle PaletteGroup::_type_handle;
|
|||
PaletteGroup::
|
||||
PaletteGroup() {
|
||||
_egg_count = 0;
|
||||
_dependency_level = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -39,6 +40,41 @@ set_dirname(const string &dirname) {
|
|||
_dirname = dirname;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroup::has_dirname
|
||||
// Access: Public
|
||||
// Description: Returns true if the directory name has been
|
||||
// explicitly set for this group. If it has not,
|
||||
// get_dirname() returns an empty string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PaletteGroup::
|
||||
has_dirname() const {
|
||||
return !_dirname.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroup::get_dirname
|
||||
// Access: Public
|
||||
// Description: Returns the directory name associated with the
|
||||
// palette group. See set_dirname().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const string &PaletteGroup::
|
||||
get_dirname() const {
|
||||
return _dirname;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroup::clear_depends
|
||||
// Access: Public
|
||||
// Description: Eliminates all the dependency information for this
|
||||
// group.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PaletteGroup::
|
||||
clear_depends() {
|
||||
_dependent.clear();
|
||||
_dependency_level = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroup::group_with
|
||||
// Access: Public
|
||||
|
|
@ -66,6 +102,55 @@ get_groups() const {
|
|||
return _dependent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroup::set_dependency_level
|
||||
// Access: Public
|
||||
// Description: Sets the dependency level of this group to the
|
||||
// indicated level, provided that level is not lower
|
||||
// than the level that was set previously. Also
|
||||
// cascades to all dependent groups. See
|
||||
// get_dependency_level().
|
||||
//
|
||||
// This call recurses to correctly set the dependency
|
||||
// level of all PaletteGroups in the hierarchy.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PaletteGroup::
|
||||
set_dependency_level(int level) {
|
||||
if (level > _dependency_level) {
|
||||
_dependency_level = level;
|
||||
PaletteGroups::iterator gi;
|
||||
for (gi = _dependent.begin(); gi != _dependent.end(); ++gi) {
|
||||
(*gi)->set_dependency_level(level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroup::get_dependency_level
|
||||
// Access: Public
|
||||
// Description: Returns the dependency level of this group. This is
|
||||
// a measure of how specific the group is; the lower the
|
||||
// dependency level, the more specific the group.
|
||||
//
|
||||
// Groups depend on other groups in a hierarchical
|
||||
// relationship. In general, if group a depends on
|
||||
// group b, then b->get_dependency_level() >
|
||||
// a->get_dependency_level().
|
||||
//
|
||||
// Thus, groups that lots of other groups depend on have
|
||||
// a higher dependency level; groups that no one else
|
||||
// depends on have a low dependency level. This is
|
||||
// important when deciding which groups are best suited
|
||||
// for assigning a texture to; in general, the texture
|
||||
// should be assigned to the most specific suitable
|
||||
// group (i.e. the one with the lowest dependency
|
||||
// level).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PaletteGroup::
|
||||
get_dependency_level() const {
|
||||
return _dependency_level;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroup::increment_egg_count
|
||||
// Access: Public
|
||||
|
|
@ -261,6 +346,9 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
datagram.add_string(_dirname);
|
||||
_dependent.write_datagram(writer, datagram);
|
||||
|
||||
// We don't write out _dependency_level. It's best to recompute
|
||||
// that each time.
|
||||
|
||||
datagram.add_uint32(_placements.size());
|
||||
Placements::const_iterator pli;
|
||||
for (pli = _placements.begin(); pli != _placements.end(); ++pli) {
|
||||
|
|
|
|||
|
|
@ -37,10 +37,16 @@ public:
|
|||
PaletteGroup();
|
||||
|
||||
void set_dirname(const string &dirname);
|
||||
bool has_dirname() const;
|
||||
const string &get_dirname() const;
|
||||
|
||||
void clear_depends();
|
||||
void group_with(PaletteGroup *other);
|
||||
const PaletteGroups &get_groups() const;
|
||||
|
||||
void set_dependency_level(int level);
|
||||
int get_dependency_level() const;
|
||||
|
||||
void increment_egg_count();
|
||||
int get_egg_count() const;
|
||||
|
||||
|
|
@ -59,6 +65,7 @@ private:
|
|||
string _dirname;
|
||||
int _egg_count;
|
||||
PaletteGroups _dependent;
|
||||
int _dependency_level;
|
||||
|
||||
typedef set<TexturePlacement *> Placements;
|
||||
Placements _placements;
|
||||
|
|
|
|||
|
|
@ -143,6 +143,16 @@ make_intersection(const PaletteGroups &a, const PaletteGroups &b) {
|
|||
_groups.swap(i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroups::clear
|
||||
// Access: Public
|
||||
// Description: Empties the set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PaletteGroups::
|
||||
clear() {
|
||||
_groups.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PaletteGroups::empty
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public:
|
|||
void make_complete(const PaletteGroups &a);
|
||||
void make_union(const PaletteGroups &a, const PaletteGroups &b);
|
||||
void make_intersection(const PaletteGroups &a, const PaletteGroups &b);
|
||||
void clear();
|
||||
|
||||
bool empty() const;
|
||||
size_type size() const;
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ PaletteImage(PalettePage *page, int index) :
|
|||
name << page->get_group()->get_name() << "_palette_"
|
||||
<< page->get_name() << "_" << index + 1;
|
||||
|
||||
set_filename(name.str());
|
||||
set_filename(page->get_group(), name.str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -465,9 +465,10 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
|
||||
writer->write_pointer(datagram, _page);
|
||||
datagram.add_uint32(_index);
|
||||
datagram.add_bool(_new_image);
|
||||
|
||||
// We don't write _new_image, _got_image, or _image. These are all
|
||||
// loaded per-session.
|
||||
// We don't write _got_image or _image. These are loaded
|
||||
// per-session.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -546,4 +547,5 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||
manager->read_pointer(scan, this); // _page
|
||||
|
||||
_index = scan.get_uint32();
|
||||
_new_image = scan.get_bool();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "textureImage.h"
|
||||
#include "string_utils.h"
|
||||
#include "paletteGroup.h"
|
||||
#include "filenameUnifier.h"
|
||||
|
||||
#include <pnmImage.h>
|
||||
#include <pnmFileTypeRegistry.h>
|
||||
|
|
@ -36,6 +37,7 @@ Palettizer() {
|
|||
// version number for all bam and boo files anywhere in the world.
|
||||
_pi_version = 0;
|
||||
|
||||
_map_dirname = "%g";
|
||||
_margin = 2;
|
||||
_repeat_threshold = 250.0;
|
||||
_aggressively_clean_mapdir = true;
|
||||
|
|
@ -61,6 +63,9 @@ void Palettizer::
|
|||
report_pi() const {
|
||||
cout
|
||||
<< "\nparams\n"
|
||||
<< " map directory: " << _map_dirname << "\n"
|
||||
<< " egg relative directory: "
|
||||
<< FilenameUnifier::make_user_filename(_rel_dirname) << "\n"
|
||||
<< " palettize size: " << _pal_x_size << " by " << _pal_y_size << "\n"
|
||||
<< " margin: " << _margin << "\n"
|
||||
<< " repeat threshold: " << _repeat_threshold << "%\n"
|
||||
|
|
@ -108,8 +113,7 @@ report_pi() const {
|
|||
EggFiles::const_iterator ei;
|
||||
for (ei = _egg_files.begin(); ei != _egg_files.end(); ++ei) {
|
||||
EggFile *egg_file = (*ei).second;
|
||||
cout << " " << egg_file->get_name() << ": "
|
||||
<< egg_file->get_groups() << "\n";
|
||||
egg_file->write_description(cout, 2);
|
||||
egg_file->write_texture_refs(cout, 4);
|
||||
}
|
||||
|
||||
|
|
@ -117,35 +121,82 @@ report_pi() const {
|
|||
Groups::const_iterator gi;
|
||||
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||
PaletteGroup *group = (*gi).second;
|
||||
if (gi != _groups.begin()) {
|
||||
cout << "\n";
|
||||
}
|
||||
cout << " " << group->get_name() << ": "
|
||||
<< group->get_groups() << "\n";
|
||||
group->write_image_info(cout, 4);
|
||||
cout << "\n";
|
||||
}
|
||||
|
||||
cout << "textures\n";
|
||||
cout << "\ntextures\n";
|
||||
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
|
||||
TextureImage *texture = (*ti).second;
|
||||
texture->write_scale_info(cout, 2);
|
||||
}
|
||||
|
||||
cout << "\nsurprises\n";
|
||||
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
|
||||
TextureImage *texture = (*ti).second;
|
||||
if (texture->is_surprise()) {
|
||||
cout << " " << texture->get_name() << "\n";
|
||||
}
|
||||
}
|
||||
for (ei = _egg_files.begin(); ei != _egg_files.end(); ++ei) {
|
||||
EggFile *egg_file = (*ei).second;
|
||||
if (egg_file->is_surprise()) {
|
||||
cout << " " << egg_file->get_name() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
cout << "\n";
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Palettizer::run
|
||||
// Function: Palettizer::read_txa_file
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: Reads in the .txa file and keeps it ready for
|
||||
// matching textures and egg files.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Palettizer::
|
||||
run(const TxaFile &txa_file) {
|
||||
read_txa_file(const Filename &txa_filename) {
|
||||
// Clear out the group dependencies, in preparation for reading them
|
||||
// again from the .txa file.
|
||||
Groups::iterator gi;
|
||||
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||
PaletteGroup *group = (*gi).second;
|
||||
group->clear_depends();
|
||||
}
|
||||
|
||||
if (!_txa_file.read(txa_filename)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (_color_type == (PNMFileType *)NULL) {
|
||||
nout << "No valid output image file type available, cannot run.\n"
|
||||
nout << "No valid output image file type available; cannot run.\n"
|
||||
<< "Use :imagetype command in .txa file.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
set<TextureImage *> command_line_textures;
|
||||
// Compute the correct dependency level for each group. This will
|
||||
// help us when we assign the textures to their groups.
|
||||
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||
PaletteGroup *group = (*gi).second;
|
||||
group->set_dependency_level(1);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Palettizer::process_command_line_eggs
|
||||
// Access: Public
|
||||
// Description: Processes all the textures named in the
|
||||
// _command_line_eggs, placing them on the appropriate
|
||||
// palettes or whatever needs to be done with them.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Palettizer::
|
||||
process_command_line_eggs() {
|
||||
_command_line_textures.clear();
|
||||
|
||||
// Start by scanning all the egg files we read up on the command
|
||||
// line.
|
||||
|
|
@ -156,23 +207,23 @@ run(const TxaFile &txa_file) {
|
|||
EggFile *egg_file = (*ei);
|
||||
|
||||
egg_file->scan_textures();
|
||||
egg_file->get_textures(command_line_textures);
|
||||
|
||||
txa_file.match_egg(egg_file);
|
||||
egg_file->get_textures(_command_line_textures);
|
||||
|
||||
egg_file->pre_txa_file();
|
||||
_txa_file.match_egg(egg_file);
|
||||
egg_file->post_txa_file();
|
||||
}
|
||||
|
||||
// Now match each of the textures mentioned in those egg files
|
||||
// against a line in the .txa file.
|
||||
set<TextureImage *>::iterator ti;
|
||||
for (ti = command_line_textures.begin();
|
||||
ti != command_line_textures.end();
|
||||
CommandLineTextures::iterator ti;
|
||||
for (ti = _command_line_textures.begin();
|
||||
ti != _command_line_textures.end();
|
||||
++ti) {
|
||||
TextureImage *texture = *ti;
|
||||
|
||||
texture->pre_txa_file();
|
||||
txa_file.match_texture(texture);
|
||||
_txa_file.match_texture(texture);
|
||||
texture->post_txa_file();
|
||||
}
|
||||
|
||||
|
|
@ -185,8 +236,8 @@ run(const TxaFile &txa_file) {
|
|||
|
||||
// And now, assign each of the current set of textures to an
|
||||
// appropriate group or groups.
|
||||
for (ti = command_line_textures.begin();
|
||||
ti != command_line_textures.end();
|
||||
for (ti = _command_line_textures.begin();
|
||||
ti != _command_line_textures.end();
|
||||
++ti) {
|
||||
TextureImage *texture = *ti;
|
||||
texture->assign_groups();
|
||||
|
|
@ -202,8 +253,8 @@ run(const TxaFile &txa_file) {
|
|||
|
||||
// Now that *that's* done, we need to make sure the various
|
||||
// TexturePlacements require the right size for their textures.
|
||||
for (ti = command_line_textures.begin();
|
||||
ti != command_line_textures.end();
|
||||
for (ti = _command_line_textures.begin();
|
||||
ti != _command_line_textures.end();
|
||||
++ti) {
|
||||
TextureImage *texture = *ti;
|
||||
texture->determine_placement_size();
|
||||
|
|
@ -216,22 +267,160 @@ run(const TxaFile &txa_file) {
|
|||
PaletteGroup *group = (*gi).second;
|
||||
group->place_all();
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, generate all the images.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Palettizer::process_all
|
||||
// Access: Public
|
||||
// Description: Reprocesses all textures known.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Palettizer::
|
||||
process_all() {
|
||||
// If there *were* any egg files on the command line, deal with
|
||||
// them.
|
||||
CommandLineEggs::const_iterator ei;
|
||||
for (ei = _command_line_eggs.begin();
|
||||
ei != _command_line_eggs.end();
|
||||
++ei) {
|
||||
EggFile *egg_file = (*ei);
|
||||
|
||||
egg_file->scan_textures();
|
||||
egg_file->get_textures(_command_line_textures);
|
||||
}
|
||||
|
||||
// Then match up all the egg files we know about with the .txa file.
|
||||
EggFiles::const_iterator efi;
|
||||
for (efi = _egg_files.begin(); efi != _egg_files.end(); ++efi) {
|
||||
EggFile *egg_file = (*efi).second;
|
||||
|
||||
egg_file->pre_txa_file();
|
||||
_txa_file.match_egg(egg_file);
|
||||
egg_file->post_txa_file();
|
||||
}
|
||||
|
||||
// Now match each of the textures in the world against a line in the
|
||||
// .txa file.
|
||||
Textures::iterator ti;
|
||||
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
|
||||
TextureImage *texture = (*ti).second;
|
||||
|
||||
texture->pre_txa_file();
|
||||
_txa_file.match_texture(texture);
|
||||
texture->post_txa_file();
|
||||
}
|
||||
|
||||
// Now that all of our data is read in, build in all the cross links
|
||||
// and back pointers and stuff.
|
||||
for (efi = _egg_files.begin(); efi != _egg_files.end(); ++efi) {
|
||||
(*efi).second->build_cross_links();
|
||||
}
|
||||
|
||||
// And now, assign each texture to an appropriate group or groups.
|
||||
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
|
||||
TextureImage *texture = (*ti).second;
|
||||
texture->assign_groups();
|
||||
}
|
||||
|
||||
// And then the egg files need to sign up for a particular
|
||||
// TexturePlacement, so we can determine some more properties about
|
||||
// how the textures are placed (for instance, how big the UV range
|
||||
// is for a particular TexturePlacement).
|
||||
for (efi = _egg_files.begin(); efi != _egg_files.end(); ++efi) {
|
||||
(*efi).second->choose_placements();
|
||||
}
|
||||
|
||||
// Now that *that's* done, we need to make sure the various
|
||||
// TexturePlacements require the right size for their textures.
|
||||
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
|
||||
TextureImage *texture = (*ti).second;
|
||||
texture->determine_placement_size();
|
||||
}
|
||||
|
||||
// Now that each texture has been assigned to a suitable group,
|
||||
// make sure the textures are placed on specific PaletteImages.
|
||||
Groups::iterator gi;
|
||||
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||
PaletteGroup *group = (*gi).second;
|
||||
group->place_all();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Palettizer::generate_images
|
||||
// Access: Public
|
||||
// Description: Actually generates the appropriate palette and
|
||||
// unplaced texture images into the map directories.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Palettizer::
|
||||
generate_images() {
|
||||
Groups::iterator gi;
|
||||
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||
PaletteGroup *group = (*gi).second;
|
||||
group->update_images();
|
||||
}
|
||||
|
||||
// And now we can adjust all the egg files.
|
||||
for (ei = _command_line_eggs.begin();
|
||||
ei != _command_line_eggs.end();
|
||||
++ei) {
|
||||
EggFile *egg_file = (*ei);
|
||||
egg_file->update_egg();
|
||||
Textures::iterator ti;
|
||||
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
|
||||
TextureImage *texture = (*ti).second;
|
||||
texture->copy_unplaced();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Palettizer::read_stale_eggs
|
||||
// Access: Public
|
||||
// Description: Reads in any egg file that is known to be stale, even
|
||||
// if it was not listed on the command line, so that it
|
||||
// may be updated and written out when write_eggs() is
|
||||
// called. Returns true if successful, or false if
|
||||
// there was some error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Palettizer::
|
||||
read_stale_eggs() {
|
||||
bool okflag = true;
|
||||
|
||||
EggFiles::iterator ei;
|
||||
for (ei = _egg_files.begin(); ei != _egg_files.end(); ++ei) {
|
||||
EggFile *egg_file = (*ei).second;
|
||||
if (!egg_file->has_data() && egg_file->is_stale()) {
|
||||
if (!egg_file->read_egg()) {
|
||||
okflag = false;
|
||||
|
||||
} else {
|
||||
egg_file->scan_textures();
|
||||
egg_file->choose_placements();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return okflag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Palettizer::write_eggs
|
||||
// Access: Public
|
||||
// Description: Adjusts the egg files to reference the newly
|
||||
// generated textures, and writes them out. Returns
|
||||
// true if successful, or false if there was some error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Palettizer::
|
||||
write_eggs() {
|
||||
bool okflag = true;
|
||||
|
||||
EggFiles::iterator ei;
|
||||
for (ei = _egg_files.begin(); ei != _egg_files.end(); ++ei) {
|
||||
EggFile *egg_file = (*ei).second;
|
||||
if (egg_file->has_data()) {
|
||||
egg_file->update_egg();
|
||||
if (!egg_file->write_egg()) {
|
||||
okflag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return okflag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Palettizer::get_egg_file
|
||||
// Access: Public
|
||||
|
|
@ -298,7 +487,11 @@ test_palette_group(const string &name) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PaletteGroup *Palettizer::
|
||||
get_default_group() {
|
||||
return get_palette_group(_default_groupname);
|
||||
PaletteGroup *default_group = get_palette_group(_default_groupname);
|
||||
if (!_default_groupdir.empty() && !default_group->has_dirname()) {
|
||||
default_group->set_dirname(_default_groupdir);
|
||||
}
|
||||
return default_group;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -319,7 +512,7 @@ get_texture(const string &name) {
|
|||
|
||||
TextureImage *image = new TextureImage;
|
||||
image->set_name(name);
|
||||
image->set_filename(name);
|
||||
// image->set_filename(name);
|
||||
_textures.insert(Textures::value_type(name, image));
|
||||
return image;
|
||||
}
|
||||
|
|
@ -358,9 +551,7 @@ void Palettizer::
|
|||
write_datagram(BamWriter *writer, Datagram &datagram) {
|
||||
datagram.add_int32(_pi_version);
|
||||
datagram.add_string(_map_dirname);
|
||||
datagram.add_string(_rel_dirname);
|
||||
datagram.add_string(_default_groupname);
|
||||
datagram.add_string(_default_groupdir);
|
||||
datagram.add_string(FilenameUnifier::make_bam_filename(_rel_dirname));
|
||||
datagram.add_int32(_pal_x_size);
|
||||
datagram.add_int32(_pal_y_size);
|
||||
datagram.add_int32(_margin);
|
||||
|
|
@ -477,9 +668,8 @@ void Palettizer::
|
|||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_pi_version = scan.get_int32();
|
||||
_map_dirname = scan.get_string();
|
||||
_rel_dirname = scan.get_string();
|
||||
_default_groupname = scan.get_string();
|
||||
_default_groupdir = scan.get_string();
|
||||
_rel_dirname = FilenameUnifier::get_bam_filename(scan.get_string());
|
||||
FilenameUnifier::set_rel_dirname(_rel_dirname);
|
||||
_pal_x_size = scan.get_int32();
|
||||
_pal_y_size = scan.get_int32();
|
||||
_margin = scan.get_int32();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <typedWriteable.h>
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
class PNMFileType;
|
||||
|
|
@ -33,7 +34,12 @@ public:
|
|||
Palettizer();
|
||||
|
||||
void report_pi() const;
|
||||
void run(const TxaFile &txa_file);
|
||||
void read_txa_file(const Filename &txa_filename);
|
||||
void process_command_line_eggs();
|
||||
void process_all();
|
||||
void generate_images();
|
||||
bool read_stale_eggs();
|
||||
bool write_eggs();
|
||||
|
||||
EggFile *get_egg_file(const string &name);
|
||||
PaletteGroup *get_palette_group(const string &name);
|
||||
|
|
@ -53,13 +59,17 @@ public:
|
|||
RU_poly
|
||||
};
|
||||
|
||||
// The following parameter values specifically relate to textures
|
||||
// and palettes. These values are stored in the .pi file for future
|
||||
// reference.
|
||||
Filename _map_dirname;
|
||||
Filename _rel_dirname;
|
||||
// These values are not stored in the bam file, but are specific to
|
||||
// each session.
|
||||
TxaFile _txa_file;
|
||||
string _default_groupname;
|
||||
string _default_groupdir;
|
||||
|
||||
// The following parameter values specifically relate to textures
|
||||
// and palettes. These values are stored in the bam file for future
|
||||
// reference.
|
||||
string _map_dirname;
|
||||
Filename _rel_dirname;
|
||||
int _pal_x_size, _pal_y_size;
|
||||
int _margin;
|
||||
double _repeat_threshold;
|
||||
|
|
@ -79,6 +89,9 @@ private:
|
|||
typedef vector<EggFile *> CommandLineEggs;
|
||||
CommandLineEggs _command_line_eggs;
|
||||
|
||||
typedef set<TextureImage *> CommandLineTextures;
|
||||
CommandLineTextures _command_line_textures;
|
||||
|
||||
typedef map<string, PaletteGroup *> Groups;
|
||||
Groups _groups;
|
||||
|
||||
|
|
|
|||
|
|
@ -120,19 +120,6 @@ read_header() {
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SourceTextureImage::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SourceTextureImage::
|
||||
output(ostream &out) const {
|
||||
out << _filename;
|
||||
if (!_alpha_filename.empty()) {
|
||||
out << " (" << _alpha_filename << ")";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SourceTextureImage::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ public:
|
|||
bool get_size();
|
||||
bool read_header();
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
bool _read_header;
|
||||
bool _successfully_read_header;
|
||||
|
|
@ -67,7 +65,7 @@ private:
|
|||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const SourceTextureImage &source) {
|
||||
source.output(out);
|
||||
source.output_filename(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "textureImage.h"
|
||||
#include "sourceTextureImage.h"
|
||||
#include "destTextureImage.h"
|
||||
#include "eggFile.h"
|
||||
#include "paletteGroup.h"
|
||||
#include "texturePlacement.h"
|
||||
|
|
@ -26,6 +27,8 @@ TextureImage::
|
|||
TextureImage() {
|
||||
_preferred_source = (SourceTextureImage *)NULL;
|
||||
_read_source_image = false;
|
||||
_got_dest_image = false;
|
||||
_is_surprise = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -38,7 +41,7 @@ TextureImage() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TextureImage::
|
||||
note_egg_file(EggFile *egg_file) {
|
||||
nassertv(!egg_file->get_groups().empty());
|
||||
nassertv(!egg_file->get_complete_groups().empty());
|
||||
_egg_files.insert(egg_file);
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +76,7 @@ assign_groups() {
|
|||
EggFiles::const_iterator ei;
|
||||
for (ei = _egg_files.begin(); ei != _egg_files.end(); ++ei) {
|
||||
PaletteGroups intersect;
|
||||
intersect.make_intersection(_explicitly_assigned_groups, (*ei)->get_groups());
|
||||
intersect.make_intersection(_explicitly_assigned_groups, (*ei)->get_complete_groups());
|
||||
if (!intersect.empty()) {
|
||||
// This egg file is satisfied by one of the texture's explicit
|
||||
// assignments.
|
||||
|
|
@ -100,12 +103,13 @@ assign_groups() {
|
|||
PaletteGroups total;
|
||||
WorkingEggs::const_iterator ei;
|
||||
for (ei = needed_eggs.begin(); ei != needed_eggs.end(); ++ei) {
|
||||
total.make_union(total, (*ei)->get_groups());
|
||||
total.make_union(total, (*ei)->get_complete_groups());
|
||||
}
|
||||
|
||||
// Now, find the group that will satisfy the most egg files. If two
|
||||
// groups satisfy the same number of egg files, choose the one that
|
||||
// has the fewest egg files sharing it.
|
||||
// Now, find the group that will satisfy the most egg files. If
|
||||
// two groups satisfy the same number of egg files, choose (a) the
|
||||
// most specific one, i.e. with the lowest dependency_level value,
|
||||
// and (b) the one that has the fewest egg files sharing it.
|
||||
nassertv(!total.empty());
|
||||
PaletteGroups::iterator gi = total.begin();
|
||||
PaletteGroup *best = (*gi);
|
||||
|
|
@ -113,10 +117,22 @@ assign_groups() {
|
|||
++gi;
|
||||
while (gi != total.end()) {
|
||||
PaletteGroup *group = (*gi);
|
||||
|
||||
// Do we prefer this group to our current 'best'?
|
||||
bool prefer_group = false;
|
||||
int group_egg_count = compute_egg_count(group, needed_eggs);
|
||||
if (group_egg_count > best_egg_count ||
|
||||
(group_egg_count == best_egg_count &&
|
||||
group->get_egg_count() < best->get_egg_count())) {
|
||||
if (group_egg_count != best_egg_count) {
|
||||
prefer_group = (group_egg_count > best_egg_count);
|
||||
|
||||
} else if (group->get_dependency_level() != best->get_dependency_level()){
|
||||
prefer_group =
|
||||
(group->get_dependency_level() < best->get_dependency_level());
|
||||
|
||||
} else {
|
||||
prefer_group = (group->get_egg_count() < best->get_egg_count());
|
||||
}
|
||||
|
||||
if (prefer_group) {
|
||||
best = group;
|
||||
best_egg_count = group_egg_count;
|
||||
}
|
||||
|
|
@ -129,7 +145,7 @@ assign_groups() {
|
|||
|
||||
WorkingEggs next_needed_eggs;
|
||||
for (ei = needed_eggs.begin(); ei != needed_eggs.end(); ++ei) {
|
||||
if ((*ei)->get_groups().count(best) == 0) {
|
||||
if ((*ei)->get_complete_groups().count(best) == 0) {
|
||||
// This one wasn't eliminated.
|
||||
next_needed_eggs.push_back(*ei);
|
||||
}
|
||||
|
|
@ -209,6 +225,7 @@ pre_txa_file() {
|
|||
}
|
||||
|
||||
_request.pre_txa_file();
|
||||
_is_surprise = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -332,6 +349,19 @@ get_margin() const {
|
|||
return _request._margin;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::is_surprise
|
||||
// Access: Public
|
||||
// Description: Returns true if this particular texture is a
|
||||
// 'surprise', i.e. it wasn't matched by a line in the
|
||||
// .txa file that didn't include the keyword 'cont'.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TextureImage::
|
||||
is_surprise() const {
|
||||
return _is_surprise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::get_source
|
||||
|
|
@ -359,6 +389,7 @@ get_source(const Filename &filename, const Filename &alpha_filename) {
|
|||
// next time someone asks.
|
||||
_preferred_source = (SourceTextureImage *)NULL;
|
||||
_read_source_image = false;
|
||||
_got_dest_image = false;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
|
@ -387,6 +418,62 @@ get_preferred_source() {
|
|||
return _preferred_source;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::copy_unplaced
|
||||
// Access: Public
|
||||
// Description: Copies the texture to whichever destination
|
||||
// directories are appropriate for the groups in which
|
||||
// it has been unplaced. Also removes the old filenames
|
||||
// for previous sessions where it was unplaced, but is
|
||||
// no longer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureImage::
|
||||
copy_unplaced() {
|
||||
// First, we need to build up the set of DestTextureImages that
|
||||
// represents the files we need to generate.
|
||||
Dests generate;
|
||||
|
||||
// Go through all the TexturePlacements and note the ones for which
|
||||
// we're unplaced. We check get_omit_reason() and not is_placed(),
|
||||
// because we want to consider solitary images to be unplaced in
|
||||
// this case.
|
||||
Placement::iterator pi;
|
||||
for (pi = _placement.begin(); pi != _placement.end(); ++pi) {
|
||||
TexturePlacement *placement = (*pi).second;
|
||||
if (placement->get_omit_reason() != OR_none) {
|
||||
DestTextureImage *dest = new DestTextureImage(placement);
|
||||
Filename filename = dest->get_filename();
|
||||
filename.make_canonical();
|
||||
|
||||
pair<Dests::iterator, bool> insert_result = generate.insert
|
||||
(Dests::value_type(filename, dest));
|
||||
if (!insert_result.second) {
|
||||
// At least two DestTextureImages map to the same filename, no
|
||||
// sweat.
|
||||
delete dest;
|
||||
dest = (*insert_result.first).second;
|
||||
}
|
||||
|
||||
placement->set_dest(dest);
|
||||
}
|
||||
}
|
||||
|
||||
// Now remove the old files that we previously generated, but we
|
||||
// don't need any more.
|
||||
remove_old_dests(generate, _dests);
|
||||
|
||||
// And then copy in the new ones.
|
||||
copy_new_dests(generate, _dests);
|
||||
|
||||
// Clean up the old set.
|
||||
Dests::iterator di;
|
||||
for (di = _dests.begin(); di != _dests.end(); ++di) {
|
||||
delete (*di).second;
|
||||
}
|
||||
|
||||
_dests.swap(generate);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::read_source_image
|
||||
// Access: Public
|
||||
|
|
@ -406,6 +493,27 @@ read_source_image() {
|
|||
return _source_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::get_dest_image
|
||||
// Access: Public
|
||||
// Description: Returns the image appropriate for writing to the
|
||||
// destination directory, having been resized and
|
||||
// everything.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const PNMImage &TextureImage::
|
||||
get_dest_image() {
|
||||
if (!_got_dest_image) {
|
||||
const PNMImage &source_image = read_source_image();
|
||||
_dest_image.clear(get_x_size(), get_y_size(), get_num_channels(),
|
||||
source_image.get_maxval());
|
||||
_dest_image.quick_filter_from(source_image);
|
||||
|
||||
_got_dest_image = true;
|
||||
}
|
||||
|
||||
return _dest_image;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::write_source_pathnames
|
||||
// Access: Public
|
||||
|
|
@ -464,7 +572,7 @@ write_scale_info(ostream &out, int indent_level) {
|
|||
double scale =
|
||||
100.0 * (((double)get_x_size() / (double)source->get_x_size()) +
|
||||
((double)get_y_size() / (double)source->get_y_size())) / 2.0;
|
||||
out << " " << scale << "%";
|
||||
out << " scale " << scale << "%";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
|
|
@ -483,7 +591,7 @@ compute_egg_count(PaletteGroup *group,
|
|||
|
||||
WorkingEggs::const_iterator ei;
|
||||
for (ei = egg_files.begin(); ei != egg_files.end(); ++ei) {
|
||||
if ((*ei)->get_groups().count(group) != 0) {
|
||||
if ((*ei)->get_complete_groups().count(group) != 0) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
|
@ -589,6 +697,88 @@ consider_grayscale() {
|
|||
_properties._num_channels -= 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::remove_old_dests
|
||||
// Access: Private
|
||||
// Description: Removes all of the filenames named in b that are not
|
||||
// also named in a.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureImage::
|
||||
remove_old_dests(const TextureImage::Dests &a, const TextureImage::Dests &b) {
|
||||
Dests::const_iterator ai = a.begin();
|
||||
Dests::const_iterator bi = b.begin();
|
||||
|
||||
while (ai != a.end() && bi != b.end()) {
|
||||
const string &astr = (*ai).first;
|
||||
const string &bstr = (*bi).first;
|
||||
|
||||
if (astr < bstr) {
|
||||
// Here's a filename in a, not in b.
|
||||
++ai;
|
||||
|
||||
} else if (bstr < astr) {
|
||||
// Here's a filename in b, not in a.
|
||||
(*bi).second->unlink();
|
||||
++bi;
|
||||
|
||||
} else { // bstr == astr
|
||||
// Here's a filename in both a and b.
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
}
|
||||
|
||||
while (bi != b.end()) {
|
||||
// Here's a filename in b, not in a.
|
||||
(*bi).second->unlink();
|
||||
++bi;
|
||||
}
|
||||
|
||||
while (ai != a.end()) {
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::copy_new_dests
|
||||
// Access: Private
|
||||
// Description: Copies a resized texture into each filename named in
|
||||
// a that is not also listed in b, or whose
|
||||
// corresponding listing in b is out of date.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureImage::
|
||||
copy_new_dests(const TextureImage::Dests &a, const TextureImage::Dests &b) {
|
||||
Dests::const_iterator ai = a.begin();
|
||||
Dests::const_iterator bi = b.begin();
|
||||
|
||||
while (ai != a.end() && bi != b.end()) {
|
||||
const string &astr = (*ai).first;
|
||||
const string &bstr = (*bi).first;
|
||||
|
||||
if (astr < bstr) {
|
||||
// Here's a filename in a, not in b.
|
||||
(*ai).second->copy(this);
|
||||
++ai;
|
||||
|
||||
} else if (bstr < astr) {
|
||||
// Here's a filename in b, not in a.
|
||||
++bi;
|
||||
|
||||
} else { // bstr == astr
|
||||
// Here's a filename in both a and b.
|
||||
(*ai).second->copy_if_stale((*bi).second, this);
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
}
|
||||
|
||||
while (ai != a.end()) {
|
||||
// Here's a filename in a, not in b.
|
||||
(*ai).second->copy(this);
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureImage::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
|
@ -621,6 +811,8 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
// We don't write out _preferred_source; this is redetermined each
|
||||
// session.
|
||||
|
||||
datagram.add_bool(_is_surprise);
|
||||
|
||||
// We don't write out _explicitly_assigned_groups; this is re-read
|
||||
// from the .txa file each time.
|
||||
|
||||
|
|
@ -641,8 +833,15 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
writer->write_pointer(datagram, (*si).second);
|
||||
}
|
||||
|
||||
// We don't write out _read_source_image or _source_image; this must
|
||||
// be reread each session.
|
||||
datagram.add_uint32(_dests.size());
|
||||
Dests::const_iterator di;
|
||||
for (di = _dests.begin(); di != _dests.end(); ++di) {
|
||||
writer->write_pointer(datagram, (*di).second);
|
||||
}
|
||||
|
||||
// We don't write out _read_source_image, _source_image,
|
||||
// _got_dest_image, or _dest_image; these must be reread each
|
||||
// session.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -656,7 +855,7 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int TextureImage::
|
||||
complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
|
||||
nassertr((int)plist.size() >= _num_placement * 2 + _num_sources, 0);
|
||||
nassertr((int)plist.size() >= _num_placement * 2 + _num_sources + _num_dests, 0);
|
||||
int index = 0;
|
||||
|
||||
int i;
|
||||
|
|
@ -680,6 +879,13 @@ complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
|
|||
index++;
|
||||
}
|
||||
|
||||
for (i = 0; i < _num_dests; i++) {
|
||||
DestTextureImage *dest;
|
||||
DCAST_INTO_R(dest, plist[index], index);
|
||||
_dests.insert(Dests::value_type(dest->get_filename(), dest));
|
||||
index++;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
|
@ -716,6 +922,8 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||
ImageFile::fillin(scan, manager);
|
||||
set_name(scan.get_string());
|
||||
|
||||
_is_surprise = scan.get_bool();
|
||||
|
||||
_actual_assigned_groups.fillin(scan, manager);
|
||||
|
||||
_num_placement = scan.get_uint32();
|
||||
|
|
@ -723,4 +931,6 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||
|
||||
_num_sources = scan.get_uint32();
|
||||
manager->read_pointers(scan, this, _num_sources);
|
||||
_num_dests = scan.get_uint32();
|
||||
manager->read_pointers(scan, this, _num_dests);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <set>
|
||||
|
||||
class SourceTextureImage;
|
||||
class DestTextureImage;
|
||||
class TexturePlacement;
|
||||
class EggFile;
|
||||
|
||||
|
|
@ -55,15 +56,17 @@ public:
|
|||
bool get_omit() const;
|
||||
double get_repeat_threshold() const;
|
||||
int get_margin() const;
|
||||
|
||||
bool is_surprise() const;
|
||||
|
||||
SourceTextureImage *get_source(const Filename &filename,
|
||||
const Filename &alpha_filename);
|
||||
|
||||
SourceTextureImage *get_preferred_source();
|
||||
bool get_size();
|
||||
|
||||
void copy_unplaced();
|
||||
|
||||
const PNMImage &read_source_image();
|
||||
const PNMImage &get_dest_image();
|
||||
|
||||
void write_source_pathnames(ostream &out, int indent_level = 0) const;
|
||||
void write_scale_info(ostream &out, int indent_level = 0);
|
||||
|
|
@ -71,6 +74,8 @@ public:
|
|||
private:
|
||||
typedef set<EggFile *> EggFiles;
|
||||
typedef vector<EggFile *> WorkingEggs;
|
||||
typedef map<string, SourceTextureImage *> Sources;
|
||||
typedef map<string, DestTextureImage *> Dests;
|
||||
|
||||
static int compute_egg_count(PaletteGroup *group,
|
||||
const WorkingEggs &egg_files);
|
||||
|
|
@ -78,9 +83,14 @@ private:
|
|||
void assign_to_groups(const PaletteGroups &groups);
|
||||
void consider_grayscale();
|
||||
|
||||
void remove_old_dests(const Dests &a, const Dests &b);
|
||||
void copy_new_dests(const Dests &a, const Dests &b);
|
||||
|
||||
private:
|
||||
TextureRequest _request;
|
||||
TextureProperties _pre_txa_properties;
|
||||
SourceTextureImage *_preferred_source;
|
||||
bool _is_surprise;
|
||||
|
||||
PaletteGroups _explicitly_assigned_groups;
|
||||
PaletteGroups _actual_assigned_groups;
|
||||
|
|
@ -90,11 +100,13 @@ private:
|
|||
typedef map<PaletteGroup *, TexturePlacement *> Placement;
|
||||
Placement _placement;
|
||||
|
||||
typedef map<string, SourceTextureImage *> Sources;
|
||||
Sources _sources;
|
||||
Dests _dests;
|
||||
|
||||
bool _read_source_image;
|
||||
PNMImage _source_image;
|
||||
bool _got_dest_image;
|
||||
PNMImage _dest_image;
|
||||
|
||||
|
||||
// The TypedWriteable interface follows.
|
||||
|
|
@ -113,6 +125,7 @@ private:
|
|||
// don't use them otherwise.
|
||||
int _num_placement;
|
||||
int _num_sources;
|
||||
int _num_dests;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "paletteGroup.h"
|
||||
#include "paletteImage.h"
|
||||
#include "palettizer.h"
|
||||
#include "eggFile.h"
|
||||
|
||||
#include <indent.h>
|
||||
#include <datagram.h>
|
||||
|
|
@ -30,6 +31,7 @@ TexturePlacement() {
|
|||
_texture = (TextureImage *)NULL;
|
||||
_group = (PaletteGroup *)NULL;
|
||||
_image = (PaletteImage *)NULL;
|
||||
_dest = (DestTextureImage *)NULL;
|
||||
_has_uvs = false;
|
||||
_size_known = false;
|
||||
_is_filled = true;
|
||||
|
|
@ -55,6 +57,7 @@ TexturePlacement(TextureImage *texture, PaletteGroup *group) :
|
|||
}
|
||||
|
||||
_image = (PaletteImage *)NULL;
|
||||
_dest = (DestTextureImage *)NULL;
|
||||
_has_uvs = false;
|
||||
_size_known = false;
|
||||
_is_filled = false;
|
||||
|
|
@ -119,8 +122,11 @@ get_group() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TexturePlacement::
|
||||
add_egg(TextureReference *reference) {
|
||||
reference->mark_egg_stale();
|
||||
/*
|
||||
_has_uvs = false;
|
||||
_size_known = false;
|
||||
*/
|
||||
_references.insert(reference);
|
||||
}
|
||||
|
||||
|
|
@ -132,11 +138,53 @@ add_egg(TextureReference *reference) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TexturePlacement::
|
||||
remove_egg(TextureReference *reference) {
|
||||
_has_uvs = false;
|
||||
_size_known = false;
|
||||
reference->mark_egg_stale();
|
||||
/*
|
||||
_has_uvs = false;
|
||||
_size_known = false;
|
||||
*/
|
||||
_references.erase(reference);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePlacement::mark_eggs_stale
|
||||
// Access: Public
|
||||
// Description: Marks all the egg files that reference this placement
|
||||
// stale. Presumably this is called after moving the
|
||||
// texture around in the palette or something.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TexturePlacement::
|
||||
mark_eggs_stale() {
|
||||
References::iterator ri;
|
||||
for (ri = _references.begin(); ri != _references.end(); ++ri) {
|
||||
TextureReference *reference = (*ri);
|
||||
|
||||
reference->mark_egg_stale();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePlacement::set_dest
|
||||
// Access: Public
|
||||
// Description: Sets the DestTextureImage that corresponds to this
|
||||
// texture as it was copied to the install directory.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TexturePlacement::
|
||||
set_dest(DestTextureImage *dest) {
|
||||
_dest = dest;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePlacement::get_dest
|
||||
// Access: Public
|
||||
// Description: Returns the DestTextureImage that corresponds to this
|
||||
// texture as it was copied to the install directory.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DestTextureImage *TexturePlacement::
|
||||
get_dest() const {
|
||||
return _dest;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexturePlacement::determine_size
|
||||
// Access: Public
|
||||
|
|
@ -358,7 +406,9 @@ get_y_size() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
double TexturePlacement::
|
||||
get_uv_area() const {
|
||||
nassertr(_has_uvs, 0.0);
|
||||
if (!_has_uvs) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
TexCoordd range = _position._max_uv - _position._min_uv;
|
||||
return range[0] * range[1];
|
||||
|
|
@ -462,8 +512,7 @@ get_placed_y_size() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
double TexturePlacement::
|
||||
get_placed_uv_area() const {
|
||||
nassertr(_has_uvs, 0.0);
|
||||
|
||||
nassertr(is_placed(), 0);
|
||||
TexCoordd range = _placed._max_uv - _placed._min_uv;
|
||||
return range[0] * range[1];
|
||||
}
|
||||
|
|
@ -502,8 +551,9 @@ force_replace() {
|
|||
if (_image != (PaletteImage *)NULL) {
|
||||
_image->unplace(this);
|
||||
_image = (PaletteImage *)NULL;
|
||||
_omit_reason = OR_working;
|
||||
}
|
||||
_omit_reason = OR_working;
|
||||
mark_eggs_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -519,7 +569,10 @@ force_replace() {
|
|||
void TexturePlacement::
|
||||
omit_solitary() {
|
||||
nassertv(is_placed());
|
||||
_omit_reason = OR_solitary;
|
||||
if (_omit_reason != OR_solitary) {
|
||||
mark_eggs_stale();
|
||||
_omit_reason = OR_solitary;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -531,7 +584,10 @@ omit_solitary() {
|
|||
void TexturePlacement::
|
||||
not_solitary() {
|
||||
nassertv(is_placed());
|
||||
_omit_reason = OR_none;
|
||||
if (_omit_reason != OR_none) {
|
||||
mark_eggs_stale();
|
||||
_omit_reason = OR_none;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -807,6 +863,9 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
writer->write_pointer(datagram, _texture);
|
||||
writer->write_pointer(datagram, _group);
|
||||
writer->write_pointer(datagram, _image);
|
||||
|
||||
// We don't write _dest. That can safely be redetermined each
|
||||
// session.
|
||||
|
||||
datagram.add_bool(_has_uvs);
|
||||
datagram.add_bool(_size_known);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#include <set>
|
||||
|
||||
|
||||
class TextureImage;
|
||||
class DestTextureImage;
|
||||
class PaletteGroup;
|
||||
class PaletteImage;
|
||||
class PalettePage;
|
||||
|
|
@ -47,6 +47,10 @@ public:
|
|||
|
||||
void add_egg(TextureReference *reference);
|
||||
void remove_egg(TextureReference *reference);
|
||||
void mark_eggs_stale();
|
||||
|
||||
void set_dest(DestTextureImage *dest);
|
||||
DestTextureImage *get_dest() const;
|
||||
|
||||
bool determine_size();
|
||||
OmitReason get_omit_reason() const;
|
||||
|
|
@ -83,6 +87,7 @@ private:
|
|||
TextureImage *_texture;
|
||||
PaletteGroup *_group;
|
||||
PaletteImage *_image;
|
||||
DestTextureImage *_dest;
|
||||
|
||||
bool _has_uvs;
|
||||
bool _size_known;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@
|
|||
#include "textureImage.h"
|
||||
#include "paletteImage.h"
|
||||
#include "sourceTextureImage.h"
|
||||
#include "destTextureImage.h"
|
||||
#include "texturePlacement.h"
|
||||
#include "palettizer.h"
|
||||
#include "eggFile.h"
|
||||
|
||||
#include <indent.h>
|
||||
#include <eggTexture.h>
|
||||
|
|
@ -32,6 +34,7 @@ TypeHandle TextureReference::_type_handle;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
TextureReference::
|
||||
TextureReference() {
|
||||
_egg_file = (EggFile *)NULL;
|
||||
_egg_tex = (EggTexture *)NULL;
|
||||
_tex_mat = LMatrix3d::ident_mat();
|
||||
_inv_tex_mat = LMatrix3d::ident_mat();
|
||||
|
|
@ -62,7 +65,8 @@ TextureReference::
|
|||
// extracted from an egg file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureReference::
|
||||
from_egg(EggData *data, EggTexture *egg_tex) {
|
||||
from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex) {
|
||||
_egg_file = egg_file;
|
||||
_egg_tex = egg_tex;
|
||||
_egg_data = data;
|
||||
|
||||
|
|
@ -112,6 +116,16 @@ from_egg(EggData *data, EggTexture *egg_tex) {
|
|||
_wrap_v = egg_tex->determine_wrap_v();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureReference::get_egg_file
|
||||
// Access: Public
|
||||
// Description: Returns the EggFile that references this texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggFile *TextureReference::
|
||||
get_egg_file() const {
|
||||
return _egg_file;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureReference::get_source
|
||||
// Access: Public
|
||||
|
|
@ -237,6 +251,19 @@ get_placement() const {
|
|||
return _placement;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureReference::mark_egg_stale
|
||||
// Access: Public
|
||||
// Description: Marks the egg file that shares this reference as
|
||||
// stale.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureReference::
|
||||
mark_egg_stale() {
|
||||
if (_egg_file != (EggFile *)NULL) {
|
||||
_egg_file->mark_stale();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureReference::update_egg
|
||||
// Access: Public
|
||||
|
|
@ -261,9 +288,9 @@ update_egg() {
|
|||
// The texture does not appear on a palette. This is the easy
|
||||
// case; we simply have to update the texture reference to the new
|
||||
// texture location.
|
||||
TextureImage *texture = _placement->get_texture();
|
||||
nassertv(texture != (TextureImage *)NULL);
|
||||
texture->update_egg_tex(_egg_tex);
|
||||
DestTextureImage *dest = _placement->get_dest();
|
||||
nassertv(dest != (DestTextureImage *)NULL);
|
||||
dest->update_egg_tex(_egg_tex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -601,6 +628,7 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
// We don't write _egg_tex, _egg_data, or _tex_mat; that's specific
|
||||
// to the session.
|
||||
|
||||
writer->write_pointer(datagram, _egg_file);
|
||||
writer->write_pointer(datagram, _source_texture);
|
||||
writer->write_pointer(datagram, _placement);
|
||||
|
||||
|
|
@ -626,9 +654,14 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int TextureReference::
|
||||
complete_pointers(vector_typedWriteable &plist, BamReader *manager) {
|
||||
nassertr((int)plist.size() >= 2, 0);
|
||||
nassertr((int)plist.size() >= 3, 0);
|
||||
int index = 0;
|
||||
|
||||
if (plist[index] != (TypedWriteable *)NULL) {
|
||||
DCAST_INTO_R(_egg_file, plist[index], index);
|
||||
}
|
||||
index++;
|
||||
|
||||
if (plist[index] != (TypedWriteable *)NULL) {
|
||||
DCAST_INTO_R(_source_texture, plist[index], index);
|
||||
}
|
||||
|
|
@ -672,6 +705,7 @@ make_TextureReference(const FactoryParams ¶ms) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void TextureReference::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
manager->read_pointer(scan, this); // _egg_file
|
||||
manager->read_pointer(scan, this); // _source_texture
|
||||
manager->read_pointer(scan, this); // _placement
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
class TextureImage;
|
||||
class SourceTextureImage;
|
||||
class Filename;
|
||||
class EggFile;
|
||||
class EggData;
|
||||
class EggTexture;
|
||||
class EggGroupNode;
|
||||
|
|
@ -34,8 +35,9 @@ public:
|
|||
TextureReference();
|
||||
~TextureReference();
|
||||
|
||||
void from_egg(EggData *data, EggTexture *egg_tex);
|
||||
void from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex);
|
||||
|
||||
EggFile *get_egg_file() const;
|
||||
SourceTextureImage *get_source() const;
|
||||
TextureImage *get_texture() const;
|
||||
|
||||
|
|
@ -50,6 +52,7 @@ public:
|
|||
void clear_placement();
|
||||
TexturePlacement *get_placement() const;
|
||||
|
||||
void mark_egg_stale();
|
||||
void update_egg();
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
|
@ -68,8 +71,10 @@ private:
|
|||
static LVector2d translate_uv(const TexCoordd &min_uv,
|
||||
const TexCoordd &max_uv);
|
||||
|
||||
EggFile *_egg_file;
|
||||
EggTexture *_egg_tex;
|
||||
EggData *_egg_data;
|
||||
|
||||
LMatrix3d _tex_mat, _inv_tex_mat;
|
||||
SourceTextureImage *_source_texture;
|
||||
TexturePlacement *_placement;
|
||||
|
|
|
|||
|
|
@ -56,10 +56,21 @@ parse(const string &line) {
|
|||
|
||||
vector_string::iterator wi;
|
||||
for (wi = words.begin(); wi != words.end(); ++wi) {
|
||||
_patterns.push_back(GlobPattern(*wi));
|
||||
const string &word = (*wi);
|
||||
|
||||
// If the pattern ends in the string ".egg", and only if it ends
|
||||
// in this string, it is deemed an egg pattern and will only be
|
||||
// tested against egg files. If it ends in anything else, it is
|
||||
// deemed a texture pattern and will only be tested against
|
||||
// textures.
|
||||
if (word.length() > 4 && word.substr(word.length() - 4) == ".egg") {
|
||||
_egg_patterns.push_back(GlobPattern(word));
|
||||
} else {
|
||||
_texture_patterns.push_back(GlobPattern(*wi));
|
||||
}
|
||||
}
|
||||
|
||||
if (_patterns.empty()) {
|
||||
if (_egg_patterns.empty() && _texture_patterns.empty()) {
|
||||
nout << "No texture or egg filenames given.\n";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -229,8 +240,8 @@ match_egg(EggFile *egg_file) const {
|
|||
|
||||
bool matched_any = false;
|
||||
Patterns::const_iterator pi;
|
||||
for (pi = _patterns.begin();
|
||||
pi != _patterns.end() && !matched_any;
|
||||
for (pi = _egg_patterns.begin();
|
||||
pi != _egg_patterns.end() && !matched_any;
|
||||
++pi) {
|
||||
matched_any = (*pi).matches(name);
|
||||
}
|
||||
|
|
@ -259,8 +270,7 @@ match_egg(EggFile *egg_file) const {
|
|||
}
|
||||
}
|
||||
|
||||
egg_file->_assigned_groups.make_union
|
||||
(egg_file->_assigned_groups, _palette_groups);
|
||||
egg_file->match_txa_groups(_palette_groups);
|
||||
|
||||
if (got_cont) {
|
||||
// If we have the "cont" keyword, we should keep scanning for
|
||||
|
|
@ -270,6 +280,8 @@ match_egg(EggFile *egg_file) const {
|
|||
|
||||
// Otherwise, in the normal case, a match ends the search for
|
||||
// matches.
|
||||
egg_file->clear_surprise();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -290,8 +302,8 @@ match_texture(TextureImage *texture) const {
|
|||
|
||||
bool matched_any = false;
|
||||
Patterns::const_iterator pi;
|
||||
for (pi = _patterns.begin();
|
||||
pi != _patterns.end() && !matched_any;
|
||||
for (pi = _texture_patterns.begin();
|
||||
pi != _texture_patterns.end() && !matched_any;
|
||||
++pi) {
|
||||
matched_any = (*pi).matches(name);
|
||||
}
|
||||
|
|
@ -387,6 +399,8 @@ match_texture(TextureImage *texture) const {
|
|||
|
||||
// Otherwise, in the normal case, a match ends the search for
|
||||
// matches.
|
||||
texture->_is_surprise = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -398,7 +412,10 @@ match_texture(TextureImage *texture) const {
|
|||
void TxaLine::
|
||||
output(ostream &out) const {
|
||||
Patterns::const_iterator pi;
|
||||
for (pi = _patterns.begin(); pi != _patterns.end(); ++pi) {
|
||||
for (pi = _texture_patterns.begin(); pi != _texture_patterns.end(); ++pi) {
|
||||
out << (*pi) << " ";
|
||||
}
|
||||
for (pi = _egg_patterns.begin(); pi != _egg_patterns.end(); ++pi) {
|
||||
out << (*pi) << " ";
|
||||
}
|
||||
out << ":";
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ public:
|
|||
|
||||
private:
|
||||
typedef vector<GlobPattern> Patterns;
|
||||
Patterns _patterns;
|
||||
Patterns _texture_patterns;
|
||||
Patterns _egg_patterns;
|
||||
|
||||
enum SizeType {
|
||||
ST_none,
|
||||
|
|
|
|||
Loading…
Reference in New Issue