Panda3D
 All Classes Functions Variables Enumerations
palettePage.cxx
00001 // Filename: palettePage.cxx
00002 // Created by:  drose (01Dec00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "palettePage.h"
00016 #include "texturePlacement.h"
00017 #include "textureImage.h"
00018 #include "paletteImage.h"
00019 #include "paletteGroup.h"
00020 
00021 #include "indent.h"
00022 #include "datagram.h"
00023 #include "datagramIterator.h"
00024 #include "bamReader.h"
00025 #include "bamWriter.h"
00026 
00027 #include <algorithm>
00028 
00029 TypeHandle PalettePage::_type_handle;
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: PalettePage::Default Constructor
00033 //       Access: Private
00034 //  Description: The default constructor is only for the convenience
00035 //               of the Bam reader.
00036 ////////////////////////////////////////////////////////////////////
00037 PalettePage::
00038 PalettePage() {
00039   _group = (PaletteGroup *)NULL;
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: PalettePage::Constructor
00044 //       Access: Public
00045 //  Description:
00046 ////////////////////////////////////////////////////////////////////
00047 PalettePage::
00048 PalettePage(PaletteGroup *group, const TextureProperties &properties) :
00049   Namable(properties.get_string()),
00050   _group(group),
00051   _properties(properties)
00052 {
00053 }
00054 
00055 ////////////////////////////////////////////////////////////////////
00056 //     Function: PalettePage::get_group
00057 //       Access: Public
00058 //  Description: Returns the group this particular PalettePage belongs
00059 //               to.
00060 ////////////////////////////////////////////////////////////////////
00061 PaletteGroup *PalettePage::
00062 get_group() const {
00063   return _group;
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: PalettePage::get_properties
00068 //       Access: Public
00069 //  Description: Returns the texture grouping properties that all
00070 //               textures in this page share.
00071 ////////////////////////////////////////////////////////////////////
00072 const TextureProperties &PalettePage::
00073 get_properties() const {
00074   return _properties;
00075 }
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: PalettePage::assign
00079 //       Access: Public
00080 //  Description: Adds the indicated texture to the list of textures to
00081 //               consider placing on the page.
00082 ////////////////////////////////////////////////////////////////////
00083 void PalettePage::
00084 assign(TexturePlacement *placement) {
00085   _assigned.push_back(placement);
00086 }
00087 
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: PalettePage::place_all
00091 //       Access: Public
00092 //  Description: Assigns all the textures to their final home in a
00093 //               PaletteImage somewhere.
00094 ////////////////////////////////////////////////////////////////////
00095 void PalettePage::
00096 place_all() {
00097   // Sort the textures to be placed in order from biggest to smallest,
00098   // as an aid to optimal packing.
00099   sort(_assigned.begin(), _assigned.end(), SortPlacementBySize());
00100 
00101   Assigned::const_iterator ai;
00102   for (ai = _assigned.begin(); ai != _assigned.end(); ++ai) {
00103     TexturePlacement *placement = (*ai);
00104     place(placement);
00105   }
00106 
00107   _assigned.clear();
00108 
00109   // Now, look for solitary images; these are left placed, but flagged
00110   // with OR_solitary, so they won't go into egg references.  There's
00111   // no real point in referencing these.
00112   Images::iterator ii;
00113   for (ii = _images.begin(); ii != _images.end(); ++ii) {
00114     PaletteImage *image = (*ii);
00115     image->check_solitary();
00116   }
00117 }
00118 
00119 ////////////////////////////////////////////////////////////////////
00120 //     Function: PalettePage::place
00121 //       Access: Public
00122 //  Description: Assigns the particular TexturePlacement to a
00123 //               PaletteImage where it fits.
00124 ////////////////////////////////////////////////////////////////////
00125 void PalettePage::
00126 place(TexturePlacement *placement) {
00127   nassertv(placement->get_omit_reason() == OR_working);
00128 
00129   // First, try to place it in one of our existing PaletteImages.
00130   Images::iterator ii;
00131   for (ii = _images.begin(); ii != _images.end(); ++ii) {
00132     PaletteImage *image = (*ii);
00133     if (image->place(placement)) {
00134       return;
00135     }
00136   }
00137 
00138   // No good?  Then we need to create a new PaletteImage for it.
00139   PaletteImage *image = new PaletteImage(this, _images.size());
00140   _images.push_back(image);
00141 
00142   bool placed = image->place(placement);
00143 
00144   // This should have stuck.
00145   nassertv(placed);
00146 }
00147 
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: PalettePage::unplace
00151 //       Access: Public
00152 //  Description: Removes the TexturePlacement from wherever it has
00153 //               been placed.
00154 ////////////////////////////////////////////////////////////////////
00155 void PalettePage::
00156 unplace(TexturePlacement *placement) {
00157   nassertv(placement->is_placed() && placement->get_page() == this);
00158   placement->get_image()->unplace(placement);
00159 }
00160 
00161 ////////////////////////////////////////////////////////////////////
00162 //     Function: PalettePage::write_image_info
00163 //       Access: Public
00164 //  Description: Writes a list of the PaletteImages associated with
00165 //               this page, and all of their textures, to the
00166 //               indicated output stream.
00167 ////////////////////////////////////////////////////////////////////
00168 void PalettePage::
00169 write_image_info(ostream &out, int indent_level) const {
00170   Images::const_iterator ii;
00171   for (ii = _images.begin(); ii != _images.end(); ++ii) {
00172     PaletteImage *image = (*ii);
00173     if (!image->is_empty()) {
00174       indent(out, indent_level);
00175       image->output_filename(out);
00176       out << "\n";
00177       image->write_placements(out, indent_level + 2);
00178     }
00179   }
00180 }
00181 
00182 ////////////////////////////////////////////////////////////////////
00183 //     Function: PalettePage::optimal_resize
00184 //       Access: Public
00185 //  Description: Attempts to resize each PalettteImage down to its
00186 //               smallest possible size.
00187 ////////////////////////////////////////////////////////////////////
00188 void PalettePage::
00189 optimal_resize() {
00190   Images::iterator ii;
00191   for (ii = _images.begin(); ii != _images.end(); ++ii) {
00192     PaletteImage *image = (*ii);
00193     image->optimal_resize();
00194   }
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: PalettePage::reset_images
00199 //       Access: Public
00200 //  Description: Throws away all of the current PaletteImages, so that
00201 //               new ones may be created (and the packing made more
00202 //               optimal).
00203 ////////////////////////////////////////////////////////////////////
00204 void PalettePage::
00205 reset_images() {
00206   Images::iterator ii;
00207   for (ii = _images.begin(); ii != _images.end(); ++ii) {
00208     PaletteImage *image = (*ii);
00209     image->reset_image();
00210     delete image;
00211   }
00212 
00213   _images.clear();
00214 }
00215 
00216 ////////////////////////////////////////////////////////////////////
00217 //     Function: PalettePage::setup_shadow_images
00218 //       Access: Public
00219 //  Description: Ensures that each PaletteImage's _shadow_image has
00220 //               the correct filename and image types, based on what
00221 //               was supplied on the command line and in the .txa
00222 //               file.
00223 ////////////////////////////////////////////////////////////////////
00224 void PalettePage::
00225 setup_shadow_images() {
00226   Images::iterator ii;
00227   for (ii = _images.begin(); ii != _images.end(); ++ii) {
00228     PaletteImage *image = (*ii);
00229     image->setup_shadow_image();
00230   }
00231 }
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: PalettePage::update_images
00235 //       Access: Public
00236 //  Description: Regenerates each PaletteImage on this page that needs
00237 //               it.
00238 ////////////////////////////////////////////////////////////////////
00239 void PalettePage::
00240 update_images(bool redo_all) {
00241   Images::iterator ii;
00242   for (ii = _images.begin(); ii != _images.end(); ++ii) {
00243     PaletteImage *image = (*ii);
00244     image->update_image(redo_all);
00245   }
00246 }
00247 
00248 ////////////////////////////////////////////////////////////////////
00249 //     Function: PalettePage::register_with_read_factory
00250 //       Access: Public, Static
00251 //  Description: Registers the current object as something that can be
00252 //               read from a Bam file.
00253 ////////////////////////////////////////////////////////////////////
00254 void PalettePage::
00255 register_with_read_factory() {
00256   BamReader::get_factory()->
00257     register_factory(get_class_type(), make_PalettePage);
00258 }
00259 
00260 ////////////////////////////////////////////////////////////////////
00261 //     Function: PalettePage::write_datagram
00262 //       Access: Public, Virtual
00263 //  Description: Fills the indicated datagram up with a binary
00264 //               representation of the current object, in preparation
00265 //               for writing to a Bam file.
00266 ////////////////////////////////////////////////////////////////////
00267 void PalettePage::
00268 write_datagram(BamWriter *writer, Datagram &datagram) {
00269   TypedWritable::write_datagram(writer, datagram);
00270   datagram.add_string(get_name());
00271 
00272   writer->write_pointer(datagram, _group);
00273   _properties.write_datagram(writer, datagram);
00274 
00275   // We don't write out _assigned, since that's rebuilt each session.
00276 
00277   datagram.add_uint32(_images.size());
00278   Images::const_iterator ii;
00279   for (ii = _images.begin(); ii != _images.end(); ++ii) {
00280     writer->write_pointer(datagram, *ii);
00281   }
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////////
00285 //     Function: PalettePage::complete_pointers
00286 //       Access: Public, Virtual
00287 //  Description: Called after the object is otherwise completely read
00288 //               from a Bam file, this function's job is to store the
00289 //               pointers that were retrieved from the Bam file for
00290 //               each pointer object written.  The return value is the
00291 //               number of pointers processed from the list.
00292 ////////////////////////////////////////////////////////////////////
00293 int PalettePage::
00294 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00295   int pi = TypedWritable::complete_pointers(p_list, manager);
00296 
00297   if (p_list[pi] != (TypedWritable *)NULL) {
00298     DCAST_INTO_R(_group, p_list[pi], pi);
00299   }
00300   pi++;
00301 
00302   pi += _properties.complete_pointers(p_list + pi, manager);
00303 
00304   int i;
00305   _images.reserve(_num_images);
00306   for (i = 0; i < _num_images; i++) {
00307     PaletteImage *image;
00308     DCAST_INTO_R(image, p_list[pi++], pi);
00309     _images.push_back(image);
00310   }
00311 
00312   return pi;
00313 }
00314 
00315 ////////////////////////////////////////////////////////////////////
00316 //     Function: PalettePage::make_PalettePage
00317 //       Access: Protected
00318 //  Description: This method is called by the BamReader when an object
00319 //               of this type is encountered in a Bam file; it should
00320 //               allocate and return a new object with all the data
00321 //               read.
00322 ////////////////////////////////////////////////////////////////////
00323 TypedWritable* PalettePage::
00324 make_PalettePage(const FactoryParams &params) {
00325   PalettePage *me = new PalettePage;
00326   DatagramIterator scan;
00327   BamReader *manager;
00328 
00329   parse_params(params, scan, manager);
00330   me->fillin(scan, manager);
00331   return me;
00332 }
00333 
00334 ////////////////////////////////////////////////////////////////////
00335 //     Function: PalettePage::fillin
00336 //       Access: Protected
00337 //  Description: Reads the binary data from the given datagram
00338 //               iterator, which was written by a previous call to
00339 //               write_datagram().
00340 ////////////////////////////////////////////////////////////////////
00341 void PalettePage::
00342 fillin(DatagramIterator &scan, BamReader *manager) {
00343   TypedWritable::fillin(scan, manager);
00344   set_name(scan.get_string());
00345 
00346   manager->read_pointer(scan);  // _group
00347   _properties.fillin(scan, manager);
00348 
00349   _num_images = scan.get_uint32();
00350   manager->read_pointers(scan, _num_images);
00351 }
 All Classes Functions Variables Enumerations