15 #include "texturePlacement.h"
16 #include "textureReference.h"
17 #include "textureImage.h"
18 #include "paletteGroup.h"
19 #include "paletteImage.h"
20 #include "palettizer.h"
22 #include "destTextureImage.h"
26 #include "datagramIterator.h"
27 #include "bamReader.h"
28 #include "bamWriter.h"
48 _omit_reason = OR_none;
61 _omit_reason = OR_working;
66 _omit_reason = OR_unknown;
85 References::iterator ri;
86 References copy_references = _references;
87 for (ri = copy_references.begin(); ri != copy_references.end(); ++ri) {
105 return _texture->get_name();
154 _references.insert(reference);
170 _references.erase(reference);
182 References::iterator ri;
183 for (ri = _references.begin(); ri != _references.end(); ++ri) {
230 _omit_reason = OR_unknown;
249 _position._wrap_u = EggTexture::WM_clamp;
250 _position._wrap_v = EggTexture::WM_clamp;
254 References::iterator ri;
255 for (ri = _references.begin(); ri != _references.end(); ++ri) {
262 min_uv.set(min(min_uv[0], n[0]), min(min_uv[1], n[1]));
263 max_uv.set(max(max_uv[0], x[0]), max(max_uv[1], x[1]));
273 if (reference->
get_wrap_u() == EggTexture::WM_repeat) {
274 _position._wrap_u = EggTexture::WM_repeat;
276 if (reference->
get_wrap_v() == EggTexture::WM_repeat) {
277 _position._wrap_v = EggTexture::WM_repeat;
292 _omit_reason = OR_unused;
307 if (pal->_round_uvs) {
309 ceil((rounded_max_uv[0] - pal->_round_fuzz) / pal->_round_unit) *
312 ceil((rounded_max_uv[1] - pal->_round_fuzz) / pal->_round_unit) *
316 floor((rounded_min_uv[0] + pal->_round_fuzz) / pal->_round_unit) *
319 floor((rounded_min_uv[1] + pal->_round_fuzz) / pal->_round_unit) *
328 compute_size_from_uvs(rounded_min_uv, rounded_max_uv);
334 _omit_reason = OR_omitted;
339 _omit_reason = OR_coverage;
341 }
else if ((_position._x_size > pal->_pal_x_size ||
342 _position._y_size > pal->_pal_y_size) ||
343 (_position._x_size == pal->_pal_x_size &&
344 _position._y_size == pal->_pal_y_size)) {
350 _omit_reason = OR_size;
355 _omit_reason = OR_default_omit;
357 }
else if (_omit_reason == OR_omitted ||
358 _omit_reason == OR_default_omit ||
359 _omit_reason == OR_size ||
360 _omit_reason == OR_coverage ||
361 _omit_reason == OR_unknown) {
367 _omit_reason = OR_working;
373 if (_position._x_size != _placed._x_size ||
374 _position._y_size != _placed._y_size ||
375 _position._min_uv[0] < _placed._min_uv[0] ||
376 _position._min_uv[1] < _placed._min_uv[1] ||
377 _position._max_uv[0] > _placed._max_uv[0] ||
378 _position._max_uv[1] > _placed._max_uv[1]) {
386 if ((_position._x_size > _placed._x_size ||
387 _position._y_size > _placed._y_size) &&
389 compute_size_from_uvs(min_uv, max_uv);
390 if (_position._x_size <= _placed._x_size &&
391 _position._y_size <= _placed._y_size &&
392 _position._min_uv[0] >= _placed._min_uv[0] &&
393 _position._min_uv[1] >= _placed._min_uv[1] &&
394 _position._max_uv[0] <= _placed._max_uv[0] &&
395 _position._max_uv[1] <= _placed._max_uv[1]) {
399 compute_size_from_uvs(rounded_min_uv, rounded_max_uv);
407 if (_position._wrap_u != _placed._wrap_u ||
408 _position._wrap_v != _placed._wrap_v) {
412 _placed._wrap_u = _position._wrap_u;
413 _placed._wrap_v = _position._wrap_v;
456 nassertr(_size_known, 0);
457 return _position._x_size;
470 nassertr(_size_known, 0);
471 return _position._y_size;
488 LTexCoordd range = _position._max_uv - _position._min_uv;
489 return range[0] * range[1];
565 return _placed._x_size;
578 return _placed._y_size;
591 LTexCoordd range = _placed._max_uv - _placed._min_uv;
592 return range[0] * range[1];
606 nassertv(_size_known);
613 _omit_reason = OR_none;
630 if (_omit_reason == OR_none) {
633 _omit_reason = OR_working;
649 if (_omit_reason != OR_solitary) {
651 _omit_reason = OR_solitary;
664 if (_omit_reason != OR_none) {
666 _omit_reason = OR_none;
682 int hright = x + x_size;
683 int hbot = y + y_size;
685 int mright = _placed._x + _placed._x_size;
686 int mbot = _placed._y + _placed._y_size;
688 return !(x >= mright || hright <= _placed._x ||
689 y >= mbot || hbot <= _placed._y);
705 LTexCoordd range = _placed._max_uv - _placed._min_uv;
706 if (range[0] != 0.0 && range[1] != 0.0) {
712 int top = _placed._y + _placed._margin;
713 int left = _placed._x + _placed._margin;
714 int x_size = _placed._x_size - _placed._margin * 2;
715 int y_size = _placed._y_size - _placed._margin * 2;
717 int bottom = top + y_size;
721 LVecBase2d t((
double)left / (
double)pal_x_size,
722 (
double)(pal_y_size - bottom) / (
double)pal_y_size);
723 LVecBase2d s((
double)x_size / (
double)pal_x_size,
724 (
double)y_size / (
double)pal_y_size);
731 transform = source_uvs * dest_uvs;
742 indent(out, indent_level)
752 if (_placed._wrap_u != EggTexture::WM_unspecified ||
753 _placed._wrap_v != EggTexture::WM_unspecified) {
754 if (_placed._wrap_u != _placed._wrap_v) {
755 out <<
" (" << _placed._wrap_u <<
", " << _placed._wrap_v <<
")";
757 out <<
" " << _placed._wrap_u;
762 out <<
" not yet placed.\n";
817 int top = (int)floor((1.0 - ul[1]) * pal_y_size + 0.5);
818 int left = (int)floor(ul[0] * pal_x_size + 0.5);
819 int bottom = (int)floor((1.0 - lr[1]) * pal_y_size + 0.5);
820 int right = (int)floor(lr[0] * pal_x_size + 0.5);
825 int x_size = right - left;
826 int y_size = bottom - top;
827 nassertv(x_size >= 0 && y_size >= 0);
842 bool source_alpha = source.has_alpha();
850 for (
int y = _placed._y; y < _placed._y + _placed._y_size; y++) {
853 if (_placed._wrap_v == EggTexture::WM_clamp) {
855 sy = max(min(sy, y_size - 1), 0);
859 sy = (sy < 0) ? y_size - 1 - ((-sy - 1) % y_size) : sy % y_size;
862 for (
int x = _placed._x; x < _placed._x + _placed._x_size; x++) {
865 if (_placed._wrap_u == EggTexture::WM_clamp) {
867 sx = max(min(sx, x_size - 1), 0);
871 sx = (sx < 0) ? x_size - 1 - ((-sx - 1) % x_size) : sx % x_size;
874 image.
set_xel(x, y, source.get_xel(sx, sy));
877 image.
set_alpha(x, y, source.get_alpha(sx, sy));
917 int top = (int)floor((1.0 - ul[1]) * pal_y_size + 0.5);
918 int left = (int)floor(ul[0] * pal_x_size + 0.5);
919 int bottom = (int)floor((1.0 - lr[1]) * pal_y_size + 0.5);
920 int right = (int)floor(lr[0] * pal_x_size + 0.5);
925 int x_size = right - left;
926 int y_size = bottom - top;
927 nassertv(x_size >= 0 && y_size >= 0);
931 TextureSwaps::iterator tsi;
932 tsi = _textureSwaps.begin() + index;
945 bool source_alpha = source.has_alpha();
953 for (
int y = _placed._y; y < _placed._y + _placed._y_size; y++) {
956 if (_placed._wrap_v == EggTexture::WM_clamp) {
958 sy = max(min(sy, y_size - 1), 0);
962 sy = (sy < 0) ? y_size - 1 - ((-sy - 1) % y_size) : sy % y_size;
965 for (
int x = _placed._x; x < _placed._x + _placed._x_size; x++) {
968 if (_placed._wrap_u == EggTexture::WM_clamp) {
970 sx = max(min(sx, x_size - 1), 0);
974 sx = (sx < 0) ? x_size - 1 - ((-sx - 1) % x_size) : sx % x_size;
977 image.
set_xel(x, y, source.get_xel(sx, sy));
980 image.
set_alpha(x, y, source.get_alpha(sx, sy));
1001 for (
int y = _placed._y; y < _placed._y + _placed._y_size; y++) {
1002 for (
int x = _placed._x; x < _placed._x + _placed._x_size; x++) {
1007 for (
int y = _placed._y; y < _placed._y + _placed._y_size; y++) {
1008 for (
int x = _placed._x; x < _placed._x + _placed._x_size; x++) {
1023 void TexturePlacement::
1025 _position._min_uv = min_uv;
1026 _position._max_uv = max_uv;
1028 LTexCoordd range = _position._max_uv - _position._min_uv;
1034 _position._x_size = (int)floor(_texture->
get_x_size() * range[0] + 0.5);
1035 _position._y_size = (int)floor(_texture->
get_y_size() * range[1] + 0.5);
1042 _position._x_size = max(_position._x_size, 4);
1043 _position._y_size = max(_position._y_size, 4);
1045 if(
get_group()->has_margin_override()) {
1056 if ((
double)_position._margin / (
double)_position._x_size > 0.10) {
1057 _position._x_size += _position._margin * 2;
1059 if ((
double)_position._margin / (
double)_position._y_size > 0.10) {
1060 _position._y_size += _position._margin * 2;
1077 register_factory(get_class_type(), make_TexturePlacement);
1104 References::const_iterator ri;
1105 for (ri = _references.begin(); ri != _references.end(); ++ri) {
1109 datagram.
add_int32(_textureSwaps.size());
1110 TextureSwaps::const_iterator tsi;
1111 for (tsi = _textureSwaps.begin(); tsi != _textureSwaps.end(); ++tsi) {
1131 DCAST_INTO_R(_texture, p_list[index], index);
1136 DCAST_INTO_R(_group, p_list[index], index);
1141 DCAST_INTO_R(_image, p_list[index], index);
1146 DCAST_INTO_R(_dest, p_list[index], index);
1151 for (i = 0; i < _num_references; i++) {
1153 DCAST_INTO_R(reference, p_list[index], index);
1154 _references.insert(reference);
1158 for (i = 0; i < _num_textureSwaps; i++) {
1160 DCAST_INTO_R(swapTexture, p_list[index], index);
1161 _textureSwaps.push_back(swapTexture);
1182 parse_params(params, scan, manager);
1183 me->fillin(scan, manager);
1194 void TexturePlacement::
1205 _position.
fillin(scan, manager);
1208 _placed.
fillin(scan, manager);
1209 _omit_reason = (OmitReason)scan.
get_int32();
1214 if (Palettizer::_read_pi_version >= 20) {
1217 _num_textureSwaps = 0;
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_margin() const
Returns the appropriate margin for this texture.
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...
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, to represent a missing texture.
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...
bool is_valid() const
Returns true if the image has been read in or correctly initialized with a height and width...
DestTextureImage * get_dest() const
Returns the DestTextureImage that corresponds to this texture as it was copied to the install directo...
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...
PalettePage * get_page() const
Returns the particular PalettePage this image is associated with.
bool is_placed() const
Returns true if the texture has been placed on a palette image, false otherwise.
const string & get_name() const
Returns the name of the texture that this placement represents.
This is the particular reference of a texture filename by an egg file.
This is the base class for all two-component vectors and points.
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.
bool is_none_texture_swap() const
Returns textureswap information is set or not, True if it's not set.
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.
void set_xel_val(int x, int y, const xel &value)
Changes the RGB color at the indicated pixel.
Base class for objects that can be written to and read from Bam files.
This is the highest level of grouping for TextureImages.
double get_coverage_threshold() const
Returns the appropriate coverage threshold for this texture.
void unplace(TexturePlacement *placement)
Removes the texture from its position on a PaletteImage, if it has been so placed.
This is a two-component point in space.
int get_placed_y() const
Returns the Y pixel at which the texture has been placed within its PaletteImage. ...
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 fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
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...
static LMatrix3d translate_mat(const LVecBase2d &trans)
Returns a matrix that applies the indicated translation.
void place_at(PaletteImage *image, int x, int y)
Assigns the texture to a particular position within the indicated PaletteImage.
int get_y_size() const
Returns the size of the image file in pixels in the Y direction.
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...
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 LTexCoordd & get_min_uv() const
Returns the minimum UV coordinate in use for the texture by this reference.
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 quick_filter_from(const PNMImage ©, int xborder=0, int yborder=0)
Resizes from the given image, with a fixed radius of 0.5.
bool operator()(TexturePlacement *a, TexturePlacement *b) const
Compares two TexturePlacement objects and returns true if the first one is bigger than the second one...
This is a 3-by-3 transform matrix.
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 ...
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...
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()...
const LTexCoordd & get_max_uv() const
Returns the maximum UV coordinate in use for the texture by this reference.
bool is_filled() const
Returns true if the texture has been filled (i.e.
EggTexture::WrapMode get_txa_wrap_u() const
Returns the wrap mode specified in the u direction in the txa file, or WM_unspecified.
double get_placed_uv_area() const
Returns the total area of the rectangle occupied by the UV minmax box, as it has been placed...
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
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.
int get_margin_override() const
Returns the set of groups this group depends on.
PalettePage * get_page() const
Returns the particular PalettePage on which the texture has been placed.
void add_egg(TextureReference *reference)
Records the fact that a particular egg file is using this particular TexturePlacement.
PaletteGroup * get_group() const
Returns the group that this placement represents.
int get_x_size() const
Returns the size of the image file in pixels in the X direction.
EggTexture::WrapMode get_txa_wrap_v() const
Returns the wrap mode specified in the v direction in the txa file, or WM_unspecified.
int get_placed_x() const
Returns the X pixel at which the texture has been placed within its PaletteImage. ...
void mark_egg_stale()
Marks the egg file that shares this reference as stale.
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 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.
EggTexture::WrapMode get_wrap_u() const
Returns the specification for the wrapping in the U direction.
const PNMImage & read_source_image()
Reads in the original image, if it has not already been read, and returns it.
PaletteImage * get_image() const
Returns the particular PaletteImage on which the texture has been placed.
bool is_size_known() const
Returns true if the texture's size is known, false otherwise.
bool get_omit() const
Returns true if the user specifically requested to omit this texture via the "omit" keyword in the ...
static LMatrix3d scale_mat(const LVecBase2d &scale)
Returns a matrix that applies the indicated scale in each of the two axes.
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.
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 add_int32(PN_int32 value)
Adds a signed 32-bit integer to the datagram.
void set_alpha_val(int x, int y, xelval a)
Sets the alpha component color only at the indicated pixel.
static const LMatrix3d & ident_mat()
Returns an identity matrix.
EggTexture::WrapMode get_wrap_v() const
Returns the specification for the wrapping in the V direction.
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.
TextureImage * get_texture() const
Returns the texture that this placement represents.
const TextureProperties & get_properties() const
Returns the grouping properties of the image.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void set_xel(int x, int y, const LRGBColorf &value)
Changes the RGB color at the indicated pixel.
double get_uv_area() const
Returns the total area of the rectangle occupied by the UV minmax box, in UV coordinates.
bool has_uvs() const
Returns true if this TextureReference actually uses the texture on geometry, with UV's and everything...
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.
void write_placed(ostream &out, int indent_level=0)
Writes the placement position information on a line by itself.
void fill_image(PNMImage &image)
Fills in the rectangle of the palette image represented by the texture placement with the image pixel...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
void release_source_image()
Frees the memory that was allocated by a previous call to read_source_image().
TexturePlacement * get_placement() const
Returns the particular TexturePlacement that is appropriate for this egg file.
bool is_size_known() const
Returns true if the size of the image file is known, false otherwise.
This is the set of characteristics of a texture that, if different from another texture, prevent the two textures from sharing a PaletteImage.