Panda3D
 All Classes Functions Variables Enumerations
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...
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...
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 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...
bool has_margin_override() const
Returns the set of groups this group depends on.
bool determine_size()
Attempts to determine the appropriate size of the texture for the given placement.
const PaletteGroups & get_groups() const
Returns the set of groups this group depends on.
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.
bool got_txa_file() const
Returns true if this TextureImage has been looked up in the .txa file this session, false otherwise.
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...
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.
const Filename & get_alpha_filename() const
Returns the alpha filename of the image file.
Definition: imageFile.cxx:276
bool is_placed() const
Returns true if the texture has been placed on a palette image, false otherwise.
static void register_with_read_factory()
Registers the current object as something that can be read from 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_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
This is the highest level of grouping for TextureImages.
Definition: paletteGroup.h:47
iterator end() const
Returns an iterator suitable for traversing the set.
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
void unplace(TexturePlacement *placement)
Removes the texture from its position on a PaletteImage, if it has been so placed.
int get_dirname_order() const
Returns the dependency order of this group.
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...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
string get_dirname() const
Returns the directory part of the filename.
Definition: filename.I:424
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.
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.
PN_int16 get_int16()
Extracts a signed 16-bit integer.
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...
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.
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
bool is_preferred_over(const PaletteGroup &other) const
Returns true if this group should be preferred for adding textures over the other 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
const TextureProperties & get_properties() const
Returns the grouping properties of the image.
OmitReason get_omit_reason() const
Returns the reason the texture has been omitted from a palette image, or OR_none if it has not...
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-&gt;read_pointer() was called in fillin()...
void update_images(bool redo_all)
Regenerates each PaletteImage on this page that needs it.
const Filename & get_filename() const
Returns the primary filename of the image file.
Definition: imageFile.cxx:263
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
Definition: bamReader.cxx:694
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
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...
int get_margin_override() const
Returns the set of groups this group depends on.
void update_images(bool redo_all)
Regenerates each PaletteImage on this group that needs it.
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:880
int get_dependency_order() const
Returns the dependency order of this group.
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...
PalettePage * get_page() const
Returns the particular PalettePage on which the texture has been placed.
const TextureProperties & get_properties() const
Returns the texture grouping properties that all textures in this page share.
Definition: palettePage.cxx:73
PaletteGroup * get_group() const
Returns the group that this placement represents.
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...
void set_dirname(const string &dirname)
Sets the directory name associated with the palette group.
const string & get_dirname() const
Returns the directory name associated with the palette group.
int get_dependency_level() const
Returns the dependency level of this 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.
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...
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 add_uint32(PN_uint32 value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:192
bool is_size_known() const
Returns true if the texture&#39;s size is known, false otherwise.
A set of PaletteGroups.
Definition: paletteGroups.h:31
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.
void increment_egg_count()
Increments by one the number of egg files that are known to reference this PaletteGroup.
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
int get_egg_count() const
Returns the number of egg files that share this PaletteGroup.
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
TextureImage * get_texture() const
Returns the texture that this placement represents.
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.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
string get_extension() const
Returns the file extension.
Definition: filename.I:477
TextureImage * get_texture(const string &name)
Returns the TextureImage with the given name.
Definition: palettizer.cxx:902
bool has_dirname() const
Returns true if the directory name has been explicitly set for this group.
double get_uv_area() const
Returns the total area of the rectangle occupied by the UV minmax box, in UV coordinates.
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.
This represents the .txa file (usually textures.txa) that contains the user instructions for resizing...
Definition: txaFile.h:33
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.
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
iterator begin() const
Returns an iterator suitable for traversing the set.
This is the set of characteristics of a texture that, if different from another texture, prevent the two textures from sharing a PaletteImage.