Panda3D
eggFile.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file eggFile.cxx
10  * @author drose
11  * @date 2000-11-29
12  */
13 
14 #include "eggFile.h"
15 #include "textureImage.h"
16 #include "paletteGroup.h"
17 #include "texturePlacement.h"
18 #include "textureReference.h"
19 #include "sourceTextureImage.h"
20 #include "palettizer.h"
21 #include "filenameUnifier.h"
22 
23 #include "eggData.h"
24 #include "eggGroup.h"
25 #include "eggTextureCollection.h"
26 #include "eggComment.h"
27 #include "datagram.h"
28 #include "datagramIterator.h"
29 #include "bamReader.h"
30 #include "bamWriter.h"
31 #include "executionEnvironment.h"
32 #include "dSearchPath.h"
33 #include "indirectLess.h"
34 
35 #include <algorithm>
36 
37 TypeHandle EggFile::_type_handle;
38 
39 /**
40  *
41  */
42 EggFile::
43 EggFile() {
44  _data = nullptr;
45  _first_txa_match = false;
46  _default_group = nullptr;
47  _is_surprise = true;
48  _is_stale = true;
49  _had_data = false;
50 }
51 
52 /**
53  * Accepts the information about the egg file as supplied from the command
54  * line. Returns true if the egg file is valid, false otherwise.
55  */
56 bool EggFile::
58  const Filename &source_filename,
59  const Filename &dest_filename,
60  const std::string &egg_comment) {
61  _data = data;
62  _had_data = true;
63  remove_backstage(_data);
64 
65  // We save the current directory at the time the egg file appeared on the
66  // command line, so that we'll later be able to properly resolve external
67  // references (like textures) that might be relative to this directory.
68  _current_directory = ExecutionEnvironment::get_cwd();
69  _source_filename = source_filename;
70  _source_filename.make_absolute();
71  _dest_filename = dest_filename;
72  _dest_filename.make_absolute();
73 
74  // We also save the command line that loaded this egg file, so we can
75  // continue to write it as a comment to the beginning of the egg file,
76  // should we need to rewrite it later.
77  _egg_comment = egg_comment;
78 
79  // We save the default PaletteGroup at this point, because the egg file
80  // inherits the default group that was in effect when it was specified on
81  // the command line.
82  _default_group = pal->get_default_group();
83 
84  return true;
85 }
86 
87 /**
88  * Returns the filename this egg file was read from.
89  */
90 const Filename &EggFile::
92  return _source_filename;
93 }
94 
95 
96 /**
97  * Scans the egg file for texture references and updates the _textures list
98  * appropriately. This assumes the egg file was supplied on the command line
99  * and thus the _data member is available.
100  */
101 void EggFile::
103  nassertv(_data != nullptr);
104 
105  // Extract the set of textures referenced by this egg file.
107  tc.find_used_textures(_data);
108 
109  // Make sure each tref name is unique within a given file.
110  tc.uniquify_trefs();
111 
112  // Now build up a list of new TextureReference objects that represent the
113  // textures actually used and their uv range, etc.
114  Textures new_textures;
115 
116  EggTextureCollection::iterator eti;
117  for (eti = tc.begin(); eti != tc.end(); ++eti) {
118  EggTexture *egg_tex = (*eti);
119 
121  ref->from_egg(this, _data, egg_tex);
122 
123  if (!ref->has_uvs()) {
124  // This texture isn't *really* referenced. (Usually this happens if the
125  // texture is only referenced by "backstage" geometry, which we don't
126  // care about.)
127  delete ref;
128 
129  } else {
130  new_textures.push_back(ref);
131  }
132  }
133 
134  // Sort the new references into order so we can compare them with the
135  // original references.
136  sort(new_textures.begin(), new_textures.end(),
138 
139  // Sort the original references too. This should already be sorted from the
140  // previous run, but we might as well be neurotic about it.
141  sort(_textures.begin(), _textures.end(),
143 
144  // Now go through and merge the lists.
145  Textures combined_textures;
146  Textures::const_iterator ai = _textures.begin();
147  Textures::const_iterator bi = new_textures.begin();
148 
149  while (ai != _textures.end() && bi != new_textures.end()) {
150  TextureReference *aref = (*ai);
151  TextureReference *bref = (*bi);
152 
153  if ((*aref) < (*bref)) {
154  // Here's a texture reference in the original list, but not in the new
155  // list. Remove it.
156  delete aref;
157  ++ai;
158 
159  } else if ((*bref) < (*aref)) {
160  // Here's a texture reference in the new list, but not in the original
161  // list. Add it.
162  combined_textures.push_back(bref);
163  ++bi;
164 
165  } else { // (*bref) == (*aref)
166  // Here's a texture reference that was in both lists. Compare it.
167  if (aref->is_equivalent(*bref)) {
168  // It hasn't changed substantially, so keep the original (which still
169  // has the placement references from a previous pass).
170  aref->from_egg_quick(*bref);
171  combined_textures.push_back(aref);
172  delete bref;
173 
174  } else {
175  // It has changed, so drop the original and keep the new one.
176  combined_textures.push_back(bref);
177  delete aref;
178  }
179  ++ai;
180  ++bi;
181  }
182  }
183 
184  while (bi != new_textures.end()) {
185  TextureReference *bref = (*bi);
186  // Here's a texture reference in the new list, but not in the original
187  // list. Add it.
188  combined_textures.push_back(bref);
189  ++bi;
190  }
191 
192  while (ai != _textures.end()) {
193  TextureReference *aref = (*ai);
194  // Here's a texture reference in the original list, but not in the new
195  // list. Remove it.
196  delete aref;
197  ++ai;
198  }
199 
200  _textures.swap(combined_textures);
201 }
202 
203 /**
204  * Fills up the indicated set with the set of textures referenced by this egg
205  * file. It is the user's responsibility to ensure the set is empty before
206  * making this call; otherwise, the new textures will be appended to the
207  * existing set.
208  */
209 void EggFile::
211  Textures::const_iterator ti;
212  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
213  result.insert((*ti)->get_texture());
214  }
215 }
216 
217 /**
218  * Does some processing prior to scanning the .txa file.
219  */
220 void EggFile::
222  _is_surprise = true;
223  _first_txa_match = true;
224 }
225 
226 /**
227  * Adds the indicated set of groups, read from the .txa file, to the set of
228  * groups to which the egg file is assigned.
229  */
230 void EggFile::
232  if (_first_txa_match) {
233  // If this is the first line we matched in the .txa file, clear the set of
234  // groups we'd matched from before. We don't clear until we match a line
235  // in the .txa file, because if we don't match any lines we still want to
236  // remember what groups we used to be assigned to.
237  _explicitly_assigned_groups.clear();
238  _first_txa_match = false;
239  }
240 
241  _explicitly_assigned_groups.make_union(_explicitly_assigned_groups, groups);
242 }
243 
244 /**
245  * Once the egg file has been matched against all of the matching lines the
246  * .txa file, do whatever adjustment is necessary.
247  */
248 void EggFile::
250 }
251 
252 /**
253  * Returns the set of PaletteGroups that the egg file has been explicitly
254  * assigned to in the .txa file.
255  */
258  return _explicitly_assigned_groups;
259 }
260 
261 /**
262  * Returns the PaletteGroup that was specified as the default group on the
263  * command line at the time the egg file last appeared on the command line.
264  */
267  return _default_group;
268 }
269 
270 /**
271  * Returns the complete set of PaletteGroups that the egg file is assigned to.
272  * This is the set of all the groups it is explicitly assigned to, plus all
273  * the groups that these groups depend on.
274  */
277  return _complete_groups;
278 }
279 
280 /**
281  * Removes the 'surprise' flag; this file has been successfully matched
282  * against a line in the .txa file.
283  */
284 void EggFile::
286  _is_surprise = false;
287 }
288 
289 /**
290  * Returns true if this particular egg file is a 'surprise', i.e. it wasn't
291  * matched by a line in the .txa file that didn't include the keyword 'cont'.
292  */
293 bool EggFile::
294 is_surprise() const {
295  return _is_surprise;
296 }
297 
298 /**
299  * Marks this particular egg file as stale, meaning that something has
300  * changed, such as the location of a texture within its palette, which causes
301  * the egg file to need to be regenerated.
302  */
303 void EggFile::
305  _is_stale = true;
306 }
307 
308 /**
309  * Returns true if the egg file needs to be updated, i.e. some palettizations
310  * have changed affecting it, or false otherwise.
311  */
312 bool EggFile::
313 is_stale() const {
314  return _is_stale;
315 }
316 
317 /**
318  * Calls TextureImage::note_egg_file() and
319  * SourceTextureImage::increment_egg_count() for each texture the egg file
320  * references, and PaletteGroup::increment_egg_count() for each palette group
321  * it wants. This sets up some of the back references to support determining
322  * an ideal texture assignment.
323  */
324 void EggFile::
326  if (_explicitly_assigned_groups.empty()) {
327  // If the egg file has been assigned to no groups, we have to assign it to
328  // something.
329  _complete_groups.clear();
330  _complete_groups.insert(_default_group);
331  _complete_groups.make_complete(_complete_groups);
332 
333  } else {
334  _complete_groups.make_complete(_explicitly_assigned_groups);
335  }
336 
337  Textures::const_iterator ti;
338  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
339  TextureReference *reference = (*ti);
340  TextureImage *texture = reference->get_texture();
341  nassertv(texture != nullptr);
342  texture->note_egg_file(this);
343 
344  // Actually, this may count the same egg file multiple times for a
345  // particular SourceTextureImage, since a given texture may be referenced
346  // multiples times within an egg file. No harm done, however.
347  reference->get_source()->increment_egg_count();
348  }
349 
350  PaletteGroups::const_iterator gi;
351  for (gi = _complete_groups.begin();
352  gi != _complete_groups.end();
353  ++gi) {
354  (*gi)->increment_egg_count();
355  }
356 }
357 
358 /**
359  * Calls apply_properties_to_source() for each texture reference, updating all
360  * the referenced source textures with the complete set of property
361  * information from this egg file.
362  */
363 void EggFile::
365  Textures::const_iterator ti;
366  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
367  TextureReference *reference = (*ti);
368  reference->apply_properties_to_source();
369  }
370 }
371 
372 /**
373  * Once all the textures have been assigned to groups (but before they may
374  * actually be placed), chooses a suitable TexturePlacement for each texture
375  * that appears in the egg file. This will be necessary to do at some point
376  * before writing out the egg file anyway, and doing it before the textures
377  * are placed allows us to decide what the necessary UV range is for each to-
378  * be-placed texture.
379  */
380 void EggFile::
382  Textures::const_iterator ti;
383  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
384  TextureReference *reference = (*ti);
385  TextureImage *texture = reference->get_texture();
386 
387  if (reference->get_placement() != nullptr &&
388  texture->get_groups().count(reference->get_placement()->get_group()) != 0) {
389  // The egg file is already using a TexturePlacement that is suitable.
390  // Don't bother changing it.
391 
392  } else {
393  // We need to select a new TexturePlacement.
394  PaletteGroups groups;
395  groups.make_intersection(get_complete_groups(), texture->get_groups());
396 
397  // Now groups is the set of groups that the egg file requires, which
398  // also happen to include the texture.
399 
400  if (groups.empty()) {
401  // It might be empty if the egg file was assigned only to the "null"
402  // group (since this group is not propagated to the textures). In
403  // this case, choose from the wider set of groups available to the
404  // texture.
405  groups = texture->get_groups();
406  }
407 
408  if (!groups.empty()) {
409  // It doesn't really matter which group in the set we choose, so we
410  // arbitrarily choose the first one.
411  PaletteGroup *group = (*groups.begin());
412 
413  // Now get the TexturePlacement object that corresponds to the
414  // placement of this texture into this group.
415  TexturePlacement *placement = texture->get_placement(group);
416  nassertv(placement != nullptr);
417 
418  reference->set_placement(placement);
419  }
420  }
421  }
422 }
423 
424 /**
425  * Returns true if the EggData for this EggFile has been loaded, and not yet
426  * released.
427  */
428 bool EggFile::
429 has_data() const {
430  return (_data != nullptr);
431 }
432 
433 /**
434  * Returns true if the EggData for this EggFile has ever been loaded in this
435  * session.
436  */
437 bool EggFile::
438 had_data() const {
439  return _had_data;
440 }
441 
442 /**
443  * Once all textures have been placed appropriately, updates the egg file with
444  * all the information to reference the new textures.
445  */
446 void EggFile::
448  nassertv(_data != nullptr);
449 
450  Textures::iterator ti;
451  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
452  TextureReference *reference = (*ti);
453  reference->update_egg();
454  }
455 }
456 
457 /**
458  * Removes this egg file from all things that reference it, in preparation for
459  * removing it from the database.
460  */
461 void EggFile::
463  Textures::iterator ti;
464  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
465  TextureReference *reference = (*ti);
466  TexturePlacement *placement = reference->get_placement();
467  placement->remove_egg(reference);
468  }
469 }
470 
471 /**
472  * Reads in the egg file from its _source_filename. It is only valid to call
473  * this if it has not already been read in, e.g. from the command line.
474  * Returns true if successful, false if there is an error.
475  *
476  * This may also be called after a previous call to release_egg_data(), in
477  * order to re-read the same egg file.
478  */
479 bool EggFile::
480 read_egg(bool noabs) {
481  nassertr(_data == nullptr, false);
482  nassertr(!_source_filename.empty(), false);
483 
484  Filename user_source_filename =
485  FilenameUnifier::make_user_filename(_source_filename);
486 
487  if (!_source_filename.exists()) {
488  nout << user_source_filename << " does not exist.\n";
489  return false;
490  }
491 
492  PT(EggData) data = new EggData;
493  if (!data->read(_source_filename, user_source_filename)) {
494  // Failure reading.
495  return false;
496  }
497 
498  if (noabs && data->original_had_absolute_pathnames()) {
499  nout << _source_filename.get_basename()
500  << " references textures using absolute pathnames!\n";
501  return false;
502  }
503 
504  // Extract the set of textures referenced by this egg file.
506  tc.find_used_textures(data);
507 
508  // Make sure each tref name is unique within a given file.
509  tc.uniquify_trefs();
510 
511  // Now build up a list of new TextureReference objects that represent the
512  // textures actually used and their uv range, etc.
513  Textures new_textures;
514 
515  // We want to search for filenames based on the egg directory, and also on
516  // our current directory from which we originally loaded the egg file. This
517  // is important because it's possible the egg file referenced some textures
518  // or something relative to that directory.
519  DSearchPath dir;
520  dir.append_directory(_source_filename.get_dirname());
521  dir.append_directory(_current_directory);
522  data->resolve_filenames(dir);
523 
524  // If any relative filenames remain, they are relative to the source
525  // directory, by convention.
526  data->force_filenames(_current_directory);
527 
528  if (!data->load_externals()) {
529  // Failure reading an external.
530  return false;
531  }
532 
533  _data = data;
534  _had_data = true;
535  remove_backstage(_data);
536 
537  // Insert a comment that shows how we first generated the egg file.
538  PT(EggNode) comment = new EggComment("", _egg_comment);
539  _data->insert(_data->begin(), comment);
540 
541  if (!_textures.empty()) {
542  // If we already have textures, assume we're re-reading the file.
543  rescan_textures();
544  }
545 
546  return true;
547 }
548 
549 /**
550  * Releases the memory that was loaded by a previous call to read_egg().
551  */
552 void EggFile::
554  if (_data != nullptr) {
555  _data = nullptr;
556  }
557  Textures::iterator ti;
558  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
559  TextureReference *reference = (*ti);
560  reference->release_egg_data();
561  }
562 }
563 
564 /**
565  * Writes out the egg file to its _dest_filename. Returns true if successful,
566  * false if there is an error.
567  */
568 bool EggFile::
570  nassertr(_data != nullptr, false);
571  nassertr(!_dest_filename.empty(), false);
572 
573  _dest_filename.make_dir();
574  nout << "Writing " << FilenameUnifier::make_user_filename(_dest_filename)
575  << "\n";
576  if (!_data->write_egg(_dest_filename)) {
577  // Some error while writing. Most unusual.
578  _is_stale = true;
579  return false;
580  }
581 
582  _is_stale = false;
583  return true;
584 }
585 
586 /**
587  * Writes a one-line description of the egg file and its group assignments to
588  * the indicated output stream.
589  */
590 void EggFile::
591 write_description(std::ostream &out, int indent_level) const {
592  indent(out, indent_level) << get_name() << ": ";
593  if (_explicitly_assigned_groups.empty()) {
594  if (_default_group != nullptr) {
595  out << _default_group->get_name();
596  }
597  } else {
598  out << _explicitly_assigned_groups;
599  }
600 
601  if (is_stale()) {
602  out << " (needs update)";
603  }
604  out << "\n";
605 }
606 
607 /**
608  * Writes the list of texture references to the indicated output stream, one
609  * per line.
610  */
611 void EggFile::
612 write_texture_refs(std::ostream &out, int indent_level) const {
613  Textures::const_iterator ti;
614  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
615  TextureReference *reference = (*ti);
616  reference->write(out, indent_level);
617  }
618 }
619 
620 /**
621  * Recursively walks the egg hierarchy and removes any "backstage" nodes found
622  * from the scene graph completely. These aren't part of the egg scene
623  * anyway, and removing them early helps reduce confusion.
624  */
625 void EggFile::
626 remove_backstage(EggGroupNode *node) {
627  EggGroupNode::iterator ci;
628  ci = node->begin();
629  while (ci != node->end()) {
630  EggNode *child = (*ci);
631  bool remove_child = false;
632 
633  if (child->is_of_type(EggGroup::get_class_type())) {
634  EggGroup *egg_group;
635  DCAST_INTO_V(egg_group, child);
636  remove_child = egg_group->has_object_type("backstage");
637  }
638 
639  if (remove_child) {
640  ci = node->erase(ci);
641  } else {
642  if (child->is_of_type(EggGroupNode::get_class_type())) {
643  // Recurse on children.
644  remove_backstage(DCAST(EggGroupNode, child));
645  }
646  ++ci;
647  }
648  }
649 }
650 
651 /**
652  * After reloading the egg file for the second time in a given session,
653  * rematches the texture pointers with the TextureReference objects.
654  */
655 void EggFile::
656 rescan_textures() {
657  nassertv(_data != nullptr);
658 
659  // Extract the set of textures referenced by this egg file.
661  tc.find_used_textures(_data);
662 
663  // Make sure each tref name is unique within a given file.
664  tc.uniquify_trefs();
665 
666  typedef pmap<std::string, TextureReference *> ByTRefName;
667  ByTRefName by_tref_name;
668  for (Textures::const_iterator ti = _textures.begin();
669  ti != _textures.end();
670  ++ti) {
671  TextureReference *ref = (*ti);
672  by_tref_name[ref->get_tref_name()] = ref;
673  }
674 
675  EggTextureCollection::iterator eti;
676  for (eti = tc.begin(); eti != tc.end(); ++eti) {
677  EggTexture *egg_tex = (*eti);
678 
679  ByTRefName::const_iterator tni = by_tref_name.find(egg_tex->get_name());
680  if (tni == by_tref_name.end()) {
681  // We didn't find this TRef name last time around!
682  nout << _source_filename.get_basename()
683  << " modified during session--TRef " << egg_tex->get_name()
684  << " is new!\n";
685 
686  } else {
687  TextureReference *ref = (*tni).second;
688  ref->rebind_egg_data(_data, egg_tex);
689  }
690  }
691 }
692 
693 /**
694  * Registers the current object as something that can be read from a Bam file.
695  */
696 void EggFile::
699  register_factory(get_class_type(), make_EggFile);
700 }
701 
702 /**
703  * Fills the indicated datagram up with a binary representation of the current
704  * object, in preparation for writing to a Bam file.
705  */
706 void EggFile::
707 write_datagram(BamWriter *writer, Datagram &datagram) {
708  TypedWritable::write_datagram(writer, datagram);
709  datagram.add_string(get_name());
710 
711  // We don't write out _data; that needs to be reread each session.
712 
713  datagram.add_string(FilenameUnifier::make_bam_filename(_current_directory));
714  datagram.add_string(FilenameUnifier::make_bam_filename(_source_filename));
715  datagram.add_string(FilenameUnifier::make_bam_filename(_dest_filename));
716  datagram.add_string(_egg_comment);
717 
718  datagram.add_uint32(_textures.size());
719  Textures::iterator ti;
720  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
721  writer->write_pointer(datagram, (*ti));
722  }
723 
724  _explicitly_assigned_groups.write_datagram(writer, datagram);
725  writer->write_pointer(datagram, _default_group);
726 
727  // We don't write out _complete_groups; that is recomputed each session.
728 
729  datagram.add_bool(_is_surprise);
730  datagram.add_bool(_is_stale);
731 }
732 
733 /**
734  * Called after the object is otherwise completely read from a Bam file, this
735  * function's job is to store the pointers that were retrieved from the Bam
736  * file for each pointer object written. The return value is the number of
737  * pointers processed from the list.
738  */
739 int EggFile::
741  int pi = TypedWritable::complete_pointers(p_list, manager);
742 
743  int i;
744  _textures.reserve(_num_textures);
745  for (i = 0; i < _num_textures; i++) {
746  TextureReference *texture;
747  DCAST_INTO_R(texture, p_list[pi], pi);
748  _textures.push_back(texture);
749  pi++;
750  }
751 
752  pi += _explicitly_assigned_groups.complete_pointers(p_list + pi, manager);
753 
754  if (p_list[pi] != nullptr) {
755  DCAST_INTO_R(_default_group, p_list[pi], pi);
756  }
757  pi++;
758 
759  return pi;
760 }
761 
762 /**
763  * This method is called by the BamReader when an object of this type is
764  * encountered in a Bam file; it should allocate and return a new object with
765  * all the data read.
766  */
767 TypedWritable* EggFile::
768 make_EggFile(const FactoryParams &params) {
769  EggFile *me = new EggFile();
770  DatagramIterator scan;
771  BamReader *manager;
772 
773  parse_params(params, scan, manager);
774  me->fillin(scan, manager);
775  return me;
776 }
777 
778 /**
779  * Reads the binary data from the given datagram iterator, which was written
780  * by a previous call to write_datagram().
781  */
782 void EggFile::
783 fillin(DatagramIterator &scan, BamReader *manager) {
784  TypedWritable::fillin(scan, manager);
785  set_name(scan.get_string());
786  _current_directory = FilenameUnifier::get_bam_filename(scan.get_string());
787  _source_filename = FilenameUnifier::get_bam_filename(scan.get_string());
788  _dest_filename = FilenameUnifier::get_bam_filename(scan.get_string());
789  if (Palettizer::_read_pi_version >= 9) {
790  _egg_comment = scan.get_string();
791  }
792 
793  _num_textures = scan.get_uint32();
794  manager->read_pointers(scan, _num_textures);
795 
796  _explicitly_assigned_groups.fillin(scan, manager);
797  manager->read_pointer(scan); // _default_group
798 
799  _is_surprise = scan.get_bool();
800  _is_stale = scan.get_bool();
801 
802  if (Palettizer::_read_pi_version < 11) {
803  // If this file was written by a version of egg-palettize prior to 11, we
804  // didn't store the tref names on the texture references. Since we need
805  // that information now, it follows that every egg file is stale.
806  _is_stale = true;
807  }
808 }
bool is_equivalent(const TextureReference &other) const
Returns true if all essential properties of this TextureReference are the same as that of the other,...
void increment_egg_count()
Increments by one the number of egg files that are known to reference this SourceTextureImage.
void make_intersection(const PaletteGroups &a, const PaletteGroups &b)
Computes the intersection of PaletteGroups a and b, and stores the result in this object.
void from_egg_quick(const TextureReference &other)
Sets up the pointers within the TextureReference to the same egg file pointers indicated by the other...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static Filename make_bam_filename(Filename filename)
Returns a new filename that's made relative to the bam file itself, suitable for writing to the bam f...
std::string get_dirname() const
Returns the directory part of the filename.
Definition: filename.I:358
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function's job is to store...
void set_placement(TexturePlacement *placement)
Sets the particular TexturePlacement that is appropriate for this egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void uniquify_trefs()
Guarantees that each texture in the collection has a unique TRef name.
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
void post_txa_file()
Once the egg file has been matched against all of the matching lines the .txa file,...
Definition: eggFile.cxx:249
void update_egg()
Updates the egg file with all the relevant information to reference the texture in its new home,...
iterator end() const
Returns an iterator suitable for traversing the set.
void apply_properties_to_source()
Applies the texture properties as read from the egg file to the source image's properties.
bool get_bool()
Extracts a boolean value.
void scan_textures()
Scans the egg file for texture references and updates the _textures list appropriately.
Definition: eggFile.cxx:102
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
void write_description(std::ostream &out, int indent_level=0) const
Writes a one-line description of the egg file and its group assignments to the indicated output strea...
Definition: eggFile.cxx:591
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
This is the particular reference of a texture filename by an egg file.
A base class for nodes in the hierarchy that are not leaf nodes.
Definition: eggGroupNode.h:46
PaletteGroup * get_group() const
Returns the group that this placement represents.
A comment that appears in an egg file within a <Comment> entry.
Definition: eggComment.h:24
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:30
bool had_data() const
Returns true if the EggData for this EggFile has ever been loaded in this session.
Definition: eggFile.cxx:438
void clear_surprise()
Removes the 'surprise' flag; this file has been successfully matched against a line in the ....
Definition: eggFile.cxx:285
void mark_stale()
Marks this particular egg file as stale, meaning that something has changed, such as the location of ...
Definition: eggFile.cxx:304
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
iterator begin() const
Returns an iterator suitable for traversing the set.
size_type count(PaletteGroup *group) const
Returns the number of times the given group appears in the set.
This is the highest level of grouping for TextureImages.
Definition: paletteGroup.h:43
const Filename & get_source_filename() const
Returns the filename this egg file was read from.
Definition: eggFile.cxx:91
void remove_egg()
Removes this egg file from all things that reference it, in preparation for removing it from the data...
Definition: eggFile.cxx:462
void pre_txa_file()
Does some processing prior to scanning the .txa file.
Definition: eggFile.cxx:221
bool read_egg(bool noabs)
Reads in the egg file from its _source_filename.
Definition: eggFile.cxx:480
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear()
Empties the set.
This is a collection of textures by TRef name.
TexturePlacement * get_placement(PaletteGroup *group) const
Gets the TexturePlacement object which represents the assignment of this texture to the indicated gro...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const PaletteGroups & get_explicit_groups() const
Returns the set of PaletteGroups that the egg file has been explicitly assigned to in the ....
Definition: eggFile.cxx:257
void append_directory(const Filename &directory)
Adds a new directory to the end of the search list.
void apply_properties_to_source()
Calls apply_properties_to_source() for each texture reference, updating all the referenced source tex...
Definition: eggFile.cxx:364
This is the primary interface into all the egg data, and the root of the egg file structure.
Definition: eggData.h:37
const PaletteGroups & get_complete_groups() const
Returns the complete set of PaletteGroups that the egg file is assigned to.
Definition: eggFile.cxx:276
std::string get_string()
Extracts a variable-length string.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
SourceTextureImage * get_source() const
Returns the SourceTextureImage that this object refers to.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
void note_egg_file(EggFile *egg_file)
Records that a particular egg file references this texture.
void add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:94
An STL function object class, this is intended to be used on any ordered collection of pointers to cl...
Definition: indirectLess.h:25
TextureImage * get_texture() const
Returns the TextureImage that this object refers to.
void get_textures(pset< TextureImage * > &result) const
Fills up the indicated set with the set of textures referenced by this egg file.
Definition: eggFile.cxx:210
void choose_placements()
Once all the textures have been assigned to groups (but before they may actually be placed),...
Definition: eggFile.cxx:381
const std::string & get_tref_name() const
Returns the name of the EggTexture entry that references this texture.
void release_egg_data()
Releases the memory that was loaded by a previous call to read_egg().
Definition: eggFile.cxx:553
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
bool from_command_line(EggData *data, const Filename &source_filename, const Filename &dest_filename, const std::string &egg_comment)
Accepts the information about the egg file as supplied from the command line.
Definition: eggFile.cxx:57
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function's job is to store...
Definition: eggFile.cxx:740
static Filename make_user_filename(Filename filename)
Returns a new filename that's made relative to the current directory, suitable for reporting to the u...
void match_txa_groups(const PaletteGroups &groups)
Adds the indicated set of groups, read from the .txa file, to the set of groups to which the egg file...
Definition: eggFile.cxx:231
bool write_egg()
Writes out the egg file to its _dest_filename.
Definition: eggFile.cxx:569
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void update_egg()
Once all textures have been placed appropriately, updates the egg file with all the information to re...
Definition: eggFile.cxx:447
bool has_object_type(const std::string &object_type) const
Returns true if the indicated object type has been added to the group, or false otherwise.
Definition: eggGroup.cxx:145
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
Definition: bamReader.cxx:653
void rebind_egg_data(EggData *data, EggTexture *egg_tex)
After an EggData has previously been released via release_egg_data(), this can be called to indicate ...
static Filename get_bam_filename(Filename filename)
Returns an absolute pathname based on the given relative pathname, presumably read from the bam file ...
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
Definition: eggFile.cxx:697
bool has_data() const
Returns true if the EggData for this EggFile has been loaded, and not yet released.
Definition: eggFile.cxx:429
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:219
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
uint32_t get_uint32()
Extracts an unsigned 32-bit integer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool empty() const
Returns true if the set is empty, false otherwise.
This corresponds to a particular assignment of a TextureImage with a PaletteGroup,...
void from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex)
Sets up the TextureReference using information extracted from an egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int find_used_textures(EggNode *node)
Walks the egg hierarchy beginning at the indicated node, looking for textures that are referenced by ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_basename() const
Returns the basename part of the filename.
Definition: filename.I:367
bool is_surprise() const
Returns true if this particular egg file is a 'surprise', i.e.
Definition: eggFile.cxx:294
bool is_stale() const
Returns true if the egg file needs to be updated, i.e.
Definition: eggFile.cxx:313
void make_complete(const PaletteGroups &a)
Completes the set with the transitive closure of all dependencies: for each PaletteGroup already in t...
void make_absolute()
Converts the filename to a fully-qualified pathname from the root (if it is a relative pathname),...
Definition: filename.cxx:968
void make_union(const PaletteGroups &a, const PaletteGroups &b)
Computes the union of PaletteGroups a and b, and stores the result in this object.
void remove_egg(TextureReference *reference)
Notes that a particular egg file is no longer using this particular TexturePlacement.
void insert(PaletteGroup *group)
Inserts a new group to the set, if it is not already there.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
Definition: eggFile.cxx:707
A set of PaletteGroups.
Definition: paletteGroups.h:28
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:35
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:610
This class stores a list of directories that can be searched, in order, to locate a particular file.
Definition: dSearchPath.h:28
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
bool make_dir() const
Creates all the directories in the path to the file specified in the filename, except for the basenam...
Definition: filename.cxx:2484
PaletteGroup * get_default_group()
Returns the default group to which an egg file should be assigned if it is not mentioned in the ....
Definition: palettizer.cxx:824
bool has_uvs() const
Returns true if this TextureReference actually uses the texture on geometry, with UV's and everything...
A class to retrieve the individual data elements previously stored in a Datagram.
This represents a single source texture that is referenced by one or more egg files.
Definition: textureImage.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void build_cross_links()
Calls TextureImage::note_egg_file() and SourceTextureImage::increment_egg_count() for each texture th...
Definition: eggFile.cxx:325
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
TexturePlacement * get_placement() const
Returns the particular TexturePlacement that is appropriate for this egg file.
void release_egg_data()
Called to indicate that the EggData previously passed to from_egg() is about to be deallocated,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
Definition: filename.cxx:1267
void write_texture_refs(std::ostream &out, int indent_level=0) const
Writes the list of texture references to the indicated output stream, one per line.
Definition: eggFile.cxx:612
This represents a single egg file known to the palettizer.
Definition: eggFile.h:36
PaletteGroup * get_default_group() const
Returns the PaletteGroup that was specified as the default group on the command line at the time the ...
Definition: eggFile.cxx:266
const PaletteGroups & get_groups() const
Once assign_groups() has been called, this returns the actual set of groups the TextureImage has been...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:317
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.