Panda3D
palettePage.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 palettePage.cxx
10  * @author drose
11  * @date 2000-12-01
12  */
13 
14 #include "palettePage.h"
15 #include "texturePlacement.h"
16 #include "textureImage.h"
17 #include "paletteImage.h"
18 #include "paletteGroup.h"
19 
20 #include "indent.h"
21 #include "datagram.h"
22 #include "datagramIterator.h"
23 #include "bamReader.h"
24 #include "bamWriter.h"
25 
26 #include <algorithm>
27 
28 TypeHandle PalettePage::_type_handle;
29 
30 /**
31  * The default constructor is only for the convenience of the Bam reader.
32  */
33 PalettePage::
34 PalettePage() {
35  _group = nullptr;
36 }
37 
38 /**
39  *
40  */
41 PalettePage::
42 PalettePage(PaletteGroup *group, const TextureProperties &properties) :
43  Namable(properties.get_string()),
44  _group(group),
45  _properties(properties)
46 {
47 }
48 
49 /**
50  * Returns the group this particular PalettePage belongs to.
51  */
53 get_group() const {
54  return _group;
55 }
56 
57 /**
58  * Returns the texture grouping properties that all textures in this page
59  * share.
60  */
62 get_properties() const {
63  return _properties;
64 }
65 
66 /**
67  * Adds the indicated texture to the list of textures to consider placing on
68  * the page.
69  */
70 void PalettePage::
71 assign(TexturePlacement *placement) {
72  _assigned.push_back(placement);
73 }
74 
75 
76 /**
77  * Assigns all the textures to their final home in a PaletteImage somewhere.
78  */
79 void PalettePage::
81  // Sort the textures to be placed in order from biggest to smallest, as an
82  // aid to optimal packing.
83  sort(_assigned.begin(), _assigned.end(), SortPlacementBySize());
84 
85  Assigned::const_iterator ai;
86  for (ai = _assigned.begin(); ai != _assigned.end(); ++ai) {
87  TexturePlacement *placement = (*ai);
88  place(placement);
89  }
90 
91  _assigned.clear();
92 
93  // Now, look for solitary images; these are left placed, but flagged with
94  // OR_solitary, so they won't go into egg references. There's no real point
95  // in referencing these.
96  Images::iterator ii;
97  for (ii = _images.begin(); ii != _images.end(); ++ii) {
98  PaletteImage *image = (*ii);
99  image->check_solitary();
100  }
101 }
102 
103 /**
104  * Assigns the particular TexturePlacement to a PaletteImage where it fits.
105  */
106 void PalettePage::
107 place(TexturePlacement *placement) {
108  nassertv(placement->get_omit_reason() == OR_working);
109 
110  // First, try to place it in one of our existing PaletteImages.
111  Images::iterator ii;
112  for (ii = _images.begin(); ii != _images.end(); ++ii) {
113  PaletteImage *image = (*ii);
114  if (image->place(placement)) {
115  return;
116  }
117  }
118 
119  // No good? Then we need to create a new PaletteImage for it.
120  PaletteImage *image = new PaletteImage(this, _images.size());
121  _images.push_back(image);
122 
123  bool placed = image->place(placement);
124 
125  // This should have stuck.
126  nassertv(placed);
127 }
128 
129 
130 /**
131  * Removes the TexturePlacement from wherever it has been placed.
132  */
133 void PalettePage::
135  nassertv(placement->is_placed() && placement->get_page() == this);
136  placement->get_image()->unplace(placement);
137 }
138 
139 /**
140  * Writes a list of the PaletteImages associated with this page, and all of
141  * their textures, to the indicated output stream.
142  */
143 void PalettePage::
144 write_image_info(std::ostream &out, int indent_level) const {
145  Images::const_iterator ii;
146  for (ii = _images.begin(); ii != _images.end(); ++ii) {
147  PaletteImage *image = (*ii);
148  if (!image->is_empty()) {
149  indent(out, indent_level);
150  image->output_filename(out);
151  out << "\n";
152  image->write_placements(out, indent_level + 2);
153  }
154  }
155 }
156 
157 /**
158  * Attempts to resize each PalettteImage down to its smallest possible size.
159  */
160 void PalettePage::
162  Images::iterator ii;
163  for (ii = _images.begin(); ii != _images.end(); ++ii) {
164  PaletteImage *image = (*ii);
165  image->optimal_resize();
166  }
167 }
168 
169 /**
170  * Throws away all of the current PaletteImages, so that new ones may be
171  * created (and the packing made more optimal).
172  */
173 void PalettePage::
175  Images::iterator ii;
176  for (ii = _images.begin(); ii != _images.end(); ++ii) {
177  PaletteImage *image = (*ii);
178  image->reset_image();
179  delete image;
180  }
181 
182  _images.clear();
183 }
184 
185 /**
186  * Ensures that each PaletteImage's _shadow_image has the correct filename and
187  * image types, based on what was supplied on the command line and in the .txa
188  * file.
189  */
190 void PalettePage::
192  Images::iterator ii;
193  for (ii = _images.begin(); ii != _images.end(); ++ii) {
194  PaletteImage *image = (*ii);
195  image->setup_shadow_image();
196  }
197 }
198 
199 /**
200  * Regenerates each PaletteImage on this page that needs it.
201  */
202 void PalettePage::
203 update_images(bool redo_all) {
204  Images::iterator ii;
205  for (ii = _images.begin(); ii != _images.end(); ++ii) {
206  PaletteImage *image = (*ii);
207  image->update_image(redo_all);
208  }
209 }
210 
211 /**
212  * Registers the current object as something that can be read from a Bam file.
213  */
214 void PalettePage::
217  register_factory(get_class_type(), make_PalettePage);
218 }
219 
220 /**
221  * Fills the indicated datagram up with a binary representation of the current
222  * object, in preparation for writing to a Bam file.
223  */
224 void PalettePage::
225 write_datagram(BamWriter *writer, Datagram &datagram) {
226  TypedWritable::write_datagram(writer, datagram);
227  datagram.add_string(get_name());
228 
229  writer->write_pointer(datagram, _group);
230  _properties.write_datagram(writer, datagram);
231 
232  // We don't write out _assigned, since that's rebuilt each session.
233 
234  datagram.add_uint32(_images.size());
235  Images::const_iterator ii;
236  for (ii = _images.begin(); ii != _images.end(); ++ii) {
237  writer->write_pointer(datagram, *ii);
238  }
239 }
240 
241 /**
242  * Called after the object is otherwise completely read from a Bam file, this
243  * function's job is to store the pointers that were retrieved from the Bam
244  * file for each pointer object written. The return value is the number of
245  * pointers processed from the list.
246  */
247 int PalettePage::
249  int pi = TypedWritable::complete_pointers(p_list, manager);
250 
251  if (p_list[pi] != nullptr) {
252  DCAST_INTO_R(_group, p_list[pi], pi);
253  }
254  pi++;
255 
256  pi += _properties.complete_pointers(p_list + pi, manager);
257 
258  int i;
259  _images.reserve(_num_images);
260  for (i = 0; i < _num_images; i++) {
261  PaletteImage *image;
262  DCAST_INTO_R(image, p_list[pi++], pi);
263  _images.push_back(image);
264  }
265 
266  return pi;
267 }
268 
269 /**
270  * This method is called by the BamReader when an object of this type is
271  * encountered in a Bam file; it should allocate and return a new object with
272  * all the data read.
273  */
274 TypedWritable* PalettePage::
275 make_PalettePage(const FactoryParams &params) {
276  PalettePage *me = new PalettePage;
277  DatagramIterator scan;
278  BamReader *manager;
279 
280  parse_params(params, scan, manager);
281  me->fillin(scan, manager);
282  return me;
283 }
284 
285 /**
286  * Reads the binary data from the given datagram iterator, which was written
287  * by a previous call to write_datagram().
288  */
289 void PalettePage::
290 fillin(DatagramIterator &scan, BamReader *manager) {
291  TypedWritable::fillin(scan, manager);
292  set_name(scan.get_string());
293 
294  manager->read_pointer(scan); // _group
295  _properties.fillin(scan, manager);
296 
297  _num_images = scan.get_uint32();
298  manager->read_pointers(scan, _num_images);
299 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_empty() const
Returns true if there are no textures, or only one "solitary" texture, placed on the image.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PaletteImage * get_image() const
Returns the particular PaletteImage on which the texture has been placed.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
This is the highest level of grouping for TextureImages.
Definition: paletteGroup.h:43
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 output_filename(std::ostream &out) const
Writes the filename (or pair of filenames) to the indicated output stream.
Definition: imageFile.cxx:424
void place_all()
Assigns all the textures to their final home in a PaletteImage somewhere.
Definition: palettePage.cxx:80
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
void setup_shadow_images()
Ensures that each PaletteImage'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:63
void place(TexturePlacement *placement)
Assigns the particular TexturePlacement to a PaletteImage where it fits.
This is a particular collection of textures, within a PaletteGroup, that all share the same TexturePr...
Definition: palettePage.h:33
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...
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 add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:94
bool place(TexturePlacement *placement)
Attempts to place the indicated texture on the image.
void unplace(TexturePlacement *placement)
Removes the TexturePlacement from wherever it has been placed.
void optimal_resize()
Attempts to resize the palette image to as small as it can go.
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
A base class for all things which can have a name.
Definition: namable.h:26
void check_solitary()
To be called after all textures have been placed on the image, this checks to see if there is only on...
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().
void update_images(bool redo_all)
Regenerates each PaletteImage on this page that needs it.
void write_placements(std::ostream &out, int indent_level=0) const
Writes a list of the textures that have been placed on this image to the indicated output stream,...
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
void reset_image()
Unpacks each texture that has been placed on this image, resetting the image to empty.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
PaletteGroup * get_group() const
Returns the group this particular PalettePage belongs to.
Definition: palettePage.cxx:53
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
Definition: bamReader.cxx:653
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
void assign(TexturePlacement *placement)
Adds the indicated texture to the list of textures to consider placing on the page.
Definition: palettePage.cxx:71
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.
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,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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 fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
void reset_images()
Throws away all of the current PaletteImages, so that new ones may be created (and the packing made m...
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:610
void setup_shadow_image()
Ensures the _shadow_image has the correct filename and image types, based on what was supplied on the...
This is a single palette image, one of several within a PalettePage, which is in turn one of several ...
Definition: paletteImage.h:32
void unplace(TexturePlacement *placement)
Removes the texture from the image.
A class to retrieve the individual data elements previously stored in a Datagram.
void update_image(bool redo_all)
If the palette has changed since it was last written out, updates the image and writes out a new one.
void write_image_info(std::ostream &out, int indent_level=0) const
Writes a list of the PaletteImages associated with this page, and all of their textures,...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_placed() const
Returns true if the texture has been placed on a palette image, false otherwise.
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
const TextureProperties & get_properties() const
Returns the texture grouping properties that all textures in this page share.
Definition: palettePage.cxx:62
This is the set of characteristics of a texture that, if different from another texture,...