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;
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);
736 bool source_alpha = source.has_alpha();
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;
803 image.
set_xel(x, y, source.get_xel(sx, sy));
806 image.
set_alpha(x, y, source.get_alpha(sx, sy));
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;
868 bool source_alpha = source.has_alpha();
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;
899 image.
set_xel(x, y, source.get_xel(sx, sy));
902 image.
set_alpha(x, y, source.get_alpha(sx, sy));
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_filled() const
Returns true if the texture has been filled (i.e.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
This represents a texture filename as it has been resized and copied to the map directory (e....
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 not_solitary()
Indicates that the texture, formerly indicated as solitary, is now no longer.
void flag_error_image(PNMImage &image)
Sets the rectangle of the palette image represented by the texture placement to red,...
bool determine_size()
Attempts to determine the appropriate size of the texture for the given placement.
bool get_bool()
Extracts a boolean value.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggTexture::WrapMode get_wrap_u() const
Returns the specification for the wrapping in the U direction.
void clear_placement()
Removes any reference to a TexturePlacement.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
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...
This is the particular reference of a texture filename by an egg file.
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object,...
PaletteGroup * get_group() const
Returns the group that this placement represents.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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,...
void set_xel_val(int x, int y, const xel &value)
Changes the RGB color at the indicated pixel.
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.
This is the highest level of grouping for TextureImages.
void unplace(TexturePlacement *placement)
Removes the texture from its position on a PaletteImage, if it has been so placed.
int get_placed_x() const
Returns the X pixel at which the texture has been placed within its PaletteImage.
const LTexCoordd & get_min_uv() const
Returns the minimum UV coordinate in use for the texture by this reference.
double get_placed_uv_area() const
Returns the total area of the rectangle occupied by the UV minmax box, as it has been placed.
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...
const LTexCoordd & get_max_uv() const
Returns the maximum UV coordinate in use for the texture by this reference.
double get_uv_area() const
Returns the total area of the rectangle occupied by the UV minmax box, in UV coordinates.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
EggTexture::WrapMode get_txa_wrap_v() const
Returns the wrap mode specified in the v direction in the txa file, or WM_unspecified.
This is a particular collection of textures, within a PaletteGroup, that all share the same TexturePr...
int32_t get_int32()
Extracts a signed 32-bit integer.
EggTexture::WrapMode get_wrap_v() const
Returns the specification for the wrapping in the V direction.
void place_at(PaletteImage *image, int x, int y)
Assigns the texture to a particular position within the indicated PaletteImage.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void omit_solitary()
Sets the omit reason (returned by get_omit()) to OR_solitary, indicating that the palettized version ...
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...
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
const std::string & get_name() const
Returns the name of the texture that this placement represents.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
bool is_none_texture_swap() const
Returns textureswap information is set or not, True if it's not set.
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_y() const
Returns the Y pixel at which the texture has been placed within its PaletteImage.
bool is_valid() const
Returns true if the image has been read in or correctly initialized with a height and width.
PalettePage * get_page() const
Returns the particular PalettePage this image is associated with.
const TextureProperties & get_properties() const
Returns the grouping properties of the image.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
void force_replace()
Removes the texture from its particular PaletteImage, but does not remove it from the PaletteGroup.
void mark_unfilled()
Marks the texture as unfilled, so that it will need to be copied into the palette image again.
void add_bool(bool value)
Adds a boolean value to the datagram.
void compute_tex_matrix(LMatrix3d &transform)
Stores in the indicated matrix the appropriate texture matrix transform for the new placement of the ...
bool is_size_known() const
Returns true if the texture's size is known, false otherwise.
bool is_size_known() const
Returns true if the size of the image file is known, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_x_size() const
Returns the size of the image file in pixels in the X direction.
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().
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
bool get_omit() const
Returns true if the user specifically requested to omit this texture via the "omit" keyword in the ....
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
const TextureProperties & get_properties() const
Returns the grouping properties of the image.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PalettePage * get_page() const
Returns the particular PalettePage on which the texture has been placed.
This corresponds to a particular assignment of a TextureImage with a PaletteGroup,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
double get_coverage_threshold() const
Returns the appropriate coverage threshold for this texture.
void add_egg(TextureReference *reference)
Records the fact that a particular egg file is using this particular TexturePlacement.
OmitReason get_omit_reason() const
Returns the reason the texture has been omitted from a palette image, or OR_none if it has not.
int get_margin() const
Returns the appropriate margin for this texture.
void mark_egg_stale()
Marks the egg file that shares this reference as stale.
TextureImage * get_texture() const
Returns the texture that this placement represents.
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
void set_alpha(int x, int y, float a)
Sets the alpha component color only at the indicated pixel.
void remove_egg(TextureReference *reference)
Notes that a particular egg file is no longer using this particular TexturePlacement.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
const PNMImage & read_source_image()
Reads in the original image, if it has not already been read, and returns it.
int get_x_size() const
Returns the size in the X dimension, in pixels, of the texture image as it must appear in the palette...
void write_placed(std::ostream &out, int indent_level=0)
Writes the placement position information on a line by itself.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
DestTextureImage * get_dest() const
Returns the DestTextureImage that corresponds to this texture as it was copied to the install directo...
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...
This is a single palette image, one of several within a PalettePage, which is in turn one of several ...
void unplace(TexturePlacement *placement)
Removes the texture from the image.
OmitReason
This enumerates the reasons why a texture may not have been placed in a palette image.
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...
bool has_uvs() const
Returns true if this TextureReference actually uses the texture on geometry, with UV's and everything...
void set_alpha_val(int x, int y, xelval a)
Sets the alpha component color only at the indicated pixel.
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.
void set_dest(DestTextureImage *dest)
Sets the DestTextureImage that corresponds to this texture as it was copied to the install directory.
TypeHandle is the identifier used to differentiate C++ class types.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
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...
EggTexture::WrapMode get_txa_wrap_u() const
Returns the wrap mode specified in the u direction in the txa file, or WM_unspecified.
void set_xel(int x, int y, const LRGBColorf &value)
Changes the RGB color at the indicated pixel.
TexturePlacement * get_placement() const
Returns the particular TexturePlacement that is appropriate for this egg file.
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 mark_eggs_stale()
Marks all the egg files that reference this placement stale.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void fill_image(PNMImage &image)
Fills in the rectangle of the palette image represented by the texture placement with the image pixel...
bool is_placed() const
Returns true if the texture has been placed on a palette image, false otherwise.
int get_margin_override() const
Returns the set of groups this group depends on.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
void release_source_image()
Frees the memory that was allocated by a previous call to read_source_image().
This is the set of characteristics of a texture that, if different from another texture,...