Panda3D
paletteGroup.cxx
1 // Filename: paletteGroup.cxx
2 // Created by: drose (30Nov00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "paletteGroup.h"
16 #include "palettePage.h"
17 #include "texturePlacement.h"
18 #include "textureImage.h"
19 #include "palettizer.h"
20 #include "paletteImage.h"
21 
22 #include "indent.h"
23 #include "datagram.h"
24 #include "datagramIterator.h"
25 #include "bamReader.h"
26 #include "bamWriter.h"
27 #include "indirectCompareNames.h"
28 #include "pvector.h"
29 
30 TypeHandle PaletteGroup::_type_handle;
31 
32 ////////////////////////////////////////////////////////////////////
33 // Function: PaletteGroup::Constructor
34 // Access: Public
35 // Description:
36 ////////////////////////////////////////////////////////////////////
37 PaletteGroup::
38 PaletteGroup() {
39  _egg_count = 0;
40  _dependency_level = 0;
41  _dependency_order = 0;
42  _dirname_order = 0;
43  _has_margin_override = false;
44  _margin_override = 0;
45 }
46 
47 ////////////////////////////////////////////////////////////////////
48 // Function: PaletteGroup::set_dirname
49 // Access: Public
50 // Description: Sets the directory name associated with the palette
51 // group. This is an optional feature that can be used
52 // to place the maps for the different palette groups
53 // into different install directories.
54 ////////////////////////////////////////////////////////////////////
55 void PaletteGroup::
56 set_dirname(const string &dirname) {
57  _dirname = dirname;
58 }
59 
60 ////////////////////////////////////////////////////////////////////
61 // Function: PaletteGroup::has_dirname
62 // Access: Public
63 // Description: Returns true if the directory name has been
64 // explicitly set for this group. If it has not,
65 // get_dirname() returns an empty string.
66 ////////////////////////////////////////////////////////////////////
67 bool PaletteGroup::
68 has_dirname() const {
69  return !_dirname.empty();
70 }
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function: PaletteGroup::get_dirname
74 // Access: Public
75 // Description: Returns the directory name associated with the
76 // palette group. See set_dirname().
77 ////////////////////////////////////////////////////////////////////
78 const string &PaletteGroup::
79 get_dirname() const {
80  return _dirname;
81 }
82 
83 ////////////////////////////////////////////////////////////////////
84 // Function: PaletteGroup::clear_depends
85 // Access: Public
86 // Description: Eliminates all the dependency information for this
87 // group.
88 ////////////////////////////////////////////////////////////////////
89 void PaletteGroup::
91  _dependent.clear();
92  _dependency_level = 0;
93  _dependency_order = 0;
94  _dirname_order = 0;
95 }
96 
97 ////////////////////////////////////////////////////////////////////
98 // Function: PaletteGroup::group_with
99 // Access: Public
100 // Description: Indicates a dependency of this group on some other
101 // group. This means that the textures assigned to this
102 // group may be considered successfully assigned if they
103 // are actually placed in the other group. In practice,
104 // this means that the textures associated with the
105 // other palette group will always be resident at
106 // runtime when textures from this palette group are
107 // required.
108 ////////////////////////////////////////////////////////////////////
109 void PaletteGroup::
111  _dependent.insert(other);
112 }
113 
114 ////////////////////////////////////////////////////////////////////
115 // Function: PaletteGroup::get_groups
116 // Access: Public
117 // Description: Returns the set of groups this group depends on.
118 ////////////////////////////////////////////////////////////////////
120 get_groups() const {
121  return _dependent;
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function: PaletteGroup::get_margin_override
126 // Access: Public
127 // Description: Returns the set of groups this group depends on.
128 ////////////////////////////////////////////////////////////////////
129 int PaletteGroup::
131  return _margin_override;
132 }
133 
134 ////////////////////////////////////////////////////////////////////
135 // Function: PaletteGroup::get_margin_override
136 // Access: Public
137 // Description: Returns the set of groups this group depends on.
138 ////////////////////////////////////////////////////////////////////
139 void PaletteGroup::
140 set_margin_override(const int override) {
141  _margin_override = override;
142  _has_margin_override = true;
143 }
144 
145 ////////////////////////////////////////////////////////////////////
146 // Function: PaletteGroup::has_margin_override
147 // Access: Public
148 // Description: Returns the set of groups this group depends on.
149 ////////////////////////////////////////////////////////////////////
150 bool PaletteGroup::
152  return _has_margin_override;
153 }
154 
155 ////////////////////////////////////////////////////////////////////
156 // Function: PaletteGroup::get_placements
157 // Access: Public
158 // Description: Adds the set of TexturePlacements associated with
159 // this group to the indicated vector. The vector is
160 // not cleared before this operation; if the user wants
161 // to retrieve the set of placements particular to this
162 // group only, it is the user's responsibility to clear
163 // the vector first.
164 ////////////////////////////////////////////////////////////////////
165 void PaletteGroup::
167  Placements::const_iterator pi;
168  for (pi = _placements.begin(); pi != _placements.end(); ++pi) {
169  placements.push_back(*pi);
170  }
171 }
172 
173 ////////////////////////////////////////////////////////////////////
174 // Function: PaletteGroup::get_complete_placements
175 // Access: Public
176 // Description: Adds the set of TexturePlacements associated with
177 // this group and all dependent groups to the indicated
178 // vector. See get_placements().
179 ////////////////////////////////////////////////////////////////////
180 void PaletteGroup::
182  PaletteGroups complete;
183  complete.make_complete(_dependent);
184 
185  PaletteGroups::iterator gi;
186  for (gi = complete.begin(); gi != complete.end(); ++gi) {
187  PaletteGroup *group = (*gi);
188  group->get_placements(placements);
189  }
190 
191  get_placements(placements);
192 }
193 
194 ////////////////////////////////////////////////////////////////////
195 // Function: PaletteGroup::reset_dependency_level
196 // Access: Public
197 // Description: Unconditionally sets the dependency level and order
198 // of this group to zero, in preparation for a later
199 // call to set_dependency_level(). See
200 // set_dependency_level().
201 ////////////////////////////////////////////////////////////////////
202 void PaletteGroup::
204  _dependency_level = 0;
205  _dependency_order = 0;
206  _dirname_order = 0;
207 }
208 
209 ////////////////////////////////////////////////////////////////////
210 // Function: PaletteGroup::set_dependency_level
211 // Access: Public
212 // Description: Sets the dependency level of this group to the
213 // indicated level, provided that level is not lower
214 // than the level that was set previously. Also
215 // cascades to all dependent groups. See
216 // get_dependency_level().
217 //
218 // This call recurses to correctly set the dependency
219 // level of all PaletteGroups in the hierarchy.
220 ////////////////////////////////////////////////////////////////////
221 void PaletteGroup::
223  if (level > _dependency_level) {
224  _dependency_level = level;
225  PaletteGroups::iterator gi;
226  for (gi = _dependent.begin(); gi != _dependent.end(); ++gi) {
227  PaletteGroup *group = (*gi);
228  group->set_dependency_level(level + 1);
229  }
230  }
231 }
232 
233 ////////////////////////////////////////////////////////////////////
234 // Function: PaletteGroup::set_dependency_order
235 // Access: Public
236 // Description: Updates the dependency order of this group. This
237 // number is the inverse of the dependency level, and
238 // can be used to rank the groups in order so that all
239 // the groups that a given group depends on will appear
240 // first in the list. See get_dependency_order().
241 //
242 // This function returns true if anything was changed,
243 // false otherwise.
244 ////////////////////////////////////////////////////////////////////
245 bool PaletteGroup::
247  bool any_changed = false;
248 
249  PaletteGroups::iterator gi;
250  for (gi = _dependent.begin(); gi != _dependent.end(); ++gi) {
251  PaletteGroup *group = (*gi);
252  if (group->set_dependency_order()) {
253  any_changed = true;
254  }
255 
256  if (_dependency_order <= group->get_dependency_order()) {
257  _dependency_order = group->get_dependency_order() + 1;
258  any_changed = true;
259  }
260 
261  if (_dirname == group->get_dirname()) {
262  // The dirname orders should be equal.
263  if (_dirname_order < group->get_dirname_order()) {
264  _dirname_order = group->get_dirname_order();
265  any_changed = true;
266  }
267  } else {
268  // The dirname orders should be different.
269  if (_dirname_order <= group->get_dirname_order()) {
270  _dirname_order = group->get_dirname_order() + 1;
271  any_changed = true;
272  }
273  }
274  }
275 
276  return any_changed;
277 }
278 
279 ////////////////////////////////////////////////////////////////////
280 // Function: PaletteGroup::get_dependency_level
281 // Access: Public
282 // Description: Returns the dependency level of this group. This is
283 // a measure of how specific the group is; the lower the
284 // dependency level, the more specific the group.
285 //
286 // Groups depend on other groups in a hierarchical
287 // relationship. In general, if group a depends on
288 // group b, then b->get_dependency_level() >
289 // a->get_dependency_level().
290 //
291 // Thus, groups that lots of other groups depend on have
292 // a higher dependency level; groups that no one else
293 // depends on have a low dependency level. This is
294 // important when deciding which groups are best suited
295 // for assigning a texture to; in general, the texture
296 // should be assigned to the most specific suitable
297 // group (i.e. the one with the lowest dependency
298 // level).
299 ////////////////////////////////////////////////////////////////////
300 int PaletteGroup::
302  return _dependency_level;
303 }
304 
305 ////////////////////////////////////////////////////////////////////
306 // Function: PaletteGroup::get_dependency_order
307 // Access: Public
308 // Description: Returns the dependency order of this group. This is
309 // similar in principle to the dependency level, but it
310 // represents the inverse concept: if group a depends on
311 // group b, then a->get_dependency_order() >
312 // b->get_dependency_order().
313 //
314 // This is not exactly the same thing as n -
315 // get_dependency_level(). In particular, this can be
316 // used to sort the groups into an ordering such that
317 // all the groups that group a depends on appear before
318 // group a in the list.
319 ////////////////////////////////////////////////////////////////////
320 int PaletteGroup::
322  return _dependency_order;
323 }
324 
325 ////////////////////////////////////////////////////////////////////
326 // Function: PaletteGroup::get_dirname_order
327 // Access: Public
328 // Description: Returns the dependency order of this group. This is
329 // similar in principle to the dependency level, but it
330 // represents the inverse concept: if group a depends on
331 // group b, then a->get_dirname_order() >
332 // b->get_dirname_order().
333 //
334 // This is not exactly the same thing as n -
335 // get_dependency_level(). In particular, this can be
336 // used to sort the groups into an ordering such that
337 // all the groups that group a depends on appear before
338 // group a in the list.
339 ////////////////////////////////////////////////////////////////////
340 int PaletteGroup::
342  return _dirname_order;
343 }
344 
345 ////////////////////////////////////////////////////////////////////
346 // Function: PaletteGroup::is_preferred_over
347 // Access: Public
348 // Description: Returns true if this group should be preferred for
349 // adding textures over the other group, if both are
350 // available. In other words, this is a more specific
351 // group than the other one.
352 ////////////////////////////////////////////////////////////////////
353 bool PaletteGroup::
354 is_preferred_over(const PaletteGroup &other) const {
355  if (get_dirname_order() != other.get_dirname_order()) {
356  return (get_dirname_order() > other.get_dirname_order());
357 
358  } else if (get_dependency_order() != other.get_dependency_order()) {
359  return (get_dependency_order() > other.get_dependency_order());
360 
361  } else {
362  return (get_egg_count() < other.get_egg_count());
363  }
364 }
365 
366 ////////////////////////////////////////////////////////////////////
367 // Function: PaletteGroup::increment_egg_count
368 // Access: Public
369 // Description: Increments by one the number of egg files that are
370 // known to reference this PaletteGroup. This is
371 // designed to aid the heuristics in texture placing;
372 // it's useful to know how many different egg files are
373 // sharing a particular PaletteGroup.
374 ////////////////////////////////////////////////////////////////////
375 void PaletteGroup::
377  _egg_count++;
378 }
379 
380 ////////////////////////////////////////////////////////////////////
381 // Function: PaletteGroup::get_egg_count
382 // Access: Public
383 // Description: Returns the number of egg files that share this
384 // PaletteGroup.
385 ////////////////////////////////////////////////////////////////////
386 int PaletteGroup::
387 get_egg_count() const {
388  return _egg_count;
389 }
390 
391 ////////////////////////////////////////////////////////////////////
392 // Function: PaletteGroup::get_page
393 // Access: Public
394 // Description: Returns the page associated with the indicated
395 // properties. If no page object has yet been created,
396 // creates one.
397 ////////////////////////////////////////////////////////////////////
399 get_page(const TextureProperties &properties) {
400  Pages::iterator pi = _pages.find(properties);
401  if (pi != _pages.end()) {
402  return (*pi).second;
403  }
404 
405  PalettePage *page = new PalettePage(this, properties);
406  bool inserted = _pages.insert(Pages::value_type(properties, page)).second;
407  nassertr(inserted, page);
408  return page;
409 }
410 
411 ////////////////////////////////////////////////////////////////////
412 // Function: PaletteGroup::prepare
413 // Access: Public
414 // Description: Marks the indicated Texture as ready for placing
415 // somewhere within this group, and returns a
416 // placeholder TexturePlacement object. The texture is
417 // not placed immediately, but may be placed later when
418 // place_all() is called; at this time, the
419 // TexturePlacement fields will be filled in as
420 // appropriate.
421 ////////////////////////////////////////////////////////////////////
424  TexturePlacement *placement = new TexturePlacement(texture, this);
425  _placements.insert(placement);
426 
427  // [gjeon] update swapTexture information
428  TextureSwapInfo::iterator tsi = _textureSwapInfo.find(texture->get_name());
429  if (tsi != _textureSwapInfo.end()) {
430  vector_string swapTextures = (*tsi).second;
431 
432  vector_string::const_iterator wi;
433  wi = swapTextures.begin();
434  ++wi;
435  ++wi;
436 
437  // [gjeon] since swapped texture usually didn't mapped to any egg file
438  // we need to create soucreTextureImage by using original texture file's info
439  const string originalTextureName = (*wi);
440  TextureImage *originalTexture = pal->get_texture(originalTextureName);
441  SourceTextureImage *source = originalTexture->get_preferred_source();
442  const Filename originalTextureFilename = source->get_filename();
443  const Filename originalTextureAlphaFilename = source->get_alpha_filename();
444  int originalTextureAlphaFileChannel = source->get_alpha_file_channel();
445 
446  ++wi;
447  while (wi != swapTextures.end()) {
448  const string &swapTextureName = (*wi);
449  TextureImage *swapTextureImage = pal->get_texture(swapTextureName);
450  Filename swapTextureFilename = Filename(originalTextureFilename.get_dirname(), swapTextureName + "." + originalTextureFilename.get_extension());
451  swapTextureImage->get_source(swapTextureFilename, originalTextureAlphaFilename, originalTextureAlphaFileChannel);
452  placement->_textureSwaps.push_back(swapTextureImage);
453  ++wi;
454  }
455  }
456 
457  return placement;
458 }
459 
460 ////////////////////////////////////////////////////////////////////
461 // Function: PaletteGroup::unplace
462 // Access: Public
463 // Description: Removes the texture from its position on a
464 // PaletteImage, if it has been so placed.
465 ////////////////////////////////////////////////////////////////////
466 void PaletteGroup::
468  nassertv(placement->get_group() == this);
469 
470  Placements::iterator pi;
471  pi = _placements.find(placement);
472  if (pi != _placements.end()) {
473  _placements.erase(pi);
474 
475  if (placement->is_placed()) {
476  placement->get_page()->unplace(placement);
477  }
478  }
479 }
480 
481 ////////////////////////////////////////////////////////////////////
482 // Function: PaletteGroup::place_all
483 // Access: Public
484 // Description: Once all the textures have been assigned to this
485 // group, try to place them all onto suitable
486 // PaletteImages.
487 ////////////////////////////////////////////////////////////////////
488 void PaletteGroup::
490  // First, go through our prepared textures and assign each unplaced
491  // one to an appropriate page.
492  Placements::iterator pli;
493  for (pli = _placements.begin(); pli != _placements.end(); ++pli) {
494  TexturePlacement *placement = (*pli);
495 
496  if (placement->get_omit_reason() == OR_working) {
497  PalettePage *page = get_page(placement->get_properties());
498  page->assign(placement);
499  }
500  }
501 
502  // Then, go through the pages and actually do the placing.
503  Pages::iterator pai;
504  for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
505  PalettePage *page = (*pai).second;
506  page->place_all();
507  }
508 }
509 
510 ////////////////////////////////////////////////////////////////////
511 // Function: PaletteGroup::update_unknown_textures
512 // Access: Public
513 // Description: Checks for new information on any textures within the
514 // group for which some of the saved information is
515 // incomplete. This may be necessary before we can
516 // properly place all of the textures.
517 ////////////////////////////////////////////////////////////////////
518 void PaletteGroup::
520  Placements::iterator pli;
521  for (pli = _placements.begin(); pli != _placements.end(); ++pli) {
522  TexturePlacement *placement = (*pli);
523 
524  if (!placement->is_size_known()) {
525  // This texture's size isn't known; we have to determine its
526  // size.
527  TextureImage *texture = placement->get_texture();
528  if (!texture->got_txa_file()) {
529  // But first, we need to look up the texture in the .txa file.
530  texture->pre_txa_file();
531  txa_file.match_texture(texture);
532  texture->post_txa_file();
533  }
534 
535  placement->determine_size();
536  }
537  }
538 }
539 
540 ////////////////////////////////////////////////////////////////////
541 // Function: PaletteGroup::write_image_info
542 // Access: Public
543 // Description: Writes a list of the PaletteImages associated with
544 // this group, and all of their textures, to the
545 // indicated output stream.
546 ////////////////////////////////////////////////////////////////////
547 void PaletteGroup::
548 write_image_info(ostream &out, int indent_level) const {
549  Pages::const_iterator pai;
550  for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
551  PalettePage *page = (*pai).second;
552  page->write_image_info(out, indent_level);
553  }
554 
555  // Write out all the unplaced textures, in alphabetical order by name.
556  pvector<TexturePlacement *> placement_vector;
557  placement_vector.reserve(_placements.size());
558  Placements::const_iterator pli;
559  for (pli = _placements.begin(); pli != _placements.end(); ++pli) {
560  TexturePlacement *placement = (*pli);
561  if (placement->get_omit_reason() != OR_none) {
562  placement_vector.push_back(placement);
563  }
564  }
565  sort(placement_vector.begin(), placement_vector.end(),
567 
569  for (pvi = placement_vector.begin();
570  pvi != placement_vector.end();
571  ++pvi) {
572  TexturePlacement *placement = (*pvi);
573 
574  indent(out, indent_level)
575  << placement->get_texture()->get_name()
576  << " unplaced because ";
577  switch (placement->get_omit_reason()) {
578  case OR_coverage:
579  out << "coverage (" << placement->get_uv_area() << ")";
580  break;
581 
582  case OR_size:
583  out << "size (" << placement->get_x_size() << " "
584  << placement->get_y_size() << ")";
585  break;
586 
587  default:
588  out << placement->get_omit_reason();
589  }
590  out << "\n";
591  }
592 }
593 
594 ////////////////////////////////////////////////////////////////////
595 // Function: PaletteGroup::optimal_resize
596 // Access: Public
597 // Description: Attempts to resize each PalettteImage down to its
598 // smallest possible size.
599 ////////////////////////////////////////////////////////////////////
600 void PaletteGroup::
602  Pages::iterator pai;
603  for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
604  PalettePage *page = (*pai).second;
605  page->optimal_resize();
606  }
607 }
608 
609 ////////////////////////////////////////////////////////////////////
610 // Function: PaletteGroup::reset_images
611 // Access: Public
612 // Description: Throws away all of the current PaletteImages, so that
613 // new ones may be created (and the packing made more
614 // optimal).
615 ////////////////////////////////////////////////////////////////////
616 void PaletteGroup::
618  Pages::iterator pai;
619  for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
620  PalettePage *page = (*pai).second;
621  page->reset_images();
622  }
623 }
624 
625 ////////////////////////////////////////////////////////////////////
626 // Function: PaletteGroup::setup_shadow_images
627 // Access: Public
628 // Description: Ensures that each PaletteImage's _shadow_image has
629 // the correct filename and image types, based on what
630 // was supplied on the command line and in the .txa
631 // file.
632 ////////////////////////////////////////////////////////////////////
633 void PaletteGroup::
635  Pages::iterator pai;
636  for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
637  PalettePage *page = (*pai).second;
638  page->setup_shadow_images();
639  }
640 }
641 
642 ////////////////////////////////////////////////////////////////////
643 // Function: PaletteGroup::update_images
644 // Access: Public
645 // Description: Regenerates each PaletteImage on this group that needs
646 // it.
647 ////////////////////////////////////////////////////////////////////
648 void PaletteGroup::
649 update_images(bool redo_all) {
650  Pages::iterator pai;
651  for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
652  PalettePage *page = (*pai).second;
653  page->update_images(redo_all);
654  }
655 }
656 
657 ////////////////////////////////////////////////////////////////////
658 // Function: PaletteGroup::register_with_read_factory
659 // Access: Public, Static
660 // Description: Registers the current object as something that can be
661 // read from a Bam file.
662 ////////////////////////////////////////////////////////////////////
663 void PaletteGroup::
666  register_factory(get_class_type(), make_PaletteGroup);
667 }
668 
669 ////////////////////////////////////////////////////////////////////
670 // Function: PaletteGroup::write_datagram
671 // Access: Public, Virtual
672 // Description: Fills the indicated datagram up with a binary
673 // representation of the current object, in preparation
674 // for writing to a Bam file.
675 ////////////////////////////////////////////////////////////////////
676 void PaletteGroup::
677 write_datagram(BamWriter *writer, Datagram &datagram) {
678  TypedWritable::write_datagram(writer, datagram);
679  datagram.add_string(get_name());
680  datagram.add_string(_dirname);
681  _dependent.write_datagram(writer, datagram);
682 
683  datagram.add_int32(_dependency_level);
684  datagram.add_int32(_dependency_order);
685  datagram.add_int32(_dirname_order);
686 
687  datagram.add_uint32(_placements.size());
688  Placements::const_iterator pli;
689  for (pli = _placements.begin(); pli != _placements.end(); ++pli) {
690  writer->write_pointer(datagram, (*pli));
691  }
692 
693  datagram.add_uint32(_pages.size());
694  Pages::const_iterator pai;
695  for (pai = _pages.begin(); pai != _pages.end(); ++pai) {
696  writer->write_pointer(datagram, (*pai).second);
697  }
698  datagram.add_bool(_has_margin_override);
699  datagram.add_int16(_margin_override);
700 
701 }
702 
703 ////////////////////////////////////////////////////////////////////
704 // Function: PaletteGroup::complete_pointers
705 // Access: Public, Virtual
706 // Description: Called after the object is otherwise completely read
707 // from a Bam file, this function's job is to store the
708 // pointers that were retrieved from the Bam file for
709 // each pointer object written. The return value is the
710 // number of pointers processed from the list.
711 ////////////////////////////////////////////////////////////////////
712 int PaletteGroup::
714  int pi = TypedWritable::complete_pointers(p_list, manager);
715 
716  pi += _dependent.complete_pointers(p_list + pi, manager);
717 
718  int i;
719  for (i = 0; i < _num_placements; i++) {
720  TexturePlacement *placement;
721  DCAST_INTO_R(placement, p_list[pi++], pi);
722  bool inserted = _placements.insert(placement).second;
723  nassertr(inserted, pi);
724  }
725 
726  // We must store the list of pages in a temporary vector first. We
727  // can't put them directly into the map because the map requires
728  // that all the pointers in the page's get_properties() member have
729  // been filled in, which may not have happened yet.
730  _load_pages.reserve(_num_pages);
731  for (i = 0; i < _num_pages; i++) {
732  PalettePage *page;
733  DCAST_INTO_R(page, p_list[pi++], pi);
734  _load_pages.push_back(page);
735  }
736 
737  return pi;
738 }
739 
740 ////////////////////////////////////////////////////////////////////
741 // Function: PaletteGroup::finalize
742 // Access: Public, Virtual
743 // Description: This method is called by the BamReader after all
744 // pointers everywhere in the world have been completely
745 // read in. It's a hook at which the object can do
746 // whatever final setup it requires that depends on
747 // other pointers being valid.
748 ////////////////////////////////////////////////////////////////////
749 void PaletteGroup::
751  // Now we can copy the pages into the actual map.
753  for (pi = _load_pages.begin(); pi != _load_pages.end(); ++pi) {
754  PalettePage *page = (*pi);
755  bool inserted = _pages.
756  insert(Pages::value_type(page->get_properties(), page)).second;
757  nassertv(inserted);
758  }
759 
760  _load_pages.clear();
761 }
762 
763 ////////////////////////////////////////////////////////////////////
764 // Function: PaletteGroup::make_PaletteGroup
765 // Access: Protected, Static
766 // Description: This method is called by the BamReader when an object
767 // of this type is encountered in a Bam file; it should
768 // allocate and return a new object with all the data
769 // read.
770 ////////////////////////////////////////////////////////////////////
771 TypedWritable *PaletteGroup::
772 make_PaletteGroup(const FactoryParams &params) {
773  PaletteGroup *me = new PaletteGroup;
774  DatagramIterator scan;
775  BamReader *manager;
776 
777  parse_params(params, scan, manager);
778  me->fillin(scan, manager);
779  manager->register_finalize(me);
780  return me;
781 }
782 
783 ////////////////////////////////////////////////////////////////////
784 // Function: PaletteGroup::fillin
785 // Access: Protected
786 // Description: Reads the binary data from the given datagram
787 // iterator, which was written by a previous call to
788 // write_datagram().
789 ////////////////////////////////////////////////////////////////////
790 void PaletteGroup::
791 fillin(DatagramIterator &scan, BamReader *manager) {
792  TypedWritable::fillin(scan, manager);
793  set_name(scan.get_string());
794  _dirname = scan.get_string();
795  _dependent.fillin(scan, manager);
796 
797  _dependency_level = scan.get_int32();
798  _dependency_order = scan.get_int32();
799  _dirname_order = scan.get_int32();
800 
801  _num_placements = scan.get_uint32();
802  manager->read_pointers(scan, _num_placements);
803 
804  _num_pages = scan.get_uint32();
805  manager->read_pointers(scan, _num_pages);
806 
807  if(Palettizer::_read_pi_version >= 19) {
808  _has_margin_override = scan.get_bool();
809  _margin_override = scan.get_int16();
810  }
811 }
812 
813 ////////////////////////////////////////////////////////////////////
814 // Function: PaletteGroup::add_texture_swap_info
815 // Access: Public
816 // Description: Store textureswap information from textures.txa
817 ////////////////////////////////////////////////////////////////////
818 void PaletteGroup::
819 add_texture_swap_info(const string sourceTextureName, const vector_string &swapTextures) {
820  TextureSwapInfo::iterator tsi = _textureSwapInfo.find(sourceTextureName);
821  if (tsi != _textureSwapInfo.end()) {
822  _textureSwapInfo.erase(tsi);
823  }
824  _textureSwapInfo.insert(TextureSwapInfo::value_type(sourceTextureName, swapTextures));
825 }
826 
827 ////////////////////////////////////////////////////////////////////
828 // Function: PaletteGroup::is_none_texture_swap
829 // Access: Public
830 // Description: Returns textureswap information is set or not,
831 // True if it's not set.
832 ////////////////////////////////////////////////////////////////////
833 bool PaletteGroup::
835  return _textureSwapInfo.empty();
836 }
void setup_shadow_images()
Ensures that each PaletteImage&#39;s _shadow_image has the correct filename and image types...
string get_dirname() const
Returns the directory part of the filename.
Definition: filename.I:424
int get_y_size() const
Returns the size in the Y dimension, in pixels, of the texture image as it must appear in the palette...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function&#39;s job is to store...
void write_image_info(ostream &out, int indent_level=0) const
Writes a list of the PaletteImages associated with this group, and all of their textures, to the indicated output stream.
void update_unknown_textures(const TxaFile &txa_file)
Checks for new information on any textures within the group for which some of the saved information i...
iterator end() const
Returns an iterator suitable for traversing the set.
bool determine_size()
Attempts to determine the appropriate size of the texture for the given placement.
bool get_bool()
Extracts a boolean value.
void add_string(const string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:351
void pre_txa_file()
Updates any internal state prior to reading the .txa file.
void optimal_resize()
Attempts to resize each PalettteImage down to its smallest possible size.
void place_all()
Once all the textures have been assigned to this group, try to place them all onto suitable PaletteIm...
int get_alpha_file_channel() const
Returns the particular channel number of the alpha image file from which the alpha channel should be ...
Definition: imageFile.cxx:291
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object, in preparation for writing to a Bam file.
PaletteGroup * get_group() const
Returns the group that this placement represents.
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
SourceTextureImage * get_source(const Filename &filename, const Filename &alpha_filename, int alpha_file_channel)
Returns the SourceTextureImage corresponding to the given filename(s).
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
iterator begin() const
Returns an iterator suitable for traversing the set.
This is the highest level of grouping for TextureImages.
Definition: paletteGroup.h:47
void unplace(TexturePlacement *placement)
Removes the texture from its position on a PaletteImage, if it has been so placed.
void fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
void place_all()
Assigns all the textures to their final home in a PaletteImage somewhere.
Definition: palettePage.cxx:96
void clear()
Empties the set.
void setup_shadow_images()
Ensures that each PaletteImage&#39;s _shadow_image has the correct filename and image types...
double get_uv_area() const
Returns the total area of the rectangle occupied by the UV minmax box, in UV coordinates.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
void group_with(PaletteGroup *other)
Indicates a dependency of this group on some other group.
PN_int32 get_int32()
Extracts a signed 32-bit integer.
This is a particular collection of textures, within a PaletteGroup, that all share the same TexturePr...
Definition: palettePage.h:37
void add_texture_swap_info(const string sourceTextureName, const vector_string &swapTextures)
Store textureswap information from textures.txa.
PN_uint32 get_uint32()
Extracts an unsigned 32-bit integer.
string get_extension() const
Returns the file extension.
Definition: filename.I:477
bool has_margin_override() const
Returns the set of groups this group depends on.
PN_int16 get_int16()
Extracts a signed 16-bit integer.
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&#39;s make_from_bam() method to read in all...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
bool is_none_texture_swap() const
Returns textureswap information is set or not, True if it&#39;s not set.
SourceTextureImage * get_preferred_source()
Determines the preferred source image for examining size and reading pixels, etc. ...
void reset_dependency_level()
Unconditionally sets the dependency level and order of this group to zero, in preparation for a later...
void add_int16(PN_int16 value)
Adds a signed 16-bit integer to the datagram.
Definition: datagram.I:148
int get_dirname_order() const
Returns the dependency order of this group.
void unplace(TexturePlacement *placement)
Removes the TexturePlacement from wherever it has been placed.
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:118
bool is_size_known() const
Returns true if the texture&#39;s size is known, false otherwise.
void write_image_info(ostream &out, int indent_level=0) const
Writes a list of the PaletteImages associated with this page, and all of their textures, to the indicated output stream.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
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()...
void update_images(bool redo_all)
Regenerates each PaletteImage on this page that needs it.
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
Definition: bamReader.cxx:700
const TextureProperties & get_properties() const
Returns the grouping properties of the image.
An STL function object class, this is intended to be used on any ordered collection of pointers to cl...
void assign(TexturePlacement *placement)
Adds the indicated texture to the list of textures to consider placing on the page.
Definition: palettePage.cxx:84
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
const string & get_dirname() const
Returns the directory name associated with the palette group.
PalettePage * get_page() const
Returns the particular PalettePage on which the texture has been placed.
void optimal_resize()
Attempts to resize each PalettteImage down to its smallest possible size.
This corresponds to a particular assignment of a TextureImage with a PaletteGroup, and specifically describes which PaletteImage (if any), and where on the PaletteImage, the TextureImage has been assigned to.
This is a texture image reference as it appears in an egg file: the source image of the texture...
void update_images(bool redo_all)
Regenerates each PaletteImage on this group that needs it.
int get_dependency_level() const
Returns the dependency level of this group.
void register_finalize(TypedWritable *whom)
Should be called by an object reading itself from the Bam file to indicate that this particular objec...
Definition: bamReader.cxx:886
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function&#39;s job is to store...
OmitReason get_omit_reason() const
Returns the reason the texture has been omitted from a palette image, or OR_none if it has not...
void set_dependency_level(int level)
Sets the dependency level of this group to the indicated level, provided that level is not lower than...
PalettePage * get_page(const TextureProperties &properties)
Returns the page associated with the indicated properties.
void make_complete(const PaletteGroups &a)
Completes the set with the transitive closure of all dependencies: for each PaletteGroup already in t...
const Filename & get_alpha_filename() const
Returns the alpha filename of the image file.
Definition: imageFile.cxx:276
void set_dirname(const string &dirname)
Sets the directory name associated with the palette group.
void reset_images()
Throws away all of the current PaletteImages, so that new ones may be created (and the packing made m...
bool set_dependency_order()
Updates the dependency order of this group.
TextureImage * get_texture() const
Returns the texture that this placement represents.
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:213
void reset_images()
Throws away all of the current PaletteImages, so that new ones may be created (and the packing made m...
int get_x_size() const
Returns the size in the X dimension, in pixels, of the texture image as it must appear in the palette...
void add_uint32(PN_uint32 value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:192
A set of PaletteGroups.
Definition: paletteGroups.h:31
bool has_dirname() const
Returns true if the directory name has been explicitly set for this group.
void increment_egg_count()
Increments by one the number of egg files that are known to reference this PaletteGroup.
bool is_preferred_over(const PaletteGroup &other) const
Returns true if this group should be preferred for adding textures over the other group...
virtual void finalize(BamReader *manager)
This method is called by the BamReader after all pointers everywhere in the world have been completel...
TexturePlacement * prepare(TextureImage *texture)
Marks the indicated Texture as ready for placing somewhere within this group, and returns a placehold...
void add_int32(PN_int32 value)
Adds a signed 32-bit integer to the datagram.
Definition: datagram.I:159
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:51
bool got_txa_file() const
Returns true if this TextureImage has been looked up in the .txa file this session, false otherwise.
void post_txa_file()
Once the .txa file has been read and the TextureImage matched against it, considers applying the requ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object, in preparation for writing to a Bam file.
const Filename & get_filename() const
Returns the primary filename of the image file.
Definition: imageFile.cxx:263
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
TextureImage * get_texture(const string &name)
Returns the TextureImage with the given name.
Definition: palettizer.cxx:902
const PaletteGroups & get_groups() const
Returns the set of groups this group depends on.
int get_egg_count() const
Returns the number of egg files that share this PaletteGroup.
void get_complete_placements(pvector< TexturePlacement *> &placements) const
Adds the set of TexturePlacements associated with this group and all dependent groups to the indicate...
void clear_depends()
Eliminates all the dependency information for this group.
void get_placements(pvector< TexturePlacement *> &placements) const
Adds the set of TexturePlacements associated with this group to the indicated vector.
int get_dependency_order() const
Returns the dependency order of this group.
This represents the .txa file (usually textures.txa) that contains the user instructions for resizing...
Definition: txaFile.h:33
bool is_placed() const
Returns true if the texture has been placed on a palette image, false otherwise.
int get_margin_override() const
Returns the set of groups this group depends on.
bool match_texture(TextureImage *texture) const
Searches for a matching line in the .txa file for the given texture and applies its specifications...
Definition: txaFile.cxx:158
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:279
void set_margin_override(const int override)
Returns the set of groups this group depends on.
const TextureProperties & get_properties() const
Returns the texture grouping properties that all textures in this page share.
Definition: palettePage.cxx:73
This is the set of characteristics of a texture that, if different from another texture, prevent the two textures from sharing a PaletteImage.