00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00026
00027
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
00090
00091
00092
00093
00094
00095
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
00105
00106
00107
00108 Filename FltTexture::
00109 get_texture_filename() const {
00110 return _converted_filename;
00111 }
00112
00113
00114
00115
00116
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
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
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
00147
00148
00149
00150
00151
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
00163
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
00186
00187
00188
00189
00190
00191 FltError FltTexture::
00192 write_attr_data() const {
00193 return write_attr_data(get_attr_filename());
00194 }
00195
00196
00197
00198
00199
00200
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
00225
00226
00227
00228
00229
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
00260
00261
00262
00263
00264
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
00293
00294
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);
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);
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);
00368 _file_version = iterator.get_be_int32();
00369
00370
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
00404
00405
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);
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);
00472 datagram.add_fixed_string(_comment, 512);
00473 datagram.pad_bytes(13 * 4);
00474 datagram.pad_bytes(4);
00475 datagram.add_be_int32(_file_version);
00476
00477
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
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 }