15 #include "textureReference.h"
16 #include "textureImage.h"
17 #include "paletteImage.h"
18 #include "sourceTextureImage.h"
19 #include "destTextureImage.h"
20 #include "texturePlacement.h"
21 #include "palettizer.h"
25 #include "eggTexture.h"
27 #include "eggGroupNode.h"
29 #include "eggNurbsSurface.h"
30 #include "eggVertexPool.h"
32 #include "datagramIterator.h"
33 #include "bamReader.h"
34 #include "bamWriter.h"
35 #include "string_utils.h"
56 _min_uv.set(0.0, 0.0);
57 _max_uv.set(0.0, 0.0);
58 _wrap_u = EggTexture::WM_unspecified;
59 _wrap_v = EggTexture::WM_unspecified;
83 _tref_name = egg_tex->get_name();
102 _properties._format = _egg_tex->get_format();
103 _properties._minfilter = _egg_tex->get_minfilter();
104 _properties._magfilter = _egg_tex->get_magfilter();
105 _properties._quality_level = _egg_tex->get_quality_level();
110 if (texture->get_name() != name) {
111 nout <<
"Texture name conflict: \"" << name
112 <<
"\" conflicts with existing texture named \""
113 << texture->get_name() <<
"\".\n";
120 _source_texture = texture->
get_source(filename, alpha_filename,
126 if (alpha_mode == EggRenderMode::AM_unspecified) {
132 }
else if (alpha_mode == EggRenderMode::AM_off) {
139 get_uv_range(_egg_data, pal->_remap_uv);
158 nassertv(_tref_name == other._tref_name);
159 _egg_file = other._egg_file;
160 _egg_tex = other._egg_tex;
161 _egg_data = other._egg_data;
187 nassertv(_tref_name == egg_tex->get_name());
210 return _source_texture;
243 return _tref_name < other._tref_name;
267 nassertr(_any_uvs, _min_uv);
279 nassertr(_any_uvs, _max_uv);
316 if (_source_texture != other._source_texture) {
322 if (_uses_alpha != other._uses_alpha) {
325 if (_any_uvs != other._any_uvs) {
328 if (_wrap_u != other._wrap_u ||
329 _wrap_v != other._wrap_v) {
356 if (_placement != placement) {
361 _placement = placement;
400 if (_egg_file != (
EggFile *)NULL) {
442 if (am != EggRenderMode::AM_unspecified) {
491 _egg_tex->set_wrap_mode(EggTexture::WM_unspecified);
492 _egg_tex->set_wrap_u(EggTexture::WM_unspecified);
493 _egg_tex->set_wrap_v(EggTexture::WM_unspecified);
504 if (_egg_tex->get_tex_gen() == EggTexture::TG_unspecified) {
505 update_uv_range(_egg_data, pal->_remap_uv);
528 void TextureReference::
529 output(ostream &out)
const {
530 out << *_source_texture;
538 void TextureReference::
539 write(ostream &out,
int indent_level)
const {
540 indent(out, indent_level)
544 out <<
" (uses alpha)";
551 double area = box[0] * box[1];
553 out <<
" coverage " << area;
556 if (_wrap_u != EggTexture::WM_unspecified ||
557 _wrap_v != EggTexture::WM_unspecified) {
558 if (_wrap_u != _wrap_v) {
559 out <<
" (" << _wrap_u <<
", " << _wrap_v <<
")";
561 out <<
" " << _wrap_u;
565 if (_properties._format != EggTexture::F_unspecified) {
566 out <<
" " << _properties._format;
569 switch (_properties._minfilter) {
570 case EggTexture::FT_nearest_mipmap_nearest:
571 case EggTexture::FT_linear_mipmap_nearest:
572 case EggTexture::FT_nearest_mipmap_linear:
573 case EggTexture::FT_linear_mipmap_linear:
581 if(_properties._anisotropic_degree>1) {
582 out <<
" aniso " << _properties._anisotropic_degree;
610 bool TextureReference::
611 get_uv_range(
EggGroupNode *group, Palettizer::RemapUV remap) {
612 if (group->
is_of_type(EggGroup::get_class_type())) {
614 DCAST_INTO_R(egg_group, group,
false);
616 if (egg_group->get_dart_type() != EggGroup::DT_none) {
619 remap = pal->_remap_char_uv;
623 bool group_any_uvs =
false;
626 EggGroupNode::iterator ci;
627 for (ci = group->begin(); ci != group->end(); ci++) {
629 if (child->
is_of_type(EggNurbsSurface::get_class_type())) {
644 collect_nominal_uv_range();
647 }
else if (child->
is_of_type(EggPrimitive::get_class_type())) {
653 if (_egg_tex->get_tex_gen() != EggTexture::TG_unspecified) {
660 collect_nominal_uv_range();
670 if (get_geom_uvs(geom, geom_min_uv, geom_max_uv)) {
671 if (remap == Palettizer::RU_poly) {
672 LVector2d trans = translate_uv(geom_min_uv, geom_max_uv);
673 geom_min_uv += trans;
674 geom_max_uv += trans;
676 collect_uv(group_any_uvs, group_min_uv, group_max_uv,
677 geom_min_uv, geom_max_uv);
682 }
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
684 if (!get_uv_range(cg, remap)) {
691 if (remap == Palettizer::RU_group) {
692 LVector2d trans = translate_uv(group_min_uv, group_max_uv);
693 group_min_uv += trans;
694 group_max_uv += trans;
696 collect_uv(_any_uvs, _min_uv, _max_uv, group_min_uv, group_max_uv);
708 void TextureReference::
709 update_uv_range(
EggGroupNode *group, Palettizer::RemapUV remap) {
710 if (group->
is_of_type(EggGroup::get_class_type())) {
712 DCAST_INTO_V(egg_group, group);
714 if (egg_group->get_dart_type() != EggGroup::DT_none) {
717 remap = pal->_remap_char_uv;
721 bool group_any_uvs =
false;
724 EggGroupNode::iterator ci;
725 for (ci = group->begin(); ci != group->end(); ci++) {
727 if (child->
is_of_type(EggNurbsSurface::get_class_type())) {
731 }
else if (child->
is_of_type(EggPrimitive::get_class_type())) {
732 if (remap != Palettizer::RU_never) {
737 if (get_geom_uvs(geom, geom_min_uv, geom_max_uv)) {
738 if (remap == Palettizer::RU_poly) {
739 LVector2d trans = translate_uv(geom_min_uv, geom_max_uv);
740 trans = trans * _inv_tex_mat;
742 translate_geom_uvs(geom, trans);
745 collect_uv(group_any_uvs, group_min_uv, group_max_uv,
746 geom_min_uv, geom_max_uv);
752 }
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
754 update_uv_range(cg, remap);
758 if (group_any_uvs && remap == Palettizer::RU_group) {
759 LVector2d trans = translate_uv(group_min_uv, group_max_uv);
760 trans = trans * _inv_tex_mat;
762 for (ci = group->begin(); ci != group->end(); ci++) {
764 if (child->
is_of_type(EggPrimitive::get_class_type())) {
767 translate_geom_uvs(geom, trans);
782 bool TextureReference::
786 bool geom_any_uvs =
false;
788 EggPrimitive::iterator pi;
789 for (pi = geom->begin(); pi != geom->end(); ++pi) {
791 if (vtx->
has_uv(uv_name)) {
793 collect_uv(geom_any_uvs, geom_min_uv, geom_max_uv, uv, uv);
806 void TextureReference::
810 EggPrimitive::iterator pi;
811 for (pi = geom->begin(); pi != geom->end(); ++pi) {
813 if (vtx->
has_uv(uv_name)) {
815 vtx_copy.set_uv(uv_name, vtx_copy.get_uv(uv_name) + trans);
833 void TextureReference::
834 collect_nominal_uv_range() {
835 static const int num_nurbs_uvs = 4;
836 static LTexCoordd nurbs_uvs[num_nurbs_uvs] = {
843 for (
int i = 0; i < num_nurbs_uvs; i++) {
845 collect_uv(_any_uvs, _min_uv, _max_uv, uv, uv);
855 void TextureReference::
859 min_uv.set(min(min_uv[0], got_min_uv[0]),
860 min(min_uv[1], got_min_uv[1]));
861 max_uv.set(max(max_uv[0], got_max_uv[0]),
862 max(max_uv[1], got_max_uv[1]));
881 return LVector2d(-floor(center[0]), -floor(center[1]));
893 register_factory(get_class_type(), make_TextureReference);
914 _inv_tex_mat.write_datagram(datagram);
944 DCAST_INTO_R(_egg_file, p_list[pi], pi);
949 DCAST_INTO_R(_source_texture, p_list[pi], pi);
954 DCAST_INTO_R(_placement, p_list[pi], pi);
977 parse_params(params, scan, manager);
978 me->fillin(scan, manager);
989 void TextureReference::
994 if (Palettizer::_read_pi_version >= 11) {
999 _inv_tex_mat.read_datagram(scan);
1010 _wrap_u = (EggTexture::WrapMode)scan.
get_int32();
1011 _wrap_v = (EggTexture::WrapMode)scan.
get_int32();
1012 _properties.
fillin(scan, manager);
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
void from_egg_quick(const TextureReference &other)
Sets up the pointers within the TextureReference to the same egg file pointers indicated by the other...
This represents a texture filename as it has been resized and copied to the map directory (e...
void set_placement(TexturePlacement *placement)
Sets the particular TexturePlacement that is appropriate for this egg file.
void update_egg()
Updates the egg file with all the relevant information to reference the texture in its new home...
LTexCoordd get_uv() const
Returns the unnamed UV coordinate pair on the vertex.
void apply_properties_to_source()
Applies the texture properties as read from the egg file to the source image's properties.
bool has_num_channels() const
Returns true if the number of channels in the image is known, false otherwise.
int get_anisotropic_degree() const
Returns the anisotropic filtering degree that has been specified for this texture, or 0 if nothing has been specified.
bool get_bool()
Extracts a boolean value.
void add_string(const string &str)
Adds a variable-length string to the datagram.
WrapMode determine_wrap_v() const
Determines the appropriate wrap in the V direction.
DestTextureImage * get_dest() const
Returns the DestTextureImage that corresponds to this texture as it was copied to the install directo...
void add_float64(PN_float64 value)
Adds a 64-bit floating-point number to the datagram.
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...
This is a two-component vector offset.
This is the particular reference of a texture filename by an egg file.
A base class for nodes in the hierarchy that are not leaf nodes.
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
int get_num_channels() const
Returns the number of channels of the image.
SourceTextureImage * get_source(const Filename &filename, const Filename &alpha_filename, int alpha_file_channel)
Returns the SourceTextureImage corresponding to the given filename(s).
Defines a texture map that may be applied to geometry.
EggFile * get_egg_file() const
Returns the EggFile that references this texture.
void mark_stale()
Marks this particular egg file as stale, meaning that something has changed, such as the location of ...
Base class for objects that can be written to and read from Bam files.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
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 a two-component point in space.
SourceTextureImage * get_source() const
Returns the SourceTextureImage that this object refers to.
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.
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 the primary interface into all the egg data, and the root of the egg file structure...
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...
bool operator<(const TextureReference &other) const
Defines an ordering of TextureReference pointers in alphabetical order by their tref name...
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 read_datagram(DatagramIterator &source)
Reads the matrix from the Datagram using get_stdfloat().
bool invert_from(const LMatrix3d &other)
Computes the inverse of the other matrix, and stores the result in this matrix.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
This is a 3-by-3 transform matrix.
const string & get_uv_name() const
Returns the texcoord name that has been specified for this texture, or the empty string if no texcoor...
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_equivalent(const TextureReference &other) const
Returns true if all essential properties of this TextureReference are the same as that of the other...
bool almost_equal(const LVecBase2d &other, double threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
OmitReason get_omit_reason() const
Returns the reason the texture has been omitted from a palette image, or OR_none if it has not...
The name of a file, such as a texture file or an Egg 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()...
const LTexCoordd & get_max_uv() const
Returns the maximum UV coordinate in use for the texture by this reference.
bool has_alpha_filename() const
Returns true if a separate file for the alpha component has been applied, false otherwise.
int get_alpha_file_channel() const
Returns the particular channel that has been specified for the alpha-file image, or 0 if no channel h...
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
WrapMode determine_wrap_u() const
Determines the appropriate wrap in the U direction.
EggTexture::WrapMode get_txa_wrap_u() const
Returns the wrap mode specified in the u direction in the txa file, or WM_unspecified.
void rebind_egg_data(EggData *data, EggTexture *egg_tex)
After an EggData has previously been released via release_egg_data(), this can be called to indicate ...
static const LVector2d & zero()
Returns a zero-length vector.
TextureImage * get_texture() const
Returns the TextureImage that this object refers to.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
TextureImage * get_texture() const
Returns the particular texture that this image is one of the sources for.
void set_alpha_mode(AlphaMode mode)
Specifies precisely how the transparency for this geometry should be achieved, or if it should be use...
bool get_size()
Determines the size of the SourceTextureImage, if it is not already known.
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.
void from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex)
Sets up the TextureReference using information extracted from an egg file.
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
This is a texture image reference as it appears in an egg file: the source image of the texture...
EggRenderMode::AlphaMode get_alpha_mode() const
Returns the alpha mode that should be used to render objects with this texture, as specified by the u...
void add_egg(TextureReference *reference)
Records the fact that a particular egg file is using this particular TexturePlacement.
bool egg_properties_match(const TextureProperties &other) const
Returns true if all of the properties that are reflected directly in an egg file match between this T...
const string & get_tref_name() const
Returns the name of the EggTexture entry that references this texture.
void fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
EggTexture::WrapMode get_txa_wrap_v() const
Returns the wrap mode specified in the v direction in the txa file, or WM_unspecified.
bool has_alpha_channel(int num_components) const
Given the number of color components (channels) in the image file as actually read from the disk...
string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
AlphaMode get_alpha_mode() const
Returns the alpha mode that was set, or AM_unspecified if nothing was set.
PN_float64 get_float64()
Extracts a 64-bit floating-point number.
void mark_egg_stale()
Marks the egg file that shares this reference as stale.
string get_basename() const
Returns the basename part of the filename.
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.
PaletteImage * get_image() const
Returns the particular PaletteImage on which the texture has been placed.
const Filename & get_alpha_filename() const
Returns the separate file assigned for the alpha channel.
bool almost_equal(const LMatrix3d &other, double threshold) const
Returns true if two matrices are memberwise equal within a specified tolerance.
A base class for things that may be directly added into the egg hierarchy.
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.
A parametric NURBS surface.
void write_datagram(Datagram &destination) const
Writes the matrix to the Datagram using add_stdfloat().
This is a single palette image, one of several within a PalettePage, which is in turn one of several ...
void replace(iterator position, EggVertex *vertex)
Replaces the vertex at the indicated position with the indicated vertex.
void update_properties(const TextureProperties &properties)
If the indicate TextureProperties structure is more specific than this one, updates this one...
void add_int32(PN_int32 value)
Adds a signed 32-bit integer to the datagram.
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.
void copy_grefs_from(const EggVertex &other)
Copies all the group references from the other vertex onto this one.
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.
TypeHandle is the identifier used to differentiate C++ class types.
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
GroupRef::size_type gref_size() const
Returns the number of elements between gref_begin() and gref_end().
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
TextureImage * get_texture(const string &name)
Returns the TextureImage with the given name.
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...
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
bool has_uvs() const
Returns true if this TextureReference actually uses the texture on geometry, with UV's and everything...
void release_egg_data()
Called to indicate that the EggData previously passed to from_egg() is about to be deallocated...
This represents a single egg file known to the palettizer.
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
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.
TexturePlacement * get_placement() const
Returns the particular TexturePlacement that is appropriate for this egg file.
void update_egg_tex(EggTexture *egg_tex) const
Sets the indicated EggTexture to refer to this file.