00001 // Filename: eggFile.cxx 00002 // Created by: drose (29Nov00) 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 "eggFile.h" 00020 #include "textureImage.h" 00021 #include "paletteGroup.h" 00022 #include "texturePlacement.h" 00023 #include "textureReference.h" 00024 #include "sourceTextureImage.h" 00025 #include "palettizer.h" 00026 #include "filenameUnifier.h" 00027 00028 #include "eggData.h" 00029 #include "eggGroup.h" 00030 #include "eggTextureCollection.h" 00031 #include "eggComment.h" 00032 #include "datagram.h" 00033 #include "datagramIterator.h" 00034 #include "bamReader.h" 00035 #include "bamWriter.h" 00036 #include "executionEnvironment.h" 00037 #include "dSearchPath.h" 00038 00039 TypeHandle EggFile::_type_handle; 00040 00041 //////////////////////////////////////////////////////////////////// 00042 // Function: EggFile::Constructor 00043 // Access: Public 00044 // Description: 00045 //////////////////////////////////////////////////////////////////// 00046 EggFile:: 00047 EggFile() { 00048 _data = (EggData *)NULL; 00049 _default_group = (PaletteGroup *)NULL; 00050 _is_surprise = true; 00051 _is_stale = true; 00052 _first_txa_match = false; 00053 } 00054 00055 //////////////////////////////////////////////////////////////////// 00056 // Function: EggFile::from_command_line 00057 // Access: Public 00058 // Description: Accepts the information about the egg file as 00059 // supplied from the command line. 00060 //////////////////////////////////////////////////////////////////// 00061 void EggFile:: 00062 from_command_line(EggData *data, 00063 const Filename &source_filename, 00064 const Filename &dest_filename, 00065 const string &egg_comment) { 00066 _data = data; 00067 remove_backstage(_data); 00068 00069 // We save the current directory at the time the egg file appeared 00070 // on the command line, so that we'll later be able to properly 00071 // resolve external references (like textures) that might be 00072 // relative to this directory. 00073 _current_directory = ExecutionEnvironment::get_cwd(); 00074 _source_filename = source_filename; 00075 _source_filename.make_absolute(); 00076 _dest_filename = dest_filename; 00077 _dest_filename.make_absolute(); 00078 00079 // We also save the command line that loaded this egg file, so we 00080 // can continue to write it as a comment to the beginning of the egg 00081 // file, should we need to rewrite it later. 00082 _egg_comment = egg_comment; 00083 00084 // We save the default PaletteGroup at this point, because the egg 00085 // file inherits the default group that was in effect when it was 00086 // specified on the command line. 00087 _default_group = pal->get_default_group(); 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: EggFile::scan_textures 00092 // Access: Public 00093 // Description: Scans the egg file for texture references and updates 00094 // the _textures list appropriately. This assumes the 00095 // egg file was supplied on the command line and thus 00096 // the _data member is available. 00097 //////////////////////////////////////////////////////////////////// 00098 void EggFile:: 00099 scan_textures() { 00100 nassertv(_data != (EggData *)NULL); 00101 00102 EggTextureCollection tc; 00103 tc.find_used_textures(_data); 00104 00105 // Remove the old TextureReference objects. 00106 Textures::iterator ti; 00107 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00108 delete (*ti); 00109 } 00110 _textures.clear(); 00111 00112 EggTextureCollection::iterator eti; 00113 for (eti = tc.begin(); eti != tc.end(); ++eti) { 00114 EggTexture *egg_tex = (*eti); 00115 00116 TextureReference *ref = new TextureReference; 00117 ref->from_egg(this, _data, egg_tex); 00118 00119 if (!ref->has_uvs()) { 00120 // This texture isn't *really* referenced. (Usually this 00121 // happens if the texture is only referenced by "backstage" 00122 // geometry, which we don't care about.) 00123 delete ref; 00124 00125 } else { 00126 _textures.push_back(ref); 00127 } 00128 } 00129 } 00130 00131 //////////////////////////////////////////////////////////////////// 00132 // Function: EggFile::get_textures 00133 // Access: Public 00134 // Description: Fills up the indicated set with the set of textures 00135 // referenced by this egg file. It is the user's 00136 // responsibility to ensure the set is empty before 00137 // making this call; otherwise, the new textures will be 00138 // appended to the existing set. 00139 //////////////////////////////////////////////////////////////////// 00140 void EggFile:: 00141 get_textures(pset<TextureImage *> &result) const { 00142 Textures::const_iterator ti; 00143 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00144 result.insert((*ti)->get_texture()); 00145 } 00146 } 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: EggFile::pre_txa_file 00150 // Access: Public 00151 // Description: Does some processing prior to scanning the .txa file. 00152 //////////////////////////////////////////////////////////////////// 00153 void EggFile:: 00154 pre_txa_file() { 00155 _is_surprise = true; 00156 _first_txa_match = true; 00157 } 00158 00159 //////////////////////////////////////////////////////////////////// 00160 // Function: EggFile::match_txa_groups 00161 // Access: Public 00162 // Description: Adds the indicated set of groups, read from the .txa 00163 // file, to the set of groups to which the egg file is 00164 // assigned. 00165 //////////////////////////////////////////////////////////////////// 00166 void EggFile:: 00167 match_txa_groups(const PaletteGroups &groups) { 00168 if (_first_txa_match) { 00169 // If this is the first line we matched in the .txa file, clear 00170 // the set of groups we'd matched from before. We don't clear 00171 // until we match a line in the .txa file, because if we don't 00172 // match any lines we still want to remember what groups we used 00173 // to be assigned to. 00174 _explicitly_assigned_groups.clear(); 00175 _first_txa_match = false; 00176 } 00177 00178 _explicitly_assigned_groups.make_union(_explicitly_assigned_groups, groups); 00179 } 00180 00181 //////////////////////////////////////////////////////////////////// 00182 // Function: EggFile::post_txa_file 00183 // Access: Public 00184 // Description: Once the egg file has been matched against all of the 00185 // matching lines the .txa file, do whatever adjustment 00186 // is necessary. 00187 //////////////////////////////////////////////////////////////////// 00188 void EggFile:: 00189 post_txa_file() { 00190 } 00191 00192 //////////////////////////////////////////////////////////////////// 00193 // Function: EggFile::get_explicit_groups 00194 // Access: Public 00195 // Description: Returns the set of PaletteGroups that the egg file 00196 // has been explicitly assigned to in the .txa file. 00197 //////////////////////////////////////////////////////////////////// 00198 const PaletteGroups &EggFile:: 00199 get_explicit_groups() const { 00200 return _explicitly_assigned_groups; 00201 } 00202 00203 //////////////////////////////////////////////////////////////////// 00204 // Function: EggFile::get_default_group 00205 // Access: Public 00206 // Description: Returns the PaletteGroup that was specified as the 00207 // default group on the command line at the time the egg 00208 // file last appeared on the command line. 00209 //////////////////////////////////////////////////////////////////// 00210 PaletteGroup *EggFile:: 00211 get_default_group() const { 00212 return _default_group; 00213 } 00214 00215 //////////////////////////////////////////////////////////////////// 00216 // Function: EggFile::get_complete_groups 00217 // Access: Public 00218 // Description: Returns the complete set of PaletteGroups that the 00219 // egg file is assigned to. This is the set of all the 00220 // groups it is explicitly assigned to, plus all the 00221 // groups that these groups depend on. 00222 //////////////////////////////////////////////////////////////////// 00223 const PaletteGroups &EggFile:: 00224 get_complete_groups() const { 00225 return _complete_groups; 00226 } 00227 00228 //////////////////////////////////////////////////////////////////// 00229 // Function: EggFile::clear_surprise 00230 // Access: Public 00231 // Description: Removes the 'surprise' flag; this file has been 00232 // successfully matched against a line in the .txa file. 00233 //////////////////////////////////////////////////////////////////// 00234 void EggFile:: 00235 clear_surprise() { 00236 _is_surprise = false; 00237 } 00238 00239 //////////////////////////////////////////////////////////////////// 00240 // Function: EggFile::is_surprise 00241 // Access: Public 00242 // Description: Returns true if this particular egg file is a 00243 // 'surprise', i.e. it wasn't matched by a line in the 00244 // .txa file that didn't include the keyword 'cont'. 00245 //////////////////////////////////////////////////////////////////// 00246 bool EggFile:: 00247 is_surprise() const { 00248 return _is_surprise; 00249 } 00250 00251 //////////////////////////////////////////////////////////////////// 00252 // Function: EggFile::mark_stale 00253 // Access: Public 00254 // Description: Marks this particular egg file as stale, meaning that 00255 // something has changed, such as the location of a 00256 // texture within its palette, which causes the egg file 00257 // to need to be regenerated. 00258 //////////////////////////////////////////////////////////////////// 00259 void EggFile:: 00260 mark_stale() { 00261 _is_stale = true; 00262 } 00263 00264 //////////////////////////////////////////////////////////////////// 00265 // Function: EggFile::is_stale 00266 // Access: Public 00267 // Description: Returns true if the egg file needs to be updated, 00268 // i.e. some palettizations have changed affecting it, 00269 // or false otherwise. 00270 //////////////////////////////////////////////////////////////////// 00271 bool EggFile:: 00272 is_stale() const { 00273 return _is_stale; 00274 } 00275 00276 //////////////////////////////////////////////////////////////////// 00277 // Function: EggFile::build_cross_links 00278 // Access: Public 00279 // Description: Calls TextureImage::note_egg_file() and 00280 // SourceTextureImage::increment_egg_count() for each 00281 // texture the egg file references, and 00282 // PaletteGroup::increment_egg_count() for each palette 00283 // group it wants. This sets up some of the back 00284 // references to support determining an ideal texture 00285 // assignment. 00286 //////////////////////////////////////////////////////////////////// 00287 void EggFile:: 00288 build_cross_links() { 00289 if (_explicitly_assigned_groups.empty()) { 00290 // If the egg file has been assigned to no groups, we have to 00291 // assign it to something. 00292 _complete_groups.clear(); 00293 _complete_groups.insert(_default_group); 00294 _complete_groups.make_complete(_complete_groups); 00295 00296 } else { 00297 _complete_groups.make_complete(_explicitly_assigned_groups); 00298 } 00299 00300 Textures::const_iterator ti; 00301 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00302 TextureReference *reference = (*ti); 00303 TextureImage *texture = reference->get_texture(); 00304 nassertv(texture != (TextureImage *)NULL); 00305 texture->note_egg_file(this); 00306 00307 // Actually, this may count the same egg file multiple times for a 00308 // particular SourceTextureImage, since a given texture may be 00309 // reference multiples times within an egg file. No harm done, 00310 // however. 00311 reference->get_source()->increment_egg_count(); 00312 } 00313 00314 PaletteGroups::const_iterator gi; 00315 for (gi = _complete_groups.begin(); 00316 gi != _complete_groups.end(); 00317 ++gi) { 00318 (*gi)->increment_egg_count(); 00319 } 00320 } 00321 00322 //////////////////////////////////////////////////////////////////// 00323 // Function: EggFile::apply_properties_to_source 00324 // Access: Public 00325 // Description: Calls apply_properties_to_source() for each texture 00326 // reference, updating all the referenced source 00327 // textures with the complete set of property 00328 // information from this egg file. 00329 //////////////////////////////////////////////////////////////////// 00330 void EggFile:: 00331 apply_properties_to_source() { 00332 Textures::const_iterator ti; 00333 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00334 TextureReference *reference = (*ti); 00335 reference->apply_properties_to_source(); 00336 } 00337 } 00338 00339 //////////////////////////////////////////////////////////////////// 00340 // Function: EggFile::choose_placements 00341 // Access: Public 00342 // Description: Once all the textures have been assigned to groups 00343 // (but before they may actually be placed), chooses a 00344 // suitable TexturePlacement for each texture that 00345 // appears in the egg file. This will be necessary to 00346 // do at some point before writing out the egg file 00347 // anyway, and doing it before the textures are placed 00348 // allows us to decide what the necessary UV range is 00349 // for each to-be-placed texture. 00350 //////////////////////////////////////////////////////////////////// 00351 void EggFile:: 00352 choose_placements() { 00353 Textures::const_iterator ti; 00354 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00355 TextureReference *reference = (*ti); 00356 TextureImage *texture = reference->get_texture(); 00357 00358 if (reference->get_placement() != (TexturePlacement *)NULL && 00359 texture->get_groups().count(reference->get_placement()->get_group()) != 0) { 00360 // The egg file is already using a TexturePlacement that is 00361 // suitable. Don't bother changing it. 00362 00363 } else { 00364 // We need to select a new TexturePlacement. 00365 PaletteGroups groups; 00366 groups.make_intersection(get_complete_groups(), texture->get_groups()); 00367 00368 // Now groups is the set of groups that the egg file requires, 00369 // which also happen to include the texture. It better not be 00370 // empty. 00371 if (groups.empty()) { 00372 nout << "Warning! Egg file " << get_name() << " and texture " 00373 << *reference << " do not have any groups in common.\n" 00374 << "Egg groups:\n"; 00375 get_complete_groups().write(nout, 2); 00376 nout << "Texture groups:\n"; 00377 texture->get_groups().write(nout, 2); 00378 00379 } else { 00380 // It doesn't really matter which group in the set we choose, so 00381 // we arbitrarily choose the first one. 00382 PaletteGroup *group = (*groups.begin()); 00383 00384 // Now get the TexturePlacement object that corresponds to the 00385 // placement of this texture into this group. 00386 TexturePlacement *placement = texture->get_placement(group); 00387 nassertv(placement != (TexturePlacement *)NULL); 00388 00389 reference->set_placement(placement); 00390 } 00391 } 00392 } 00393 } 00394 00395 //////////////////////////////////////////////////////////////////// 00396 // Function: EggFile::has_data 00397 // Access: Public 00398 // Description: Returns true if the EggData for this EggFile has ever 00399 // been loaded. 00400 //////////////////////////////////////////////////////////////////// 00401 bool EggFile:: 00402 has_data() const { 00403 return (_data != (EggData *)NULL); 00404 } 00405 00406 //////////////////////////////////////////////////////////////////// 00407 // Function: EggFile::update_egg 00408 // Access: Public 00409 // Description: Once all textures have been placed appropriately, 00410 // updates the egg file with all the information to 00411 // reference the new textures. 00412 //////////////////////////////////////////////////////////////////// 00413 void EggFile:: 00414 update_egg() { 00415 Textures::iterator ti; 00416 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00417 TextureReference *reference = (*ti); 00418 reference->update_egg(); 00419 } 00420 } 00421 00422 //////////////////////////////////////////////////////////////////// 00423 // Function: EggFile::remove_egg 00424 // Access: Public 00425 // Description: Removes this egg file from all things that reference 00426 // it, in preparation for removing it from the database. 00427 //////////////////////////////////////////////////////////////////// 00428 void EggFile:: 00429 remove_egg() { 00430 Textures::iterator ti; 00431 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00432 TextureReference *reference = (*ti); 00433 TexturePlacement *placement = reference->get_placement(); 00434 placement->remove_egg(reference); 00435 } 00436 } 00437 00438 //////////////////////////////////////////////////////////////////// 00439 // Function: EggFile::read_egg 00440 // Access: Public 00441 // Description: Reads in the egg file from its _source_filename. It 00442 // is only valid to call this if it has not already been 00443 // read in, e.g. from the command line. Returns true if 00444 // successful, false if there is an error. 00445 //////////////////////////////////////////////////////////////////// 00446 bool EggFile:: 00447 read_egg() { 00448 nassertr(_data == (EggData *)NULL, false); 00449 nassertr(!_source_filename.empty(), false); 00450 00451 if (!_source_filename.exists()) { 00452 nout << _source_filename << " does not exist.\n"; 00453 return false; 00454 } 00455 00456 EggData *data = new EggData; 00457 if (!data->read(_source_filename)) { 00458 // Failure reading. 00459 delete data; 00460 return false; 00461 } 00462 00463 // We also want to search for filenames based on our current 00464 // directory from which we originally loaded the egg file. This is 00465 // important because it's possible the egg file referenced some 00466 // textures or something relative to that directory. 00467 DSearchPath dir; 00468 dir.append_directory(_current_directory); 00469 data->resolve_filenames(dir); 00470 00471 if (!data->load_externals()) { 00472 // Failure reading an external. 00473 delete data; 00474 return false; 00475 } 00476 00477 _data = data; 00478 remove_backstage(_data); 00479 00480 // Replace the comment that shows how we first generated the egg 00481 // file. 00482 _data->insert(_data->begin(), new EggComment("", _egg_comment)); 00483 00484 return true; 00485 } 00486 00487 //////////////////////////////////////////////////////////////////// 00488 // Function: EggFile::write_egg 00489 // Access: Public 00490 // Description: Writes out the egg file to its _dest_filename. 00491 // Returns true if successful, false if there is an 00492 // error. 00493 //////////////////////////////////////////////////////////////////// 00494 bool EggFile:: 00495 write_egg() { 00496 nassertr(_data != (EggData *)NULL, false); 00497 nassertr(!_dest_filename.empty(), false); 00498 00499 _dest_filename.make_dir(); 00500 nout << "Writing " << FilenameUnifier::make_user_filename(_dest_filename) 00501 << "\n"; 00502 if (!_data->write_egg(_dest_filename)) { 00503 // Some error while writing. Most unusual. 00504 _is_stale = true; 00505 return false; 00506 } 00507 00508 _is_stale = false; 00509 return true; 00510 } 00511 00512 //////////////////////////////////////////////////////////////////// 00513 // Function: EggFile::write_description 00514 // Access: Public 00515 // Description: Writes a one-line description of the egg file and its 00516 // group assignments to the indicated output stream. 00517 //////////////////////////////////////////////////////////////////// 00518 void EggFile:: 00519 write_description(ostream &out, int indent_level) const { 00520 indent(out, indent_level) << get_name() << ": "; 00521 if (_explicitly_assigned_groups.empty()) { 00522 if (_default_group != (PaletteGroup *)NULL) { 00523 out << _default_group->get_name(); 00524 } 00525 } else { 00526 out << _explicitly_assigned_groups; 00527 } 00528 00529 if (is_stale()) { 00530 out << " (needs update)"; 00531 } 00532 out << "\n"; 00533 } 00534 00535 //////////////////////////////////////////////////////////////////// 00536 // Function: EggFile::write_texture_refs 00537 // Access: Public 00538 // Description: Writes the list of texture references to the 00539 // indicated output stream, one per line. 00540 //////////////////////////////////////////////////////////////////// 00541 void EggFile:: 00542 write_texture_refs(ostream &out, int indent_level) const { 00543 Textures::const_iterator ti; 00544 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00545 TextureReference *reference = (*ti); 00546 reference->write(out, indent_level); 00547 } 00548 } 00549 00550 //////////////////////////////////////////////////////////////////// 00551 // Function: EggFile::remove_backstage 00552 // Access: Private 00553 // Description: Recursively walks the egg hierarchy and removes any 00554 // "backstage" nodes found from the scene graph 00555 // completely. These aren't part of the egg scene 00556 // anyway, and removing them early helps reduce 00557 // confusion. 00558 //////////////////////////////////////////////////////////////////// 00559 void EggFile:: 00560 remove_backstage(EggGroupNode *node) { 00561 EggGroupNode::iterator ci; 00562 ci = node->begin(); 00563 while (ci != node->end()) { 00564 EggNode *child = (*ci); 00565 bool remove_child = false; 00566 00567 if (child->is_of_type(EggGroup::get_class_type())) { 00568 EggGroup *egg_group; 00569 DCAST_INTO_V(egg_group, child); 00570 remove_child = egg_group->has_object_type("backstage"); 00571 } 00572 00573 if (remove_child) { 00574 ci = node->erase(ci); 00575 } else { 00576 if (child->is_of_type(EggGroupNode::get_class_type())) { 00577 // Recurse on children. 00578 remove_backstage(DCAST(EggGroupNode, child)); 00579 } 00580 ++ci; 00581 } 00582 } 00583 } 00584 00585 //////////////////////////////////////////////////////////////////// 00586 // Function: EggFile::register_with_read_factory 00587 // Access: Public, Static 00588 // Description: Registers the current object as something that can be 00589 // read from a Bam file. 00590 //////////////////////////////////////////////////////////////////// 00591 void EggFile:: 00592 register_with_read_factory() { 00593 BamReader::get_factory()-> 00594 register_factory(get_class_type(), make_EggFile); 00595 } 00596 00597 //////////////////////////////////////////////////////////////////// 00598 // Function: EggFile::write_datagram 00599 // Access: Public, Virtual 00600 // Description: Fills the indicated datagram up with a binary 00601 // representation of the current object, in preparation 00602 // for writing to a Bam file. 00603 //////////////////////////////////////////////////////////////////// 00604 void EggFile:: 00605 write_datagram(BamWriter *writer, Datagram &datagram) { 00606 TypedWritable::write_datagram(writer, datagram); 00607 datagram.add_string(get_name()); 00608 00609 // We don't write out _data; that needs to be reread each session. 00610 00611 datagram.add_string(FilenameUnifier::make_bam_filename(_current_directory)); 00612 datagram.add_string(FilenameUnifier::make_bam_filename(_source_filename)); 00613 datagram.add_string(FilenameUnifier::make_bam_filename(_dest_filename)); 00614 datagram.add_string(_egg_comment); 00615 00616 datagram.add_uint32(_textures.size()); 00617 Textures::iterator ti; 00618 for (ti = _textures.begin(); ti != _textures.end(); ++ti) { 00619 writer->write_pointer(datagram, (*ti)); 00620 } 00621 00622 _explicitly_assigned_groups.write_datagram(writer, datagram); 00623 writer->write_pointer(datagram, _default_group); 00624 00625 // We don't write out _complete_groups; that is recomputed each 00626 // session. 00627 00628 datagram.add_bool(_is_surprise); 00629 datagram.add_bool(_is_stale); 00630 } 00631 00632 //////////////////////////////////////////////////////////////////// 00633 // Function: EggFile::complete_pointers 00634 // Access: Public, Virtual 00635 // Description: Called after the object is otherwise completely read 00636 // from a Bam file, this function's job is to store the 00637 // pointers that were retrieved from the Bam file for 00638 // each pointer object written. The return value is the 00639 // number of pointers processed from the list. 00640 //////////////////////////////////////////////////////////////////// 00641 int EggFile:: 00642 complete_pointers(TypedWritable **p_list, BamReader *manager) { 00643 int pi = TypedWritable::complete_pointers(p_list, manager); 00644 00645 int i; 00646 _textures.reserve(_num_textures); 00647 for (i = 0; i < _num_textures; i++) { 00648 TextureReference *texture; 00649 DCAST_INTO_R(texture, p_list[pi], pi); 00650 _textures.push_back(texture); 00651 pi++; 00652 } 00653 00654 pi += _explicitly_assigned_groups.complete_pointers(p_list + pi, manager); 00655 00656 if (p_list[pi] != (TypedWritable *)NULL) { 00657 DCAST_INTO_R(_default_group, p_list[pi], pi); 00658 } 00659 pi++; 00660 00661 return pi; 00662 } 00663 00664 //////////////////////////////////////////////////////////////////// 00665 // Function: EggFile::make_EggFile 00666 // Access: Protected 00667 // Description: This method is called by the BamReader when an object 00668 // of this type is encountered in a Bam file; it should 00669 // allocate and return a new object with all the data 00670 // read. 00671 //////////////////////////////////////////////////////////////////// 00672 TypedWritable* EggFile:: 00673 make_EggFile(const FactoryParams ¶ms) { 00674 EggFile *me = new EggFile; 00675 DatagramIterator scan; 00676 BamReader *manager; 00677 00678 parse_params(params, scan, manager); 00679 me->fillin(scan, manager); 00680 return me; 00681 } 00682 00683 //////////////////////////////////////////////////////////////////// 00684 // Function: EggFile::fillin 00685 // Access: Protected 00686 // Description: Reads the binary data from the given datagram 00687 // iterator, which was written by a previous call to 00688 // write_datagram(). 00689 //////////////////////////////////////////////////////////////////// 00690 void EggFile:: 00691 fillin(DatagramIterator &scan, BamReader *manager) { 00692 TypedWritable::fillin(scan, manager); 00693 set_name(scan.get_string()); 00694 _current_directory = FilenameUnifier::get_bam_filename(scan.get_string()); 00695 _source_filename = FilenameUnifier::get_bam_filename(scan.get_string()); 00696 _dest_filename = FilenameUnifier::get_bam_filename(scan.get_string()); 00697 if (Palettizer::_read_pi_version >= 9) { 00698 _egg_comment = scan.get_string(); 00699 } 00700 00701 _num_textures = scan.get_uint32(); 00702 manager->read_pointers(scan, _num_textures); 00703 00704 _explicitly_assigned_groups.fillin(scan, manager); 00705 manager->read_pointer(scan); // _default_group 00706 00707 _is_surprise = scan.get_bool(); 00708 _is_stale = scan.get_bool(); 00709 }