00001 // Filename: paletteGroup.cxx 00002 // Created by: drose (30Nov00) 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 "paletteGroup.h" 00020 #include "palettePage.h" 00021 #include "texturePlacement.h" 00022 #include "textureImage.h" 00023 #include "palettizer.h" 00024 #include "paletteImage.h" 00025 00026 #include "indent.h" 00027 #include "datagram.h" 00028 #include "datagramIterator.h" 00029 #include "bamReader.h" 00030 #include "bamWriter.h" 00031 #include "indirectCompareNames.h" 00032 #include "pvector.h" 00033 00034 TypeHandle PaletteGroup::_type_handle; 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: PaletteGroup::Constructor 00038 // Access: Public 00039 // Description: 00040 //////////////////////////////////////////////////////////////////// 00041 PaletteGroup:: 00042 PaletteGroup() { 00043 _egg_count = 0; 00044 _dependency_level = 0; 00045 _dependency_order = 0; 00046 _dirname_order = 0; 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: PaletteGroup::set_dirname 00051 // Access: Public 00052 // Description: Sets the directory name associated with the palette 00053 // group. This is an optional feature that can be used 00054 // to place the maps for the different palette groups 00055 // into different install directories. 00056 //////////////////////////////////////////////////////////////////// 00057 void PaletteGroup:: 00058 set_dirname(const string &dirname) { 00059 _dirname = dirname; 00060 } 00061 00062 //////////////////////////////////////////////////////////////////// 00063 // Function: PaletteGroup::has_dirname 00064 // Access: Public 00065 // Description: Returns true if the directory name has been 00066 // explicitly set for this group. If it has not, 00067 // get_dirname() returns an empty string. 00068 //////////////////////////////////////////////////////////////////// 00069 bool PaletteGroup:: 00070 has_dirname() const { 00071 return !_dirname.empty(); 00072 } 00073 00074 //////////////////////////////////////////////////////////////////// 00075 // Function: PaletteGroup::get_dirname 00076 // Access: Public 00077 // Description: Returns the directory name associated with the 00078 // palette group. See set_dirname(). 00079 //////////////////////////////////////////////////////////////////// 00080 const string &PaletteGroup:: 00081 get_dirname() const { 00082 return _dirname; 00083 } 00084 00085 //////////////////////////////////////////////////////////////////// 00086 // Function: PaletteGroup::clear_depends 00087 // Access: Public 00088 // Description: Eliminates all the dependency information for this 00089 // group. 00090 //////////////////////////////////////////////////////////////////// 00091 void PaletteGroup:: 00092 clear_depends() { 00093 _dependent.clear(); 00094 _dependency_level = 0; 00095 _dependency_order = 0; 00096 _dirname_order = 0; 00097 } 00098 00099 //////////////////////////////////////////////////////////////////// 00100 // Function: PaletteGroup::group_with 00101 // Access: Public 00102 // Description: Indicates a dependency of this group on some other 00103 // group. This means that the textures assigned to this 00104 // group may be considered successfully assigned if they 00105 // are actually placed in the other group. In practice, 00106 // this means that the textures associated with the 00107 // other palette group will always be resident at 00108 // runtime when textures from this palette group are 00109 // required. 00110 //////////////////////////////////////////////////////////////////// 00111 void PaletteGroup:: 00112 group_with(PaletteGroup *other) { 00113 _dependent.insert(other); 00114 } 00115 00116 //////////////////////////////////////////////////////////////////// 00117 // Function: PaletteGroup::get_groups 00118 // Access: Public 00119 // Description: Returns the set of groups this group depends on. 00120 //////////////////////////////////////////////////////////////////// 00121 const PaletteGroups &PaletteGroup:: 00122 get_groups() const { 00123 return _dependent; 00124 } 00125 00126 //////////////////////////////////////////////////////////////////// 00127 // Function: PaletteGroup::get_placements 00128 // Access: Public 00129 // Description: Adds the set of TexturePlacements associated with 00130 // this group to the indicated vector. The vector is 00131 // not cleared before this operation; if the user wants 00132 // to retrieve the set of placements particular to this 00133 // group only, it is the user's responsibility to clear 00134 // the vector first. 00135 //////////////////////////////////////////////////////////////////// 00136 void PaletteGroup:: 00137 get_placements(pvector<TexturePlacement *> &placements) const { 00138 Placements::const_iterator pi; 00139 for (pi = _placements.begin(); pi != _placements.end(); ++pi) { 00140 placements.push_back(*pi); 00141 } 00142 } 00143 00144 //////////////////////////////////////////////////////////////////// 00145 // Function: PaletteGroup::get_complete_placements 00146 // Access: Public 00147 // Description: Adds the set of TexturePlacements associated with 00148 // this group and all dependent groups to the indicated 00149 // vector. See get_placements(). 00150 //////////////////////////////////////////////////////////////////// 00151 void PaletteGroup:: 00152 get_complete_placements(pvector<TexturePlacement *> &placements) const { 00153 PaletteGroups complete; 00154 complete.make_complete(_dependent); 00155 00156 PaletteGroups::iterator gi; 00157 for (gi = complete.begin(); gi != complete.end(); ++gi) { 00158 PaletteGroup *group = (*gi); 00159 group->get_placements(placements); 00160 } 00161 00162 get_placements(placements); 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: PaletteGroup::reset_dependency_level 00167 // Access: Public 00168 // Description: Unconditionally sets the dependency level and order 00169 // of this group to zero, in preparation for a later 00170 // call to set_dependency_level(). See 00171 // set_dependency_level(). 00172 //////////////////////////////////////////////////////////////////// 00173 void PaletteGroup:: 00174 reset_dependency_level() { 00175 _dependency_level = 0; 00176 _dependency_order = 0; 00177 _dirname_order = 0; 00178 } 00179 00180 //////////////////////////////////////////////////////////////////// 00181 // Function: PaletteGroup::set_dependency_level 00182 // Access: Public 00183 // Description: Sets the dependency level of this group to the 00184 // indicated level, provided that level is not lower 00185 // than the level that was set previously. Also 00186 // cascades to all dependent groups. See 00187 // get_dependency_level(). 00188 // 00189 // This call recurses to correctly set the dependency 00190 // level of all PaletteGroups in the hierarchy. 00191 //////////////////////////////////////////////////////////////////// 00192 void PaletteGroup:: 00193 set_dependency_level(int level) { 00194 if (level > _dependency_level) { 00195 _dependency_level = level; 00196 PaletteGroups::iterator gi; 00197 for (gi = _dependent.begin(); gi != _dependent.end(); ++gi) { 00198 PaletteGroup *group = (*gi); 00199 group->set_dependency_level(level + 1); 00200 } 00201 } 00202 } 00203 00204 //////////////////////////////////////////////////////////////////// 00205 // Function: PaletteGroup::set_dependency_order 00206 // Access: Public 00207 // Description: Updates the dependency order of this group. This 00208 // number is the inverse of the dependency level, and 00209 // can be used to rank the groups in order so that all 00210 // the groups that a given group depends on will appear 00211 // first in the list. See get_dependency_order(). 00212 // 00213 // This function returns true if anything was changed, 00214 // false otherwise. 00215 //////////////////////////////////////////////////////////////////// 00216 bool PaletteGroup:: 00217 set_dependency_order() { 00218 bool any_changed = false; 00219 00220 PaletteGroups::iterator gi; 00221 for (gi = _dependent.begin(); gi != _dependent.end(); ++gi) { 00222 PaletteGroup *group = (*gi); 00223 if (group->set_dependency_order()) { 00224 any_changed = true; 00225 } 00226 00227 if (_dependency_order <= group->get_dependency_order()) { 00228 _dependency_order = group->get_dependency_order() + 1; 00229 any_changed = true; 00230 } 00231 00232 if (_dirname == group->get_dirname()) { 00233 // The dirname orders should be equal. 00234 if (_dirname_order < group->get_dirname_order()) { 00235 _dirname_order = group->get_dirname_order(); 00236 any_changed = true; 00237 } 00238 } else { 00239 // The dirname orders should be different. 00240 if (_dirname_order <= group->get_dirname_order()) { 00241 _dirname_order = group->get_dirname_order() + 1; 00242 any_changed = true; 00243 } 00244 } 00245 } 00246 00247 return any_changed; 00248 } 00249 00250 //////////////////////////////////////////////////////////////////// 00251 // Function: PaletteGroup::get_dependency_level 00252 // Access: Public 00253 // Description: Returns the dependency level of this group. This is 00254 // a measure of how specific the group is; the lower the 00255 // dependency level, the more specific the group. 00256 // 00257 // Groups depend on other groups in a hierarchical 00258 // relationship. In general, if group a depends on 00259 // group b, then b->get_dependency_level() > 00260 // a->get_dependency_level(). 00261 // 00262 // Thus, groups that lots of other groups depend on have 00263 // a higher dependency level; groups that no one else 00264 // depends on have a low dependency level. This is 00265 // important when deciding which groups are best suited 00266 // for assigning a texture to; in general, the texture 00267 // should be assigned to the most specific suitable 00268 // group (i.e. the one with the lowest dependency 00269 // level). 00270 //////////////////////////////////////////////////////////////////// 00271 int PaletteGroup:: 00272 get_dependency_level() const { 00273 return _dependency_level; 00274 } 00275 00276 //////////////////////////////////////////////////////////////////// 00277 // Function: PaletteGroup::get_dependency_order 00278 // Access: Public 00279 // Description: Returns the dependency order of this group. This is 00280 // similar in principle to the dependency level, but it 00281 // represents the inverse concept: if group a depends on 00282 // group b, then a->get_dependency_order() > 00283 // b->get_dependency_order(). 00284 // 00285 // This is not exactly the same thing as n - 00286 // get_dependency_level(). In particular, this can be 00287 // used to sort the groups into an ordering such that 00288 // all the groups that group a depends on appear before 00289 // group a in the list. 00290 //////////////////////////////////////////////////////////////////// 00291 int PaletteGroup:: 00292 get_dependency_order() const { 00293 return _dependency_order; 00294 } 00295 00296 //////////////////////////////////////////////////////////////////// 00297 // Function: PaletteGroup::get_dirname_order 00298 // Access: Public 00299 // Description: Returns the dependency order of this group. This is 00300 // similar in principle to the dependency level, but it 00301 // represents the inverse concept: if group a depends on 00302 // group b, then a->get_dirname_order() > 00303 // b->get_dirname_order(). 00304 // 00305 // This is not exactly the same thing as n - 00306 // get_dependency_level(). In particular, this can be 00307 // used to sort the groups into an ordering such that 00308 // all the groups that group a depends on appear before 00309 // group a in the list. 00310 //////////////////////////////////////////////////////////////////// 00311 int PaletteGroup:: 00312 get_dirname_order() const { 00313 return _dirname_order; 00314 } 00315 00316 //////////////////////////////////////////////////////////////////// 00317 // Function: PaletteGroup::is_preferred_over 00318 // Access: Public 00319 // Description: Returns true if this group should be preferred for 00320 // adding textures over the other group, if both are 00321 // available. In other words, this is a more specific 00322 // group than the other one. 00323 //////////////////////////////////////////////////////////////////// 00324 bool PaletteGroup:: 00325 is_preferred_over(const PaletteGroup &other) const { 00326 if (get_dirname_order() != other.get_dirname_order()) { 00327 return (get_dirname_order() > other.get_dirname_order()); 00328 00329 } else if (get_dependency_order() != other.get_dependency_order()) { 00330 return (get_dependency_order() > other.get_dependency_order()); 00331 00332 } else { 00333 return (get_egg_count() < other.get_egg_count()); 00334 } 00335 } 00336 00337 //////////////////////////////////////////////////////////////////// 00338 // Function: PaletteGroup::increment_egg_count 00339 // Access: Public 00340 // Description: Increments by one the number of egg files that are 00341 // known to reference this PaletteGroup. This is 00342 // designed to aid the heuristics in texture placing; 00343 // it's useful to know how many different egg files are 00344 // sharing a particular PaletteGroup. 00345 //////////////////////////////////////////////////////////////////// 00346 void PaletteGroup:: 00347 increment_egg_count() { 00348 _egg_count++; 00349 } 00350 00351 //////////////////////////////////////////////////////////////////// 00352 // Function: PaletteGroup::get_egg_count 00353 // Access: Public 00354 // Description: Returns the number of egg files that share this 00355 // PaletteGroup. 00356 //////////////////////////////////////////////////////////////////// 00357 int PaletteGroup:: 00358 get_egg_count() const { 00359 return _egg_count; 00360 } 00361 00362 //////////////////////////////////////////////////////////////////// 00363 // Function: PaletteGroup::get_page 00364 // Access: Public 00365 // Description: Returns the page associated with the indicated 00366 // properties. If no page object has yet been created, 00367 // creates one. 00368 //////////////////////////////////////////////////////////////////// 00369 PalettePage *PaletteGroup:: 00370 get_page(const TextureProperties &properties) { 00371 Pages::iterator pi = _pages.find(properties); 00372 if (pi != _pages.end()) { 00373 return (*pi).second; 00374 } 00375 00376 PalettePage *page = new PalettePage(this, properties); 00377 bool inserted = _pages.insert(Pages::value_type(properties, page)).second; 00378 nassertr(inserted, page); 00379 return page; 00380 } 00381 00382 //////////////////////////////////////////////////////////////////// 00383 // Function: PaletteGroup::prepare 00384 // Access: Public 00385 // Description: Marks the indicated Texture as ready for placing 00386 // somewhere within this group, and returns a 00387 // placeholder TexturePlacement object. The texture is 00388 // not placed immediately, but may be placed later when 00389 // place_all() is called; at this time, the 00390 // TexturePlacement fields will be filled in as 00391 // appropriate. 00392 //////////////////////////////////////////////////////////////////// 00393 TexturePlacement *PaletteGroup:: 00394 prepare(TextureImage *texture) { 00395 TexturePlacement *placement = new TexturePlacement(texture, this); 00396 _placements.insert(placement); 00397 00398 return placement; 00399 } 00400 00401 //////////////////////////////////////////////////////////////////// 00402 // Function: PaletteGroup::unplace 00403 // Access: Public 00404 // Description: Removes the texture from its position on a 00405 // PaletteImage, if it has been so placed. 00406 //////////////////////////////////////////////////////////////////// 00407 void PaletteGroup:: 00408 unplace(TexturePlacement *placement) { 00409 nassertv(placement->get_group() == this); 00410 00411 Placements::iterator pi; 00412 pi = _placements.find(placement); 00413 if (pi != _placements.end()) { 00414 _placements.erase(pi); 00415 00416 if (placement->is_placed()) { 00417 placement->get_page()->unplace(placement); 00418 } 00419 } 00420 } 00421 00422 //////////////////////////////////////////////////////////////////// 00423 // Function: PaletteGroup::place_all 00424 // Access: Public 00425 // Description: Once all the textures have been assigned to this 00426 // group, try to place them all onto suitable 00427 // PaletteImages. 00428 //////////////////////////////////////////////////////////////////// 00429 void PaletteGroup:: 00430 place_all() { 00431 // First, go through our prepared textures and assign each unplaced 00432 // one to an appropriate page. 00433 Placements::iterator pli; 00434 for (pli = _placements.begin(); pli != _placements.end(); ++pli) { 00435 TexturePlacement *placement = (*pli); 00436 00437 if (placement->get_omit_reason() == OR_working) { 00438 PalettePage *page = get_page(placement->get_properties()); 00439 page->assign(placement); 00440 } 00441 } 00442 00443 // Then, go through the pages and actually do the placing. 00444 Pages::iterator pai; 00445 for (pai = _pages.begin(); pai != _pages.end(); ++pai) { 00446 PalettePage *page = (*pai).second; 00447 page->place_all(); 00448 } 00449 } 00450 00451 //////////////////////////////////////////////////////////////////// 00452 // Function: PaletteGroup::update_unknown_textures 00453 // Access: Public 00454 // Description: Checks for new information on any textures within the 00455 // group for which some of the saved information is 00456 // incomplete. This may be necessary before we can 00457 // properly place all of the textures. 00458 //////////////////////////////////////////////////////////////////// 00459 void PaletteGroup:: 00460 update_unknown_textures(const TxaFile &txa_file) { 00461 Placements::iterator pli; 00462 for (pli = _placements.begin(); pli != _placements.end(); ++pli) { 00463 TexturePlacement *placement = (*pli); 00464 00465 if (!placement->is_size_known()) { 00466 // This texture's size isn't known; we have to determine its 00467 // size. 00468 TextureImage *texture = placement->get_texture(); 00469 if (!texture->got_txa_file()) { 00470 // But first, we need to look up the texture in the .txa file. 00471 texture->pre_txa_file(); 00472 txa_file.match_texture(texture); 00473 texture->post_txa_file(); 00474 } 00475 00476 placement->determine_size(); 00477 } 00478 } 00479 } 00480 00481 //////////////////////////////////////////////////////////////////// 00482 // Function: PaletteGroup::write_image_info 00483 // Access: Public 00484 // Description: Writes a list of the PaletteImages associated with 00485 // this group, and all of their textures, to the 00486 // indicated output stream. 00487 //////////////////////////////////////////////////////////////////// 00488 void PaletteGroup:: 00489 write_image_info(ostream &out, int indent_level) const { 00490 Pages::const_iterator pai; 00491 for (pai = _pages.begin(); pai != _pages.end(); ++pai) { 00492 PalettePage *page = (*pai).second; 00493 page->write_image_info(out, indent_level); 00494 } 00495 00496 // Write out all the unplaced textures, in alphabetical order by name. 00497 pvector<TexturePlacement *> placement_vector; 00498 placement_vector.reserve(_placements.size()); 00499 Placements::const_iterator pli; 00500 for (pli = _placements.begin(); pli != _placements.end(); ++pli) { 00501 TexturePlacement *placement = (*pli); 00502 if (placement->get_omit_reason() != OR_none) { 00503 placement_vector.push_back(placement); 00504 } 00505 } 00506 sort(placement_vector.begin(), placement_vector.end(), 00507 IndirectCompareNames<TexturePlacement>()); 00508 00509 pvector<TexturePlacement *>::const_iterator pvi; 00510 for (pvi = placement_vector.begin(); 00511 pvi != placement_vector.end(); 00512 ++pvi) { 00513 TexturePlacement *placement = (*pvi); 00514 00515 indent(out, indent_level) 00516 << placement->get_texture()->get_name() 00517 << " unplaced because "; 00518 switch (placement->get_omit_reason()) { 00519 case OR_coverage: 00520 out << "coverage (" << placement->get_uv_area() << ")"; 00521 break; 00522 00523 case OR_size: 00524 out << "size (" << placement->get_x_size() << " " 00525 << placement->get_y_size() << ")"; 00526 break; 00527 00528 default: 00529 out << placement->get_omit_reason(); 00530 } 00531 out << "\n"; 00532 } 00533 } 00534 00535 //////////////////////////////////////////////////////////////////// 00536 // Function: PaletteGroup::optimal_resize 00537 // Access: Public 00538 // Description: Attempts to resize each PalettteImage down to its 00539 // smallest possible size. 00540 //////////////////////////////////////////////////////////////////// 00541 void PaletteGroup:: 00542 optimal_resize() { 00543 Pages::iterator pai; 00544 for (pai = _pages.begin(); pai != _pages.end(); ++pai) { 00545 PalettePage *page = (*pai).second; 00546 page->optimal_resize(); 00547 } 00548 } 00549 00550 //////////////////////////////////////////////////////////////////// 00551 // Function: PaletteGroup::reset_images 00552 // Access: Public 00553 // Description: Throws away all of the current PaletteImages, so that 00554 // new ones may be created (and the packing made more 00555 // optimal). 00556 //////////////////////////////////////////////////////////////////// 00557 void PaletteGroup:: 00558 reset_images() { 00559 Pages::iterator pai; 00560 for (pai = _pages.begin(); pai != _pages.end(); ++pai) { 00561 PalettePage *page = (*pai).second; 00562 page->reset_images(); 00563 } 00564 } 00565 00566 //////////////////////////////////////////////////////////////////// 00567 // Function: PaletteGroup::setup_shadow_images 00568 // Access: Public 00569 // Description: Ensures that each PaletteImage's _shadow_image has 00570 // the correct filename and image types, based on what 00571 // was supplied on the command line and in the .txa 00572 // file. 00573 //////////////////////////////////////////////////////////////////// 00574 void PaletteGroup:: 00575 setup_shadow_images() { 00576 Pages::iterator pai; 00577 for (pai = _pages.begin(); pai != _pages.end(); ++pai) { 00578 PalettePage *page = (*pai).second; 00579 page->setup_shadow_images(); 00580 } 00581 } 00582 00583 //////////////////////////////////////////////////////////////////// 00584 // Function: PaletteGroup::update_images 00585 // Access: Public 00586 // Description: Regenerates each PaletteImage on this group that needs 00587 // it. 00588 //////////////////////////////////////////////////////////////////// 00589 void PaletteGroup:: 00590 update_images(bool redo_all) { 00591 Pages::iterator pai; 00592 for (pai = _pages.begin(); pai != _pages.end(); ++pai) { 00593 PalettePage *page = (*pai).second; 00594 page->update_images(redo_all); 00595 } 00596 } 00597 00598 //////////////////////////////////////////////////////////////////// 00599 // Function: PaletteGroup::register_with_read_factory 00600 // Access: Public, Static 00601 // Description: Registers the current object as something that can be 00602 // read from a Bam file. 00603 //////////////////////////////////////////////////////////////////// 00604 void PaletteGroup:: 00605 register_with_read_factory() { 00606 BamReader::get_factory()-> 00607 register_factory(get_class_type(), make_PaletteGroup); 00608 } 00609 00610 //////////////////////////////////////////////////////////////////// 00611 // Function: PaletteGroup::write_datagram 00612 // Access: Public, Virtual 00613 // Description: Fills the indicated datagram up with a binary 00614 // representation of the current object, in preparation 00615 // for writing to a Bam file. 00616 //////////////////////////////////////////////////////////////////// 00617 void PaletteGroup:: 00618 write_datagram(BamWriter *writer, Datagram &datagram) { 00619 TypedWritable::write_datagram(writer, datagram); 00620 datagram.add_string(get_name()); 00621 datagram.add_string(_dirname); 00622 _dependent.write_datagram(writer, datagram); 00623 00624 datagram.add_int32(_dependency_level); 00625 datagram.add_int32(_dependency_order); 00626 datagram.add_int32(_dirname_order); 00627 00628 datagram.add_uint32(_placements.size()); 00629 Placements::const_iterator pli; 00630 for (pli = _placements.begin(); pli != _placements.end(); ++pli) { 00631 writer->write_pointer(datagram, (*pli)); 00632 } 00633 00634 datagram.add_uint32(_pages.size()); 00635 Pages::const_iterator pai; 00636 for (pai = _pages.begin(); pai != _pages.end(); ++pai) { 00637 writer->write_pointer(datagram, (*pai).second); 00638 } 00639 } 00640 00641 //////////////////////////////////////////////////////////////////// 00642 // Function: PaletteGroup::complete_pointers 00643 // Access: Public, Virtual 00644 // Description: Called after the object is otherwise completely read 00645 // from a Bam file, this function's job is to store the 00646 // pointers that were retrieved from the Bam file for 00647 // each pointer object written. The return value is the 00648 // number of pointers processed from the list. 00649 //////////////////////////////////////////////////////////////////// 00650 int PaletteGroup:: 00651 complete_pointers(TypedWritable **p_list, BamReader *manager) { 00652 int pi = TypedWritable::complete_pointers(p_list, manager); 00653 00654 pi += _dependent.complete_pointers(p_list + pi, manager); 00655 00656 int i; 00657 for (i = 0; i < _num_placements; i++) { 00658 TexturePlacement *placement; 00659 DCAST_INTO_R(placement, p_list[pi++], pi); 00660 bool inserted = _placements.insert(placement).second; 00661 nassertr(inserted, pi); 00662 } 00663 00664 // We must store the list of pages in a temporary vector first. We 00665 // can't put them directly into the map because the map requires 00666 // that all the pointers in the page's get_properties() member have 00667 // been filled in, which may not have happened yet. 00668 _load_pages.reserve(_num_pages); 00669 for (i = 0; i < _num_pages; i++) { 00670 PalettePage *page; 00671 DCAST_INTO_R(page, p_list[pi++], pi); 00672 _load_pages.push_back(page); 00673 } 00674 00675 return pi; 00676 } 00677 00678 //////////////////////////////////////////////////////////////////// 00679 // Function: PaletteGroup::finalize 00680 // Access: Public, Virtual 00681 // Description: This method is called by the BamReader after all 00682 // pointers everywhere in the world have been completely 00683 // read in. It's a hook at which the object can do 00684 // whatever final setup it requires that depends on 00685 // other pointers being valid. 00686 //////////////////////////////////////////////////////////////////// 00687 void PaletteGroup:: 00688 finalize() { 00689 // Now we can copy the pages into the actual map. 00690 pvector<PalettePage *>::const_iterator pi; 00691 for (pi = _load_pages.begin(); pi != _load_pages.end(); ++pi) { 00692 PalettePage *page = (*pi); 00693 bool inserted = _pages. 00694 insert(Pages::value_type(page->get_properties(), page)).second; 00695 nassertv(inserted); 00696 } 00697 00698 _load_pages.clear(); 00699 } 00700 00701 //////////////////////////////////////////////////////////////////// 00702 // Function: PaletteGroup::make_PaletteGroup 00703 // Access: Protected, Static 00704 // Description: This method is called by the BamReader when an object 00705 // of this type is encountered in a Bam file; it should 00706 // allocate and return a new object with all the data 00707 // read. 00708 //////////////////////////////////////////////////////////////////// 00709 TypedWritable *PaletteGroup:: 00710 make_PaletteGroup(const FactoryParams ¶ms) { 00711 PaletteGroup *me = new PaletteGroup; 00712 DatagramIterator scan; 00713 BamReader *manager; 00714 00715 parse_params(params, scan, manager); 00716 me->fillin(scan, manager); 00717 manager->register_finalize(me); 00718 return me; 00719 } 00720 00721 //////////////////////////////////////////////////////////////////// 00722 // Function: PaletteGroup::fillin 00723 // Access: Protected 00724 // Description: Reads the binary data from the given datagram 00725 // iterator, which was written by a previous call to 00726 // write_datagram(). 00727 //////////////////////////////////////////////////////////////////// 00728 void PaletteGroup:: 00729 fillin(DatagramIterator &scan, BamReader *manager) { 00730 TypedWritable::fillin(scan, manager); 00731 set_name(scan.get_string()); 00732 _dirname = scan.get_string(); 00733 _dependent.fillin(scan, manager); 00734 00735 _dependency_level = scan.get_int32(); 00736 _dependency_order = scan.get_int32(); 00737 _dirname_order = scan.get_int32(); 00738 00739 _num_placements = scan.get_uint32(); 00740 manager->read_pointers(scan, _num_placements); 00741 00742 _num_pages = scan.get_uint32(); 00743 manager->read_pointers(scan, _num_pages); 00744 }