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