Panda3D
|
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 }