00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "fltRecord.h"
00016 #include "fltRecordReader.h"
00017 #include "fltRecordWriter.h"
00018 #include "fltHeader.h"
00019 #include "fltGroup.h"
00020 #include "fltObject.h"
00021 #include "fltFace.h"
00022 #include "fltCurve.h"
00023 #include "fltMesh.h"
00024 #include "fltLocalVertexPool.h"
00025 #include "fltMeshPrimitive.h"
00026 #include "fltVertexList.h"
00027 #include "fltLOD.h"
00028 #include "fltInstanceDefinition.h"
00029 #include "fltInstanceRef.h"
00030 #include "fltUnsupportedRecord.h"
00031 #include "fltExternalReference.h"
00032 #include "fltVectorRecord.h"
00033 #include "config_flt.h"
00034
00035 #include "dcast.h"
00036 #include "indent.h"
00037 #include "datagramIterator.h"
00038
00039 #include <assert.h>
00040
00041 TypeHandle FltRecord::_type_handle;
00042
00043
00044
00045
00046
00047
00048 FltRecord::
00049 FltRecord(FltHeader *header) :
00050 _header(header)
00051 {
00052 }
00053
00054
00055
00056
00057
00058
00059 FltRecord::
00060 ~FltRecord() {
00061 }
00062
00063
00064
00065
00066
00067
00068
00069 int FltRecord::
00070 get_num_children() const {
00071 return _children.size();
00072 }
00073
00074
00075
00076
00077
00078
00079 FltRecord *FltRecord::
00080 get_child(int n) const {
00081 nassertr(n >= 0 && n < (int)_children.size(), (FltRecord *)NULL);
00082 return _children[n];
00083 }
00084
00085
00086
00087
00088
00089
00090 void FltRecord::
00091 clear_children() {
00092 _children.clear();
00093 }
00094
00095
00096
00097
00098
00099
00100
00101 void FltRecord::
00102 add_child(FltRecord *child) {
00103 _children.push_back(child);
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 int FltRecord::
00115 get_num_subfaces() const {
00116 return _subfaces.size();
00117 }
00118
00119
00120
00121
00122
00123
00124 FltRecord *FltRecord::
00125 get_subface(int n) const {
00126 nassertr(n >= 0 && n < (int)_subfaces.size(), (FltRecord *)NULL);
00127 return _subfaces[n];
00128 }
00129
00130
00131
00132
00133
00134
00135 void FltRecord::
00136 clear_subfaces() {
00137 _subfaces.clear();
00138 }
00139
00140
00141
00142
00143
00144
00145
00146 void FltRecord::
00147 add_subface(FltRecord *subface) {
00148 _subfaces.push_back(subface);
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 int FltRecord::
00160 get_num_extensions() const {
00161 return _extensions.size();
00162 }
00163
00164
00165
00166
00167
00168
00169 FltRecord *FltRecord::
00170 get_extension(int n) const {
00171 nassertr(n >= 0 && n < (int)_extensions.size(), (FltRecord *)NULL);
00172 return _extensions[n];
00173 }
00174
00175
00176
00177
00178
00179
00180 void FltRecord::
00181 clear_extensions() {
00182 _extensions.clear();
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192 void FltRecord::
00193 add_extension(FltRecord *extension) {
00194 _extensions.push_back(extension);
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 int FltRecord::
00208 get_num_ancillary() const {
00209 return _ancillary.size();
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 FltRecord *FltRecord::
00219 get_ancillary(int n) const {
00220 nassertr(n >= 0 && n < (int)_ancillary.size(), (FltRecord *)NULL);
00221 return _ancillary[n];
00222 }
00223
00224
00225
00226
00227
00228
00229
00230 void FltRecord::
00231 clear_ancillary() {
00232 _ancillary.clear();
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 void FltRecord::
00253 add_ancillary(FltRecord *ancillary) {
00254 _ancillary.push_back(ancillary);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263 bool FltRecord::
00264 has_comment() const {
00265 return !_comment.empty();
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 const string &FltRecord::
00275 get_comment() const {
00276 return _comment;
00277 }
00278
00279
00280
00281
00282
00283
00284 void FltRecord::
00285 clear_comment() {
00286 _comment = "";
00287 }
00288
00289
00290
00291
00292
00293
00294 void FltRecord::
00295 set_comment(const string &comment) {
00296 _comment = comment;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 void FltRecord::
00313 check_remaining_size(const DatagramIterator &di, const string &name) const {
00314 if (di.get_remaining_size() == 0) {
00315 return;
00316 }
00317
00318 if (_header->get_flt_version() <= _header->max_flt_version()) {
00319 nout << "Warning! Ignoring extra " << di.get_remaining_size()
00320 << " bytes at the end of a ";
00321 if (name.empty()) {
00322 nout << get_type();
00323 } else {
00324 nout << name;
00325 }
00326 nout << " record.\n";
00327 }
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 void FltRecord::
00340 apply_converted_filenames() {
00341 Records::const_iterator ci;
00342 for (ci = _subfaces.begin(); ci != _subfaces.end(); ++ci) {
00343 (*ci)->apply_converted_filenames();
00344 }
00345 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00346 (*ci)->apply_converted_filenames();
00347 }
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 void FltRecord::
00359 output(ostream &out) const {
00360 out << get_type();
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 void FltRecord::
00372 write(ostream &out, int indent_level) const {
00373 indent(out, indent_level) << *this;
00374 write_children(out, indent_level);
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 void FltRecord::
00385 write_children(ostream &out, int indent_level) const {
00386 if (!_ancillary.empty()) {
00387 out << " + " << _ancillary.size() << " ancillary";
00388 }
00389 if (!_extensions.empty()) {
00390 out << " + " << _extensions.size() << " extensions";
00391 }
00392 if (!_subfaces.empty()) {
00393 out << " [";
00394 Records::const_iterator ci;
00395 for (ci = _subfaces.begin(); ci != _subfaces.end(); ++ci) {
00396 out << " " << *(*ci);
00397 }
00398 out << " ]";
00399 }
00400 if (!_children.empty()) {
00401 out << " {\n";
00402 Records::const_iterator ci;
00403 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00404 (*ci)->write(out, indent_level + 2);
00405 }
00406 indent(out, indent_level) << "}\n";
00407 } else {
00408 out << "\n";
00409 }
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 bool FltRecord::
00429 is_ancillary(FltOpcode opcode) {
00430 switch (opcode) {
00431 case FO_comment:
00432 case FO_long_id:
00433 case FO_multitexture:
00434 case FO_uv_list:
00435 case FO_replicate:
00436 case FO_road_zone:
00437 case FO_transform_matrix:
00438 case FO_rotate_about_edge:
00439 case FO_translate:
00440 case FO_scale:
00441 case FO_rotate_about_point:
00442 case FO_rotate_and_scale:
00443 case FO_put:
00444 case FO_general_matrix:
00445 case FO_vector:
00446 case FO_bounding_box:
00447 case FO_bounding_sphere:
00448 case FO_bounding_cylinder:
00449 case FO_bv_center:
00450 case FO_bv_orientation:
00451 case FO_local_vertex_pool:
00452 case FO_cat_data:
00453
00454 case FO_14_material_palette:
00455 case FO_vertex_palette:
00456 case FO_vertex_c:
00457 case FO_vertex_cn:
00458 case FO_vertex_cnu:
00459 case FO_vertex_cu:
00460 case FO_color_palette:
00461 case FO_name_table:
00462 case FO_15_material:
00463 case FO_texture:
00464 case FO_eyepoint_palette:
00465 case FO_light_definition:
00466 case FO_texture_map_palette:
00467 return true;
00468
00469 case FO_header:
00470 case FO_mesh:
00471 case FO_mesh_primitive:
00472 case FO_group:
00473 case FO_object:
00474 case FO_face:
00475 case FO_light_point:
00476 case FO_dof:
00477 case FO_vertex_list:
00478 case FO_morph_list:
00479 case FO_bsp:
00480 case FO_external_ref:
00481 case FO_lod:
00482 case FO_sound:
00483 case FO_light_source:
00484 case FO_road_segment:
00485 case FO_road_construction:
00486 case FO_road_path:
00487 case FO_clip_region:
00488 case FO_text:
00489 case FO_switch:
00490 case FO_cat:
00491 case FO_extension:
00492 case FO_curve:
00493 return false;
00494
00495 case FO_push:
00496 case FO_pop:
00497 case FO_push_face:
00498 case FO_pop_face:
00499 case FO_push_attribute:
00500 case FO_pop_attribute:
00501 case FO_push_extension:
00502 case FO_pop_extension:
00503 case FO_instance:
00504 case FO_instance_ref:
00505 return false;
00506
00507 default:
00508 nout << "Don't know whether " << opcode << " is ancillary.\n";
00509 return false;
00510 }
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520 FltRecord *FltRecord::
00521 create_new_record(FltOpcode opcode) const {
00522 switch (opcode) {
00523 case FO_group:
00524 return new FltGroup(_header);
00525
00526 case FO_object:
00527 return new FltObject(_header);
00528
00529 case FO_face:
00530 return new FltFace(_header);
00531
00532 case FO_curve:
00533 return new FltCurve(_header);
00534
00535 case FO_mesh:
00536 return new FltMesh(_header);
00537
00538 case FO_local_vertex_pool:
00539 return new FltLocalVertexPool(_header);
00540
00541 case FO_mesh_primitive:
00542 return new FltMeshPrimitive(_header);
00543
00544 case FO_vertex_list:
00545 return new FltVertexList(_header);
00546
00547 case FO_lod:
00548 return new FltLOD(_header);
00549
00550 case FO_instance:
00551 return new FltInstanceDefinition(_header);
00552
00553 case FO_instance_ref:
00554 return new FltInstanceRef(_header);
00555
00556 case FO_external_ref:
00557 return new FltExternalReference(_header);
00558
00559 case FO_vector:
00560 return new FltVectorRecord(_header);
00561
00562 default:
00563 nout << "Ignoring unsupported record " << opcode << "\n";
00564 return new FltUnsupportedRecord(_header);
00565 }
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 FltError FltRecord::
00580 read_record_and_children(FltRecordReader &reader) {
00581 if (!extract_record(reader)) {
00582 nout << "Could not extract record for " << *this << "\n";
00583 assert(!flt_error_abort);
00584 return FE_invalid_record;
00585 }
00586 FltError result = reader.advance();
00587 if (result == FE_end_of_file) {
00588 return FE_ok;
00589 } else if (result != FE_ok) {
00590 return result;
00591 }
00592
00593 while (true) {
00594 if (extract_ancillary(reader)) {
00595
00596
00597 } else if (reader.get_opcode() == FO_push) {
00598
00599 result = reader.advance();
00600 if (result != FE_ok) {
00601 return result;
00602 }
00603
00604 while (reader.get_opcode() != FO_pop) {
00605 PT(FltRecord) child = create_new_record(reader.get_opcode());
00606 FltError result = child->read_record_and_children(reader);
00607 if (result != FE_ok) {
00608 return result;
00609 }
00610
00611 if (child->is_of_type(FltInstanceDefinition::get_class_type())) {
00612
00613
00614
00615 _header->add_instance(DCAST(FltInstanceDefinition, child));
00616
00617 } else {
00618 add_child(child);
00619 }
00620
00621 if (reader.eof() || reader.error()) {
00622 assert(!flt_error_abort);
00623 return FE_end_of_file;
00624 }
00625 }
00626
00627 } else if (reader.get_opcode() == FO_push_face) {
00628
00629 result = reader.advance();
00630 if (result != FE_ok) {
00631 return result;
00632 }
00633
00634 while (reader.get_opcode() != FO_pop_face) {
00635 PT(FltRecord) subface = create_new_record(reader.get_opcode());
00636 FltError result = subface->read_record_and_children(reader);
00637 if (result != FE_ok) {
00638 return result;
00639 }
00640 add_subface(subface);
00641 if (reader.eof() || reader.error()) {
00642 assert(!flt_error_abort);
00643 return FE_end_of_file;
00644 }
00645 }
00646
00647 } else if (reader.get_opcode() == FO_push_extension) {
00648
00649 result = reader.advance();
00650 if (result != FE_ok) {
00651 return result;
00652 }
00653
00654 while (reader.get_opcode() != FO_pop_extension) {
00655 PT(FltRecord) extension = create_new_record(reader.get_opcode());
00656 FltError result = extension->read_record_and_children(reader);
00657 if (result != FE_ok) {
00658 return result;
00659 }
00660 add_extension(extension);
00661 if (reader.eof() || reader.error()) {
00662 assert(!flt_error_abort);
00663 return FE_end_of_file;
00664 }
00665 }
00666
00667 } else if (is_ancillary(reader.get_opcode())) {
00668
00669 PT(FltRecord) ancillary = create_new_record(reader.get_opcode());
00670 ancillary->extract_record(reader);
00671 _ancillary.push_back(ancillary);
00672
00673 } else {
00674
00675 return FE_ok;
00676 }
00677
00678
00679 result = reader.advance(true);
00680 if (reader.eof() || result != FE_ok) {
00681 return result;
00682 }
00683 }
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 bool FltRecord::
00695 extract_record(FltRecordReader &) {
00696 return true;
00697 }
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 bool FltRecord::
00709 extract_ancillary(FltRecordReader &reader) {
00710 if (reader.get_opcode() == FO_comment) {
00711 _comment = reader.get_iterator().get_remaining_bytes();
00712 return true;
00713 }
00714
00715 return false;
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725 FltError FltRecord::
00726 write_record_and_children(FltRecordWriter &writer) const {
00727
00728 if (!build_record(writer)) {
00729 assert(!flt_error_abort);
00730 return FE_bad_data;
00731 }
00732
00733 FltError result = writer.advance();
00734 if (result != FE_ok) {
00735 return result;
00736 }
00737
00738
00739 result = write_ancillary(writer);
00740 if (result != FE_ok) {
00741 return result;
00742 }
00743 Records::const_iterator ci;
00744 for (ci = _ancillary.begin(); ci != _ancillary.end(); ++ci) {
00745 if (!(*ci)->build_record(writer)) {
00746 assert(!flt_error_abort);
00747 return FE_bad_data;
00748 }
00749 result = writer.advance();
00750 if (result != FE_ok) {
00751 return result;
00752 }
00753 }
00754
00755
00756 if (!_extensions.empty()) {
00757 result = writer.write_record(FO_push_face);
00758 if (result != FE_ok) {
00759 return result;
00760 }
00761
00762 for (ci = _extensions.begin(); ci != _extensions.end(); ++ci) {
00763 (*ci)->write_record_and_children(writer);
00764 }
00765
00766 result = writer.write_record(FO_pop_face);
00767 if (result != FE_ok) {
00768 return result;
00769 }
00770 }
00771
00772
00773 if (!_children.empty()) {
00774 result = writer.write_record(FO_push);
00775 if (result != FE_ok) {
00776 return result;
00777 }
00778
00779 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00780 (*ci)->write_record_and_children(writer);
00781 }
00782
00783 result = writer.write_record(FO_pop);
00784 if (result != FE_ok) {
00785 return result;
00786 }
00787 }
00788
00789
00790
00791 if (!_subfaces.empty()) {
00792 result = writer.write_record(FO_push_face);
00793 if (result != FE_ok) {
00794 return result;
00795 }
00796
00797 for (ci = _subfaces.begin(); ci != _subfaces.end(); ++ci) {
00798 (*ci)->write_record_and_children(writer);
00799 }
00800
00801 result = writer.write_record(FO_pop_face);
00802 if (result != FE_ok) {
00803 return result;
00804 }
00805 }
00806
00807 return FE_ok;
00808 }
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 bool FltRecord::
00819 build_record(FltRecordWriter &) const {
00820 return true;
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
00830 FltError FltRecord::
00831 write_ancillary(FltRecordWriter &writer) const {
00832 if (!_comment.empty()) {
00833 Datagram dc(_comment);
00834 FltError result = writer.write_record(FO_comment, dc);
00835 if (result != FE_ok) {
00836 return result;
00837 }
00838 }
00839 return FE_ok;
00840 }