Panda3D

fltTexture.cxx

00001 // Filename: fltTexture.cxx
00002 // Created by:  drose (25Aug00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "fltTexture.h"
00016 #include "fltRecordReader.h"
00017 #include "fltRecordWriter.h"
00018 #include "fltHeader.h"
00019 #include "pathReplace.h"
00020 #include "config_util.h"
00021 
00022 TypeHandle FltTexture::_type_handle;
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: FltTexture::Constructor
00026 //       Access: Public
00027 //  Description:
00028 ////////////////////////////////////////////////////////////////////
00029 FltTexture::
00030 FltTexture(FltHeader *header) : FltRecord(header) {
00031   _pattern_index = -1;
00032   _x_location = 0;
00033   _y_location = 0;
00034 
00035   _num_texels_u = 0;
00036   _num_texels_v = 0;
00037   _real_world_size_u = 0;
00038   _real_world_size_v = 0;
00039   _up_vector_x = 0;
00040   _up_vector_y = 1;
00041   _file_format = FF_none;
00042   _min_filter = MN_point;
00043   _mag_filter = MG_point;
00044   _repeat = RT_repeat;
00045   _repeat_u = RT_repeat;
00046   _repeat_v = RT_repeat;
00047   _modify_flag = 0;
00048   _x_pivot_point = 0;
00049   _y_pivot_point = 0;
00050   _env_type = ET_modulate;
00051   _intensity_is_alpha = false;
00052   _float_real_world_size_u = 0.0;
00053   _float_real_world_size_v = 0.0;
00054   _imported_origin_code = 0;
00055   _kernel_version = 1520;
00056   _internal_format = IF_default;
00057   _external_format = EF_default;
00058   _use_mipmap_kernel = false;
00059   memset(_mipmap_kernel, 0, sizeof(_mipmap_kernel));
00060   _use_lod_scale = false;
00061   memset(_lod_scale, 0, sizeof(_lod_scale));
00062   _clamp = 0.0;
00063   _mag_filter_alpha = MG_point;
00064   _mag_filter_color = MG_point;
00065   _lambert_conic_central_meridian = 0.0;
00066   _lambert_conic_upper_latitude = 0.0;
00067   _lambert_conic_lower_latitude = 0.0;
00068   _use_detail = false;
00069   _detail_j = 0;
00070   _detail_k = 0;
00071   _detail_m = 0;
00072   _detail_n = 0;
00073   _detail_scramble = 0;
00074   _use_tile = false;
00075   _tile_lower_left_u = 0.0;
00076   _tile_lower_left_v = 0.0;
00077   _tile_upper_right_u = 0.0;
00078   _tile_upper_right_v = 0.0;
00079   _projection = PT_flat_earth;
00080   _earth_model = EM_wgs84;
00081   _utm_zone = 0;
00082   _image_origin = IO_lower_left;
00083   _geospecific_points_units = PU_degrees;
00084   _geospecific_hemisphere = H_southern;
00085   _file_version = 1501;
00086 }
00087 
00088 ////////////////////////////////////////////////////////////////////
00089 //     Function: FltTexture::apply_converted_filenames
00090 //       Access: Public, Virtual
00091 //  Description: Walks the hierarchy at this record and below and
00092 //               copies the _converted_filename record into the
00093 //               _orig_filename record, so the flt file will be
00094 //               written out with the converted filename instead of
00095 //               what was originally read in.
00096 ////////////////////////////////////////////////////////////////////
00097 void FltTexture::
00098 apply_converted_filenames() {
00099   _orig_filename = _converted_filename.to_os_generic();
00100   FltRecord::apply_converted_filenames();
00101 }
00102 
00103 ////////////////////////////////////////////////////////////////////
00104 //     Function: FltTexture::get_texture_filename
00105 //       Access: Public
00106 //  Description: Returns the name of the texture image file.
00107 ////////////////////////////////////////////////////////////////////
00108 Filename FltTexture::
00109 get_texture_filename() const {
00110   return _converted_filename;
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////
00114 //     Function: FltTexture::set_texture_filename
00115 //       Access: Public
00116 //  Description: Changes the name of the texture image file.
00117 ////////////////////////////////////////////////////////////////////
00118 void FltTexture::
00119 set_texture_filename(const Filename &filename) {
00120   _converted_filename = filename; 
00121   _orig_filename = _converted_filename.to_os_generic();
00122 }
00123 
00124 ////////////////////////////////////////////////////////////////////
00125 //     Function: FltTexture::get_attr_filename
00126 //       Access: Public
00127 //  Description: Returns the name of the texture's associated .attr
00128 //               file.  This contains some additional MultiGen
00129 //               information about the texture parameters.  This is,
00130 //               of course, just the name of the texture with .attr
00131 //               appended.
00132 //
00133 //               Normally, it won't be necessary to access this file
00134 //               directly; you can call read_attr_data() or
00135 //               write_attr_data() to get at the data stored in this
00136 //               file.  (And read_attr_data() is called automatically
00137 //               when the Flt file is read in.)
00138 ////////////////////////////////////////////////////////////////////
00139 Filename FltTexture::
00140 get_attr_filename() const {
00141   string texture_filename = get_texture_filename();
00142   return Filename::binary_filename(texture_filename + ".attr");
00143 }
00144 
00145 ////////////////////////////////////////////////////////////////////
00146 //     Function: FltTexture::read_attr_data
00147 //       Access: Public
00148 //  Description: Opens up the texture's .attr file and reads its data
00149 //               into the extra FltTexture fields.  This is normally
00150 //               performed automatically when the Flt file is read
00151 //               from disk.
00152 ////////////////////////////////////////////////////////////////////
00153 FltError FltTexture::
00154 read_attr_data() {
00155   Filename attr_filename = get_attr_filename();
00156 
00157   ifstream attr;
00158   if (!attr_filename.open_read(attr)) {
00159     return FE_could_not_open;
00160   }
00161 
00162   // Determine the file's size so we can read it all into one big
00163   // datagram.
00164   attr.seekg(0, ios::end);
00165   if (attr.fail()) {
00166     return FE_read_error;
00167   }
00168   streampos length = attr.tellg();
00169 
00170   char *buffer = new char[length];
00171 
00172   attr.seekg(0, ios::beg);
00173   attr.read(buffer, length);
00174   if (attr.fail()) {
00175     return FE_read_error;
00176   }
00177 
00178   Datagram datagram(buffer, length);
00179   delete[] buffer;
00180 
00181   return unpack_attr(datagram);
00182 }
00183 
00184 ////////////////////////////////////////////////////////////////////
00185 //     Function: FltTexture::write_attr_data
00186 //       Access: Public
00187 //  Description: Writes the texture's .attr file.  This may or may
00188 //               not be performed automatically, according to the
00189 //               setting of FltHeader::set_auto_attr_update().
00190 ////////////////////////////////////////////////////////////////////
00191 FltError FltTexture::
00192 write_attr_data() const {
00193   return write_attr_data(get_attr_filename());
00194 }
00195 
00196 ////////////////////////////////////////////////////////////////////
00197 //     Function: FltTexture::write_attr_data
00198 //       Access: Public
00199 //  Description: Writes the texture's .attr file to the named
00200 //               file.
00201 ////////////////////////////////////////////////////////////////////
00202 FltError FltTexture::
00203 write_attr_data(Filename attr_filename) const {
00204   Datagram datagram;
00205   FltError result = pack_attr(datagram);
00206   if (result != FE_ok) {
00207     return result;
00208   }
00209 
00210   attr_filename.set_binary();
00211   ofstream attr;
00212   if (!attr_filename.open_write(attr)) {
00213     return FE_could_not_open;
00214   }
00215 
00216   attr.write((const char *)datagram.get_data(), datagram.get_length());
00217   if (attr.fail()) {
00218     return FE_write_error;
00219   }
00220   return FE_ok;
00221 }
00222 
00223 ////////////////////////////////////////////////////////////////////
00224 //     Function: FltTexture::extract_record
00225 //       Access: Protected, Virtual
00226 //  Description: Fills in the information in this record based on the
00227 //               information given in the indicated datagram, whose
00228 //               opcode has already been read.  Returns true on
00229 //               success, false if the datagram is invalid.
00230 ////////////////////////////////////////////////////////////////////
00231 bool FltTexture::
00232 extract_record(FltRecordReader &reader) {
00233   if (!FltRecord::extract_record(reader)) {
00234     return false;
00235   }
00236 
00237   nassertr(reader.get_opcode() == FO_texture, false);
00238   DatagramIterator &iterator = reader.get_iterator();
00239 
00240   if (_header->get_flt_version() < 1420) {
00241     _orig_filename = iterator.get_fixed_string(80);
00242   } else {
00243     _orig_filename = iterator.get_fixed_string(200);
00244   }
00245   _converted_filename = _header->convert_path(Filename::from_os_specific(_orig_filename), get_model_path());
00246   _pattern_index = iterator.get_be_int32();
00247   _x_location = iterator.get_be_int32();
00248   _y_location = iterator.get_be_int32();
00249 
00250   if (read_attr_data() != FE_ok) {
00251     nout << "Unable to read attribute file " << get_attr_filename() << "\n";
00252   }
00253 
00254   check_remaining_size(iterator);
00255   return true;
00256 }
00257 
00258 ////////////////////////////////////////////////////////////////////
00259 //     Function: FltTexture::build_record
00260 //       Access: Protected, Virtual
00261 //  Description: Fills up the current record on the FltRecordWriter with
00262 //               data for this record, but does not advance the
00263 //               writer.  Returns true on success, false if there is
00264 //               some error.
00265 ////////////////////////////////////////////////////////////////////
00266 bool FltTexture::
00267 build_record(FltRecordWriter &writer) const {
00268   if (!FltRecord::build_record(writer)) {
00269     return false;
00270   }
00271 
00272   writer.set_opcode(FO_texture);
00273   Datagram &datagram = writer.update_datagram();
00274 
00275   datagram.add_fixed_string(_orig_filename, 200);
00276   datagram.add_be_int32(_pattern_index);
00277   datagram.add_be_int32(_x_location);
00278   datagram.add_be_int32(_y_location);
00279 
00280   if (_header->get_auto_attr_update() == FltHeader::AU_always ||
00281       (_header->get_auto_attr_update() == FltHeader::AU_if_missing &&
00282        !get_attr_filename().exists())) {
00283     if (write_attr_data() != FE_ok) {
00284       nout << "Unable to write attribute file " << get_attr_filename() << "\n";
00285     }
00286   }
00287 
00288   return true;
00289 }
00290 
00291 ////////////////////////////////////////////////////////////////////
00292 //     Function: FltTexture::unpack_attr
00293 //       Access: Private
00294 //  Description: Reads the data from the attribute file.
00295 ////////////////////////////////////////////////////////////////////
00296 FltError FltTexture::
00297 unpack_attr(const Datagram &datagram) {
00298   DatagramIterator iterator(datagram);
00299 
00300   _num_texels_u = iterator.get_be_int32();
00301   _num_texels_v = iterator.get_be_int32();
00302   _real_world_size_u = iterator.get_be_int32();
00303   _real_world_size_v = iterator.get_be_int32();
00304   _up_vector_x = iterator.get_be_int32();
00305   _up_vector_y = iterator.get_be_int32();
00306   _file_format = (FileFormat)iterator.get_be_int32();
00307   _min_filter = (Minification)iterator.get_be_int32();
00308   _mag_filter = (Magnification)iterator.get_be_int32();
00309   _repeat = (RepeatType)iterator.get_be_int32();
00310   _repeat_u = (RepeatType)iterator.get_be_int32();
00311   _repeat_v = (RepeatType)iterator.get_be_int32();
00312   _modify_flag = iterator.get_be_int32();
00313   _x_pivot_point = iterator.get_be_int32();
00314   _y_pivot_point = iterator.get_be_int32();
00315   _env_type = (EnvironmentType)iterator.get_be_int32();
00316   _intensity_is_alpha = (iterator.get_be_int32() != 0);
00317   iterator.skip_bytes(4 * 8);
00318   iterator.skip_bytes(4);  // Undocumented padding.
00319   _float_real_world_size_u = iterator.get_be_float64();
00320   _float_real_world_size_v = iterator.get_be_float64();
00321   _imported_origin_code = iterator.get_be_int32();
00322   _kernel_version = iterator.get_be_int32();
00323   _internal_format = (InternalFormat)iterator.get_be_int32();
00324   _external_format = (ExternalFormat)iterator.get_be_int32();
00325   _use_mipmap_kernel = (iterator.get_be_int32() != 0);
00326   int i;
00327   for (i = 0; i < 8; i++) {
00328     _mipmap_kernel[i] = iterator.get_be_float32();
00329   }
00330   _use_lod_scale = (iterator.get_be_int32() != 0);
00331   for (i = 0; i < 8; i++) {
00332     _lod_scale[i]._lod = iterator.get_be_float32();
00333     _lod_scale[i]._scale = iterator.get_be_float32();
00334   }
00335   _clamp = iterator.get_be_float32();
00336   _mag_filter_alpha = (Magnification)iterator.get_be_int32();
00337   _mag_filter_color = (Magnification)iterator.get_be_int32();
00338   iterator.skip_bytes(4 + 4 * 8);
00339   _lambert_conic_central_meridian = iterator.get_be_float64();
00340   _lambert_conic_upper_latitude = iterator.get_be_float64();
00341   _lambert_conic_lower_latitude = iterator.get_be_float64();
00342   iterator.skip_bytes(8 + 4 * 5);
00343   _use_detail = (iterator.get_be_int32() != 0);
00344   _detail_j = iterator.get_be_int32();
00345   _detail_k = iterator.get_be_int32();
00346   _detail_m = iterator.get_be_int32();
00347   _detail_n = iterator.get_be_int32();
00348   _detail_scramble = iterator.get_be_int32();
00349   _use_tile = (iterator.get_be_int32() != 0);
00350   _tile_lower_left_u = iterator.get_be_float32();
00351   _tile_lower_left_v = iterator.get_be_float32();
00352   _tile_upper_right_u = iterator.get_be_float32();
00353   _tile_upper_right_v = iterator.get_be_float32();
00354   _projection = (ProjectionType)iterator.get_be_int32();
00355   _earth_model = (EarthModel)iterator.get_be_int32();
00356   iterator.skip_bytes(4);
00357   _utm_zone = iterator.get_be_int32();
00358   _image_origin = (ImageOrigin)iterator.get_be_int32();
00359   _geospecific_points_units = (PointsUnits)iterator.get_be_int32();
00360   _geospecific_hemisphere = (Hemisphere)iterator.get_be_int32();
00361   iterator.skip_bytes(4 + 4 + 149 * 4);
00362   iterator.skip_bytes(8);  // Undocumented padding.
00363   _comment = iterator.get_fixed_string(512);
00364 
00365   if (iterator.get_remaining_size() != 0) {
00366     iterator.skip_bytes(13 * 4);
00367     iterator.skip_bytes(4);  // Undocumented padding.
00368     _file_version = iterator.get_be_int32();
00369 
00370     // Now read the geospecific control points.
00371     _geospecific_control_points.clear();
00372     int num_points = iterator.get_be_int32();
00373     if (num_points > 0) {
00374       iterator.skip_bytes(4);
00375 
00376       while (num_points > 0) {
00377         GeospecificControlPoint gcp;
00378         gcp._uv[0] = iterator.get_be_float64();
00379         gcp._uv[1] = iterator.get_be_float64();
00380         gcp._real_earth[0] = iterator.get_be_float64();
00381         gcp._real_earth[1] = iterator.get_be_float64();
00382       }
00383     }
00384 
00385     if (iterator.get_remaining_size() != 0) {
00386       int num_defs = iterator.get_be_int32();
00387       while (num_defs > 0) {
00388         SubtextureDef def;
00389         def._name = iterator.get_fixed_string(32);
00390         def._left = iterator.get_be_int32();
00391         def._bottom = iterator.get_be_int32();
00392         def._right = iterator.get_be_int32();
00393         def._top = iterator.get_be_int32();
00394       }
00395     }
00396   }
00397 
00398   check_remaining_size(iterator);
00399   return FE_ok;
00400 }
00401 
00402 ////////////////////////////////////////////////////////////////////
00403 //     Function: FltTexture::pack_attr
00404 //       Access: Private
00405 //  Description: Packs the attribute data into a big datagram.
00406 ////////////////////////////////////////////////////////////////////
00407 FltError FltTexture::
00408 pack_attr(Datagram &datagram) const {
00409   datagram.add_be_int32(_num_texels_u);
00410   datagram.add_be_int32(_num_texels_v);
00411   datagram.add_be_int32(_real_world_size_u);
00412   datagram.add_be_int32(_real_world_size_v);
00413   datagram.add_be_int32(_up_vector_x);
00414   datagram.add_be_int32(_up_vector_y);
00415   datagram.add_be_int32(_file_format);
00416   datagram.add_be_int32(_min_filter);
00417   datagram.add_be_int32(_mag_filter);
00418   datagram.add_be_int32(_repeat);
00419   datagram.add_be_int32(_repeat_u);
00420   datagram.add_be_int32(_repeat_v);
00421   datagram.add_be_int32(_modify_flag);
00422   datagram.add_be_int32(_x_pivot_point);
00423   datagram.add_be_int32(_y_pivot_point);
00424   datagram.add_be_int32(_env_type);
00425   datagram.add_be_int32(_intensity_is_alpha);
00426   datagram.pad_bytes(4 * 8);
00427   datagram.pad_bytes(4);  // Undocumented padding.
00428   datagram.add_be_float64(_float_real_world_size_u);
00429   datagram.add_be_float64(_float_real_world_size_v);
00430   datagram.add_be_int32(_imported_origin_code);
00431   datagram.add_be_int32(_kernel_version);
00432   datagram.add_be_int32(_internal_format);
00433   datagram.add_be_int32(_external_format);
00434   datagram.add_be_int32(_use_mipmap_kernel);
00435   int i;
00436   for (i = 0; i < 8; i++) {
00437     datagram.add_be_float32(_mipmap_kernel[i]);
00438   }
00439   datagram.add_be_int32(_use_lod_scale);
00440   for (i = 0; i < 8; i++) {
00441     datagram.add_be_float32(_lod_scale[i]._lod);
00442     datagram.add_be_float32(_lod_scale[i]._scale);
00443   }
00444   datagram.add_be_float32(_clamp);
00445   datagram.add_be_int32(_mag_filter_alpha);
00446   datagram.add_be_int32(_mag_filter_color);
00447   datagram.pad_bytes(4 + 4 * 8);
00448   datagram.add_be_float64(_lambert_conic_central_meridian);
00449   datagram.add_be_float64(_lambert_conic_upper_latitude);
00450   datagram.add_be_float64(_lambert_conic_lower_latitude);
00451   datagram.pad_bytes(8 + 4 * 5);
00452   datagram.add_be_int32(_use_detail);
00453   datagram.add_be_int32(_detail_j);
00454   datagram.add_be_int32(_detail_k);
00455   datagram.add_be_int32(_detail_m);
00456   datagram.add_be_int32(_detail_n);
00457   datagram.add_be_int32(_detail_scramble);
00458   datagram.add_be_int32(_use_tile);
00459   datagram.add_be_float32(_tile_lower_left_u);
00460   datagram.add_be_float32(_tile_lower_left_v);
00461   datagram.add_be_float32(_tile_upper_right_u);
00462   datagram.add_be_float32(_tile_upper_right_v);
00463   datagram.add_be_int32(_projection);
00464   datagram.add_be_int32(_earth_model);
00465   datagram.pad_bytes(4);
00466   datagram.add_be_int32(_utm_zone);
00467   datagram.add_be_int32(_image_origin);
00468   datagram.add_be_int32(_geospecific_points_units);
00469   datagram.add_be_int32(_geospecific_hemisphere);
00470   datagram.pad_bytes(4 + 4 + 149 * 4);
00471   datagram.pad_bytes(8);  // Undocumented padding.
00472   datagram.add_fixed_string(_comment, 512);
00473   datagram.pad_bytes(13 * 4);
00474   datagram.pad_bytes(4);  // Undocumented padding.
00475   datagram.add_be_int32(_file_version);
00476 
00477   // Now write the geospecific control points.
00478   datagram.add_be_int32(_geospecific_control_points.size());
00479   if (!_geospecific_control_points.empty()) {
00480     datagram.pad_bytes(4);
00481     GeospecificControlPoints::const_iterator pi;
00482     for (pi = _geospecific_control_points.begin();
00483          pi != _geospecific_control_points.end();
00484          ++pi) {
00485       const GeospecificControlPoint &gcp = (*pi);
00486       datagram.add_be_float64(gcp._uv[0]);
00487       datagram.add_be_float64(gcp._uv[1]);
00488       datagram.add_be_float64(gcp._real_earth[0]);
00489       datagram.add_be_float64(gcp._real_earth[1]);
00490     }
00491   }
00492 
00493   // Also write out the subtexture definitions.
00494   datagram.add_be_int32(_subtexture_defs.size());
00495   SubtextureDefs::const_iterator di;
00496   for (di = _subtexture_defs.begin();
00497        di != _subtexture_defs.end();
00498        ++di) {
00499     const SubtextureDef &def = (*di);
00500     datagram.add_fixed_string(def._name, 31);
00501     datagram.add_int8(0);
00502     datagram.add_be_int32(def._left);
00503     datagram.add_be_int32(def._bottom);
00504     datagram.add_be_int32(def._right);
00505     datagram.add_be_int32(def._top);
00506   }
00507 
00508   return FE_ok;
00509 }
 All Classes Functions Variables Enumerations