Go to the documentation of this file.
47 _omit_reason = OR_none;
58 _omit_reason = OR_working;
63 _omit_reason = OR_unknown;
79 References::iterator ri;
80 References copy_references = _references;
81 for (ri = copy_references.begin(); ri != copy_references.end(); ++ri) {
96 return _texture->get_name();
137 _references.insert(reference);
151 _references.erase(reference);
160 References::iterator ri;
161 for (ri = _references.begin(); ri != _references.end(); ++ri) {
200 _omit_reason = OR_unknown;
218 _position._wrap_u = EggTexture::WM_clamp;
219 _position._wrap_v = EggTexture::WM_clamp;
221 LTexCoordd max_uv, min_uv;
223 References::iterator ri;
224 for (ri = _references.begin(); ri != _references.end(); ++ri) {
227 const LTexCoordd &n = reference->
get_min_uv();
228 const LTexCoordd &x = reference->
get_max_uv();
231 min_uv.set(min(min_uv[0], n[0]), min(min_uv[1], n[1]));
232 max_uv.set(max(max_uv[0], x[0]), max(max_uv[1], x[1]));
242 if (reference->
get_wrap_u() == EggTexture::WM_repeat) {
243 _position._wrap_u = EggTexture::WM_repeat;
245 if (reference->
get_wrap_v() == EggTexture::WM_repeat) {
246 _position._wrap_v = EggTexture::WM_repeat;
260 _omit_reason = OR_unused;
264 LTexCoordd rounded_min_uv = min_uv;
265 LTexCoordd rounded_max_uv = max_uv;
275 if (pal->_round_uvs) {
277 ceil((rounded_max_uv[0] - pal->_round_fuzz) / pal->_round_unit) *
280 ceil((rounded_max_uv[1] - pal->_round_fuzz) / pal->_round_unit) *
284 floor((rounded_min_uv[0] + pal->_round_fuzz) / pal->_round_unit) *
287 floor((rounded_min_uv[1] + pal->_round_fuzz) / pal->_round_unit) *
296 compute_size_from_uvs(rounded_min_uv, rounded_max_uv);
302 _omit_reason = OR_omitted;
307 _omit_reason = OR_coverage;
309 }
else if ((_position._x_size > pal->_pal_x_size ||
310 _position._y_size > pal->_pal_y_size) ||
311 (_position._x_size == pal->_pal_x_size &&
312 _position._y_size == pal->_pal_y_size)) {
317 _omit_reason = OR_size;
322 _omit_reason = OR_default_omit;
324 }
else if (_omit_reason == OR_omitted ||
325 _omit_reason == OR_default_omit ||
326 _omit_reason == OR_size ||
327 _omit_reason == OR_coverage ||
328 _omit_reason == OR_unknown) {
333 _omit_reason = OR_working;
339 if (_position._x_size != _placed._x_size ||
340 _position._y_size != _placed._y_size ||
341 _position._min_uv[0] < _placed._min_uv[0] ||
342 _position._min_uv[1] < _placed._min_uv[1] ||
343 _position._max_uv[0] > _placed._max_uv[0] ||
344 _position._max_uv[1] > _placed._max_uv[1]) {
351 if ((_position._x_size > _placed._x_size ||
352 _position._y_size > _placed._y_size) &&
354 compute_size_from_uvs(min_uv, max_uv);
355 if (_position._x_size <= _placed._x_size &&
356 _position._y_size <= _placed._y_size &&
357 _position._min_uv[0] >= _placed._min_uv[0] &&
358 _position._min_uv[1] >= _placed._min_uv[1] &&
359 _position._max_uv[0] <= _placed._max_uv[0] &&
360 _position._max_uv[1] <= _placed._max_uv[1]) {
364 compute_size_from_uvs(rounded_min_uv, rounded_max_uv);
372 if (_position._wrap_u != _placed._wrap_u ||
373 _position._wrap_v != _placed._wrap_v) {
377 _placed._wrap_u = _position._wrap_u;
378 _placed._wrap_v = _position._wrap_v;
412 nassertr(_size_known, 0);
413 return _position._x_size;
423 nassertr(_size_known, 0);
424 return _position._y_size;
438 LTexCoordd range = _position._max_uv - _position._min_uv;
439 return range[0] * range[1];
449 return _image !=
nullptr;
497 return _placed._x_size;
507 return _placed._y_size;
517 LTexCoordd range = _placed._max_uv - _placed._min_uv;
518 return range[0] * range[1];
529 nassertv(_size_known);
536 _omit_reason = OR_none;
546 if (_image !=
nullptr) {
550 if (_omit_reason == OR_none) {
553 _omit_reason = OR_working;
565 if (_omit_reason != OR_solitary) {
567 _omit_reason = OR_solitary;
578 if (_omit_reason != OR_none) {
580 _omit_reason = OR_none;
590 intersects(
int x,
int y,
int x_size,
int y_size) {
593 int hright = x + x_size;
594 int hbot = y + y_size;
596 int mright = _placed._x + _placed._x_size;
597 int mbot = _placed._y + _placed._y_size;
599 return !(x >= mright || hright <= _placed._x ||
600 y >= mbot || hbot <= _placed._y);
611 LMatrix3d source_uvs = LMatrix3d::ident_mat();
613 LTexCoordd range = _placed._max_uv - _placed._min_uv;
614 if (range[0] != 0.0 && range[1] != 0.0) {
616 LMatrix3d::translate_mat(-_placed._min_uv) *
617 LMatrix3d::scale_mat(1.0 / range[0], 1.0 / range[1]);
620 int top = _placed._y + _placed._margin;
621 int left = _placed._x + _placed._margin;
622 int x_size = _placed._x_size - _placed._margin * 2;
623 int y_size = _placed._y_size - _placed._margin * 2;
625 int bottom = top + y_size;
629 LVecBase2d t((
double)left / (
double)pal_x_size,
630 (
double)(pal_y_size - bottom) / (
double)pal_y_size);
631 LVecBase2d s((
double)x_size / (
double)pal_x_size,
632 (
double)y_size / (
double)pal_y_size);
639 transform = source_uvs * dest_uvs;
657 if (_placed._wrap_u != EggTexture::WM_unspecified ||
658 _placed._wrap_v != EggTexture::WM_unspecified) {
659 if (_placed._wrap_u != _placed._wrap_v) {
660 out <<
" (" << _placed._wrap_u <<
", " << _placed._wrap_v <<
")";
662 out <<
" " << _placed._wrap_u;
667 out <<
" not yet placed.\n";
706 LTexCoordd ul = LTexCoordd(0.0, 1.0) * transform;
707 LTexCoordd lr = LTexCoordd(1.0, 0.0) * transform;
713 int top = (int)floor((1.0 - ul[1]) * pal_y_size + 0.5);
714 int left = (int)floor(ul[0] * pal_x_size + 0.5);
715 int bottom = (int)floor((1.0 - lr[1]) * pal_y_size + 0.5);
716 int right = (int)floor(lr[0] * pal_x_size + 0.5);
720 int x_size = right - left;
721 int y_size = bottom - top;
722 nassertv(x_size >= 0 && y_size >= 0);
743 for (
int y = _placed._y; y < _placed._y + _placed._y_size; y++) {
746 switch (_placed._wrap_v) {
747 case EggTexture::WM_clamp:
749 sy = max(min(sy, y_size - 1), 0);
752 case EggTexture::WM_mirror:
753 sy = (sy < 0) ? (y_size * 2) - 1 - ((-sy - 1) % (y_size * 2)) : sy % (y_size * 2);
754 sy = (sy < y_size) ? sy : 2 * y_size - sy - 1;
757 case EggTexture::WM_mirror_once:
758 sy = (sy < y_size) ? sy : 2 * y_size - sy - 1;
761 case EggTexture::WM_border_color:
762 if (sy < 0 || sy >= y_size) {
769 sy = (sy < 0) ? y_size - 1 - ((-sy - 1) % y_size) : sy % y_size;
773 for (
int x = _placed._x; x < _placed._x + _placed._x_size; x++) {
776 switch (_placed._wrap_u) {
777 case EggTexture::WM_clamp:
779 sx = max(min(sx, x_size - 1), 0);
782 case EggTexture::WM_mirror:
783 sx = (sx < 0) ? (x_size * 2) - 1 - ((-sx - 1) % (x_size * 2)) : sx % (x_size * 2);
784 sx = (sx < x_size) ? sx : 2 * x_size - sx - 1;
787 case EggTexture::WM_mirror_once:
788 sx = (sx >= 0) ? sx : ~sx;
791 case EggTexture::WM_border_color:
792 if (sx < 0 || sx >= x_size) {
799 sx = (sx < 0) ? x_size - 1 - ((-sx - 1) % x_size) : sx % x_size;
835 LTexCoordd ul = LTexCoordd(0.0, 1.0) * transform;
836 LTexCoordd lr = LTexCoordd(1.0, 0.0) * transform;
842 int top = (int)floor((1.0 - ul[1]) * pal_y_size + 0.5);
843 int left = (int)floor(ul[0] * pal_x_size + 0.5);
844 int bottom = (int)floor((1.0 - lr[1]) * pal_y_size + 0.5);
845 int right = (int)floor(lr[0] * pal_x_size + 0.5);
849 int x_size = right - left;
850 int y_size = bottom - top;
851 nassertv(x_size >= 0 && y_size >= 0);
854 TextureSwaps::iterator tsi;
855 tsi = _textureSwaps.begin() + index;
875 for (
int y = _placed._y; y < _placed._y + _placed._y_size; y++) {
878 if (_placed._wrap_v == EggTexture::WM_clamp) {
880 sy = max(min(sy, y_size - 1), 0);
884 sy = (sy < 0) ? y_size - 1 - ((-sy - 1) % y_size) : sy % y_size;
887 for (
int x = _placed._x; x < _placed._x + _placed._x_size; x++) {
890 if (_placed._wrap_u == EggTexture::WM_clamp) {
892 sx = max(min(sx, x_size - 1), 0);
896 sx = (sx < 0) ? x_size - 1 - ((-sx - 1) % x_size) : sx % x_size;
920 for (
int y = _placed._y; y < _placed._y + _placed._y_size; y++) {
921 for (
int x = _placed._x; x < _placed._x + _placed._x_size; x++) {
926 for (
int y = _placed._y; y < _placed._y + _placed._y_size; y++) {
927 for (
int x = _placed._x; x < _placed._x + _placed._x_size; x++) {
939 void TexturePlacement::
940 compute_size_from_uvs(
const LTexCoordd &min_uv,
const LTexCoordd &max_uv) {
941 _position._min_uv = min_uv;
942 _position._max_uv = max_uv;
944 LTexCoordd range = _position._max_uv - _position._min_uv;
950 _position._x_size = (int)floor(_texture->
get_x_size() * range[0] + 0.5);
951 _position._y_size = (int)floor(_texture->
get_y_size() * range[1] + 0.5);
958 _position._x_size = max(_position._x_size, 4);
959 _position._y_size = max(_position._y_size, 4);
972 if ((
double)_position._margin / (
double)_position._x_size > 0.10) {
973 _position._x_size += _position._margin * 2;
975 if ((
double)_position._margin / (
double)_position._y_size > 0.10) {
976 _position._y_size += _position._margin * 2;
990 register_factory(get_class_type(), make_TexturePlacement);
1014 References::const_iterator ri;
1015 for (ri = _references.begin(); ri != _references.end(); ++ri) {
1019 datagram.
add_int32(_textureSwaps.size());
1020 TextureSwaps::const_iterator tsi;
1021 for (tsi = _textureSwaps.begin(); tsi != _textureSwaps.end(); ++tsi) {
1037 if (p_list[index] !=
nullptr) {
1038 DCAST_INTO_R(_texture, p_list[index], index);
1042 if (p_list[index] !=
nullptr) {
1043 DCAST_INTO_R(_group, p_list[index], index);
1047 if (p_list[index] !=
nullptr) {
1048 DCAST_INTO_R(_image, p_list[index], index);
1052 if (p_list[index] !=
nullptr) {
1053 DCAST_INTO_R(_dest, p_list[index], index);
1058 for (i = 0; i < _num_references; i++) {
1060 DCAST_INTO_R(reference, p_list[index], index);
1061 _references.insert(reference);
1065 for (i = 0; i < _num_textureSwaps; i++) {
1067 DCAST_INTO_R(swapTexture, p_list[index], index);
1068 _textureSwaps.push_back(swapTexture);
1087 me->fillin(scan, manager);
1095 void TexturePlacement::
1106 _position.
fillin(scan, manager);
1109 _placed.
fillin(scan, manager);
1115 if (Palettizer::_read_pi_version >= 20) {
1118 _num_textureSwaps = 0;
bool is_size_known() const
Returns true if the texture's size is known, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void unplace(TexturePlacement *placement)
Removes the texture from the image.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
int get_y_size() const
Returns the size of the image file in pixels in the Y direction.
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
LRGBColorf get_xel(int x, int y) const
Returns the RGB color at the indicated pixel.
This is a single palette image, one of several within a PalettePage, which is in turn one of several ...
int32_t get_int32()
Extracts a signed 32-bit integer.
void set_dest(DestTextureImage *dest)
Sets the DestTextureImage that corresponds to this texture as it was copied to the install directory.
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...
This is the highest level of grouping for TextureImages.
void clear_placement()
Removes any reference to a TexturePlacement.
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
EggTexture::WrapMode get_wrap_v() const
Returns the specification for the wrapping in the V direction.
double get_coverage_threshold() const
Returns the appropriate coverage threshold for this texture.
void flag_error_image(PNMImage &image)
Sets the rectangle of the palette image represented by the texture placement to red,...
void set_xel_val(int x, int y, const xel &value)
Changes the RGB color at the indicated pixel.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const LTexCoordd & get_max_uv() const
Returns the maximum UV coordinate in use for the texture by this reference.
bool is_valid() const
Returns true if the image has been read in or correctly initialized with a height and width.
A class to retrieve the individual data elements previously stored in a Datagram.
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().
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
const std::string & get_name() const
Returns the name of the texture that this placement represents.
TexturePlacement * get_placement() const
Returns the particular TexturePlacement that is appropriate for this egg file.
void set_alpha(int x, int y, float a)
Sets the alpha component color only at the indicated pixel.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
void fill_swapped_image(PNMImage &image, int index)
Fills in the rectangle of the swapped palette image represented by the texture placement with the ima...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PalettePage * get_page() const
Returns the particular PalettePage this image is associated with.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
void force_replace()
Removes the texture from its particular PaletteImage, but does not remove it from the PaletteGroup.
void add_egg(TextureReference *reference)
Records the fact that a particular egg file is using this particular TexturePlacement.
const TextureProperties & get_properties() const
Returns the grouping properties of the image.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const PNMImage & read_source_image()
Reads in the original image, if it has not already been read, and returns it.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void quick_filter_from(const PNMImage ©, int xborder=0, int yborder=0)
Resizes from the given image, with a fixed radius of 0.5.
int get_placed_x_size() const
Returns the size in the X dimension, in pixels, of the texture image as it has been placed within the...
OmitReason
This enumerates the reasons why a texture may not have been placed in a palette image.
bool get_omit() const
Returns true if the user specifically requested to omit this texture via the "omit" keyword in the ....
TypeHandle is the identifier used to differentiate C++ class types.
double get_placed_uv_area() const
Returns the total area of the rectangle occupied by the UV minmax box, as it has been placed.
PalettePage * get_page() const
Returns the particular PalettePage on which the texture has been placed.
OmitReason get_omit_reason() const
Returns the reason the texture has been omitted from a palette image, or OR_none if it has not.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
bool get_bool()
Extracts a boolean value.
int get_margin_override() const
Returns the set of groups this group depends on.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
EggTexture::WrapMode get_wrap_u() const
Returns the specification for the wrapping in the U direction.
bool has_uvs() const
Returns true if this TextureReference actually uses the texture on geometry, with UV's and everything...
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...
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...
PaletteImage * get_image() const
Returns the particular PaletteImage on which the texture has been placed.
void compute_tex_matrix(LMatrix3d &transform)
Stores in the indicated matrix the appropriate texture matrix transform for the new placement of the ...
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const TextureProperties & get_properties() const
Returns the grouping properties of the image.
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 release_source_image()
Frees the memory that was allocated by a previous call to read_source_image().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void place_at(PaletteImage *image, int x, int y)
Assigns the texture to a particular position within the indicated PaletteImage.
bool intersects(int x, int y, int x_size, int y_size)
Returns true if the particular position this texture has been assigned to overlaps the rectangle whos...
void mark_unfilled()
Marks the texture as unfilled, so that it will need to be copied into the palette image again.
This is a particular collection of textures, within a PaletteGroup, that all share the same TexturePr...
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
int get_placed_y_size() const
Returns the size in the Y dimension, in pixels, of the texture image as it has been placed within the...
void write_placed(std::ostream &out, int indent_level=0)
Writes the placement position information on a line by itself.
TextureImage * get_texture() const
Returns the texture that this placement represents.
void remove_egg(TextureReference *reference)
Notes that a particular egg file is no longer using this particular TexturePlacement.
This is the set of characteristics of a texture that, if different from another texture,...
int get_placed_x() const
Returns the X pixel at which the texture has been placed within its PaletteImage.
void set_xel(int x, int y, const LRGBColorf &value)
Changes the RGB color at the indicated pixel.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
void set_alpha_val(int x, int y, xelval a)
Sets the alpha component color only at the indicated pixel.
bool is_filled() const
Returns true if the texture has been filled (i.e.
This corresponds to a particular assignment of a TextureImage with a PaletteGroup,...
EggTexture::WrapMode get_txa_wrap_u() const
Returns the wrap mode specified in the u direction in the txa file, or WM_unspecified.
void add_bool(bool value)
Adds a boolean value to the datagram.
float get_alpha(int x, int y) const
Returns the alpha component color at the indicated pixel.
EggTexture::WrapMode get_txa_wrap_v() const
Returns the wrap mode specified in the v direction in the txa file, or WM_unspecified.
bool is_size_known() const
Returns true if the size of the image file is known, false otherwise.
This is the particular reference of a texture filename by an egg file.
int get_x_size() const
Returns the size of the image file in pixels in the X direction.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void unplace(TexturePlacement *placement)
Removes the texture from its position on a PaletteImage, if it has been so placed.
PaletteGroup * get_group() const
Returns the group that this placement represents.
void fill_image(PNMImage &image)
Fills in the rectangle of the palette image represented by the texture placement with the image pixel...
double get_uv_area() const
Returns the total area of the rectangle occupied by the UV minmax box, in UV coordinates.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool operator()(TexturePlacement *a, TexturePlacement *b) const
Compares two TexturePlacement objects and returns true if the first one is bigger than the second one...
void mark_egg_stale()
Marks the egg file that shares this reference as stale.
DestTextureImage * get_dest() const
Returns the DestTextureImage that corresponds to this texture as it was copied to the install directo...
bool is_placed() const
Returns true if the texture has been placed on a palette image, false otherwise.
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...
void mark_eggs_stale()
Marks all the egg files that reference this placement stale.
int get_margin() const
Returns the appropriate margin for this texture.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This represents a texture filename as it has been resized and copied to the map directory (e....
bool is_none_texture_swap() const
Returns textureswap information is set or not, True if it's not set.
void omit_solitary()
Sets the omit reason (returned by get_omit()) to OR_solitary, indicating that the palettized version ...
const LTexCoordd & get_min_uv() const
Returns the minimum UV coordinate in use for the texture by this reference.
int get_placed_y() const
Returns the Y pixel at which the texture has been placed within its PaletteImage.
void not_solitary()
Indicates that the texture, formerly indicated as solitary, is now no longer.
void fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
bool determine_size()
Attempts to determine the appropriate size of the texture for the given placement.
This represents a single source texture that is referenced by one or more egg files.