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