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  */
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  */
80 place_all() {
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  */
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  */
134 unplace(TexturePlacement *placement) {
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  */
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  */
161 optimal_resize() {
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  */
174 reset_images() {
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  */
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  */
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  */
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  */
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  */
248 complete_pointers(TypedWritable **p_list, BamReader *manager) {
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.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
Definition: bamReader.cxx:653
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:610
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
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
A class to retrieve the individual data elements previously stored in a Datagram.
uint32_t get_uint32()
Extracts an unsigned 32-bit integer.
std::string get_string()
Extracts a variable-length string.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:94
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
void output_filename(std::ostream &out) const
Writes the filename (or pair of filenames) to the indicated output stream.
Definition: imageFile.cxx:424
A base class for all things which can have a name.
Definition: namable.h:26
This is the highest level of grouping for TextureImages.
Definition: paletteGroup.h:43
This is a single palette image, one of several within a PalettePage, which is in turn one of several ...
Definition: paletteImage.h:32
bool is_empty() const
Returns true if there are no textures, or only one "solitary" texture, placed on the image.
void unplace(TexturePlacement *placement)
Removes the texture from the image.
void reset_image()
Unpacks each texture that has been placed on this image, resetting the image to empty.
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 optimal_resize()
Attempts to resize the palette image to as small as it can go.
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,...
bool place(TexturePlacement *placement)
Attempts to place the indicated texture on the image.
void setup_shadow_image()
Ensures the _shadow_image has the correct filename and image types, based on what was supplied on the...
void check_solitary()
To be called after all textures have been placed on the image, this checks to see if there is only on...
This is a particular collection of textures, within a PaletteGroup, that all share the same TexturePr...
Definition: palettePage.h:33
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 optimal_resize()
Attempts to resize each PalettteImage down to its smallest possible size.
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
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,...
void setup_shadow_images()
Ensures that each PaletteImage's _shadow_image has the correct filename and image types,...
void update_images(bool redo_all)
Regenerates each PaletteImage on this page that needs it.
void unplace(TexturePlacement *placement)
Removes the TexturePlacement from wherever it has been placed.
const TextureProperties & get_properties() const
Returns the texture grouping properties that all textures in this page share.
Definition: palettePage.cxx:62
void place_all()
Assigns all the textures to their final home in a PaletteImage somewhere.
Definition: palettePage.cxx:80
void reset_images()
Throws away all of the current PaletteImages, so that new ones may be created (and the packing made m...
void assign(TexturePlacement *placement)
Adds the indicated texture to the list of textures to consider placing on the page.
Definition: palettePage.cxx:71
PaletteGroup * get_group() const
Returns the group this particular PalettePage belongs to.
Definition: palettePage.cxx:53
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
void place(TexturePlacement *placement)
Assigns the particular TexturePlacement to a PaletteImage where it fits.
This corresponds to a particular assignment of a TextureImage with a PaletteGroup,...
OmitReason get_omit_reason() const
Returns the reason the texture has been omitted from a palette image, or OR_none if it has not.
PaletteImage * get_image() const
Returns the particular PaletteImage on which the texture has been placed.
bool is_placed() const
Returns true if the texture has been placed on a palette image, false otherwise.
PalettePage * get_page() const
Returns the particular PalettePage on which the texture has been placed.
This is the set of characteristics of a texture that, if different from another texture,...
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 fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
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.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.