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