diff --git a/pandatool/src/bam/Sources.pp b/pandatool/src/bam/Sources.pp index 044509b2f1..05299d482b 100644 --- a/pandatool/src/bam/Sources.pp +++ b/pandatool/src/bam/Sources.pp @@ -3,7 +3,8 @@ #define LOCAL_LIBS \ progbase #define OTHER_LIBS \ - cull:c loader:c egg:c sgraphutil:c sgattrib:c sgraph:c pnmimagetypes:c \ + cull:c loader:c egg:c sgraphutil:c sgattrib:c \ + sgraph:c pnmimagetypes:c \ graph:c putil:c express:c panda:m pandaexpress:m \ interrogatedb:c dtoolutil:c dconfig:c dtoolconfig:m dtool:m pystub #define UNIX_SYS_LIBS \ @@ -21,7 +22,7 @@ #define LOCAL_LIBS \ eggbase progbase #define OTHER_LIBS \ - loader:c egg2sg:c builder:c egg:c pnmimagetypes:c gobj:c \ + sgmanip:c loader:c egg2sg:c builder:c egg:c pnmimagetypes:c gobj:c \ chan:c graph:c putil:c \ express:c pandaegg:m panda:m pandaexpress:m \ interrogatedb:c dtoolutil:c dconfig:c dtoolconfig:m dtool:m pystub diff --git a/pandatool/src/bam/bamInfo.cxx b/pandatool/src/bam/bamInfo.cxx index f43d56bc21..6f0543bf86 100644 --- a/pandatool/src/bam/bamInfo.cxx +++ b/pandatool/src/bam/bamInfo.cxx @@ -26,6 +26,11 @@ BamInfo() { clear_runlines(); add_runline("[opts] input.bam [input.bam ... ]"); + add_option + ("ls", "", 0, + "List the scene graph hierarchy in the bam file.", + &BamInfo::dispatch_none, &_ls); + add_option ("t", "", 0, "List explicitly each transition in the hierarchy.", @@ -157,7 +162,7 @@ describe_scene_graph(Node *node) { nout << " " << num_nodes << " nodes, bounding volume is " << arc->get_bound() << "\n"; - if (_verbose_geoms || _verbose_transitions) { + if (_ls || _verbose_geoms || _verbose_transitions) { list_hierarchy(node, 0); } } @@ -192,16 +197,20 @@ list_hierarchy(Node *node, int indent_level) { int num_children = node->get_num_children(RenderRelation::get_class_type()); for (int i = 0; i < num_children; i++) { - NodeRelation *arc = node->get_child(RenderRelation::get_class_type(), i); - nout << "\n"; - indent(nout, indent_level + 2) << *arc << "\n"; + int next_indent = indent_level + 2; + NodeRelation *arc = node->get_child(RenderRelation::get_class_type(), i); if (_verbose_transitions) { - arc->write_transitions(nout, indent_level + 2); nout << "\n"; + indent(nout, next_indent) << *arc << "\n"; + + arc->write_transitions(nout, next_indent); + nout << "\n"; + + next_indent += 2; } - list_hierarchy(arc->get_child(), indent_level + 4); + list_hierarchy(arc->get_child(), next_indent); } } diff --git a/pandatool/src/bam/bamInfo.h b/pandatool/src/bam/bamInfo.h index d30c81e1d1..7102594826 100644 --- a/pandatool/src/bam/bamInfo.h +++ b/pandatool/src/bam/bamInfo.h @@ -39,8 +39,9 @@ private: typedef vector Filenames; Filenames _filenames; - bool _verbose_geoms; + bool _ls; bool _verbose_transitions; + bool _verbose_geoms; int _num_scene_graphs; SceneGraphAnalyzer _analyzer; diff --git a/pandatool/src/bam/eggToBam.cxx b/pandatool/src/bam/eggToBam.cxx index e41dd6c38f..4047ac808b 100644 --- a/pandatool/src/bam/eggToBam.cxx +++ b/pandatool/src/bam/eggToBam.cxx @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -42,6 +43,23 @@ EggToBam() : "whatever is specified by the bam-texture-mode Configrc variable.", &EggToBam::dispatch_none, &_keep_paths); + add_option + ("fl", "flag", 0, + "Specifies whether to flatten the egg hierarchy after it is loaded. " + "If flag is zero, the egg hierarchy will not be flattened, but will " + "instead be written to the bam file exactly as it is. If flag is " + "non-zero, the hierarchy will be flattened so that unnecessary nodes " + "(usually group nodes with only one child) are eliminated. The default " + "if this is not specified is taken from the egg-flatten Configrc " + "variable.", + &EggToBam::dispatch_int, &_has_egg_flatten, &_egg_flatten); + + add_option + ("ls", "", 0, + "Writes a scene graph listing to standard output after the egg " + "file has been loaded, showing the nodes that will be written out.", + &EggToBam::dispatch_none, &_ls); + add_option ("C", "quality", 0, "Specify the quality level for lossy channel compression. If this " @@ -65,6 +83,8 @@ EggToBam() : " file. This may be " "one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default " "is z-up."); + + _egg_flatten = 0; } //////////////////////////////////////////////////////////////////// @@ -81,6 +101,12 @@ run() { bam_texture_mode = BTM_fullpath; } + if (_has_egg_flatten) { + // If the user specified some -fl, we need to set the + // corresponding Configrc variable. + egg_flatten = (_egg_flatten != 0); + } + if (_compression_off) { // If the user specified -NC, turn off channel compression. compress_channels = false; @@ -104,6 +130,12 @@ run() { exit(1); } + if (_ls) { + // If we wanted to list the contents, we need a NodePath. + NodePath np(root); + np.ls(); + } + // This should be guaranteed because we pass false to the // constructor, above. nassertv(has_output_filename()); diff --git a/pandatool/src/bam/eggToBam.h b/pandatool/src/bam/eggToBam.h index 61784f8dc4..ea542c1ddb 100644 --- a/pandatool/src/bam/eggToBam.h +++ b/pandatool/src/bam/eggToBam.h @@ -21,6 +21,9 @@ public: void run(); bool _keep_paths; + bool _has_egg_flatten; + int _egg_flatten; + bool _ls; bool _has_compression_quality; int _compression_quality; bool _compression_off; diff --git a/pandatool/src/flt/fltGeometry.cxx b/pandatool/src/flt/fltGeometry.cxx index 67675b78b2..31f0a58dd0 100644 --- a/pandatool/src/flt/fltGeometry.cxx +++ b/pandatool/src/flt/fltGeometry.cxx @@ -178,12 +178,14 @@ extract_record(FltRecordReader &reader) { if (!_alt_packed_color.extract_record(reader)) { return false; } - - _texture_mapping_index = iterator.get_be_int16(); - iterator.skip_bytes(2); - _color_index = iterator.get_be_uint32(); - _alt_color_index = iterator.get_be_uint32(); - iterator.skip_bytes(2 + 2); + + if (_header->get_flt_version() >= 15.2) { + _texture_mapping_index = iterator.get_be_int16(); + iterator.skip_bytes(2); + _color_index = iterator.get_be_uint32(); + _alt_color_index = iterator.get_be_uint32(); + iterator.skip_bytes(2 + 2); + } return true; } diff --git a/pandatool/src/flt/fltHeader.cxx b/pandatool/src/flt/fltHeader.cxx index fde189104c..06ffcc1ad1 100644 --- a/pandatool/src/flt/fltHeader.cxx +++ b/pandatool/src/flt/fltHeader.cxx @@ -69,6 +69,7 @@ FltHeader() : FltBeadID(this) { _vertex_lookups_stale = false; _current_vertex_offset = 0; _got_color_palette = false; + _got_14_material_palette = false; _got_eyepoint_trackplane_palette = false; _auto_attr_update = AU_if_missing; @@ -236,7 +237,7 @@ get_flt_version() const { //////////////////////////////////////////////////////////////////// double FltHeader:: min_flt_version() { - return 15.2; + return 14.2; } //////////////////////////////////////////////////////////////////// @@ -1150,25 +1151,28 @@ extract_record(FltRecordReader &reader) { iterator.skip_bytes(2); _next_road_id = iterator.get_be_int16(); _next_cat_id = iterator.get_be_int16(); - iterator.skip_bytes(2 + 2 + 2 + 2); - _earth_model = (EarthModel)iterator.get_be_int32(); + + if (get_flt_version() >= 15.2 && iterator.get_remaining_size() > 0) { + iterator.skip_bytes(2 + 2 + 2 + 2); + _earth_model = (EarthModel)iterator.get_be_int32(); - // Undocumented padding. - iterator.skip_bytes(4); - - if (get_flt_version() >= 15.6 && iterator.get_remaining_size() > 0) { - _next_adaptive_id = iterator.get_be_int16(); - _next_curve_id = iterator.get_be_int16(); + // Undocumented padding. iterator.skip_bytes(4); - if (get_flt_version() >= 15.7 && iterator.get_remaining_size() > 0) { - _delta_z = iterator.get_be_float64(); - _radius = iterator.get_be_float64(); - _next_mesh_id = iterator.get_be_int16(); - iterator.skip_bytes(2); - - // Undocumented padding. + if (get_flt_version() >= 15.6 && iterator.get_remaining_size() > 0) { + _next_adaptive_id = iterator.get_be_int16(); + _next_curve_id = iterator.get_be_int16(); iterator.skip_bytes(4); + + if (get_flt_version() >= 15.7 && iterator.get_remaining_size() > 0) { + _delta_z = iterator.get_be_float64(); + _radius = iterator.get_be_float64(); + _next_mesh_id = iterator.get_be_int16(); + iterator.skip_bytes(2); + + // Undocumented padding. + iterator.skip_bytes(4); + } } } @@ -1207,6 +1211,9 @@ extract_ancillary(FltRecordReader &reader) { case FO_15_material: return extract_material(reader); + case FO_14_material_palette: + return extract_14_material_palette(reader); + case FO_texture: return extract_texture(reader); @@ -1409,12 +1416,14 @@ extract_color_palette(FltRecordReader &reader) { while (iterator.get_remaining_size() > 0) { int entry_length = iterator.get_be_uint16(); iterator.skip_bytes(2); - int color_index = iterator.get_be_int16(); - iterator.skip_bytes(2); + if (iterator.get_remaining_size() > 0) { + int color_index = iterator.get_be_int16(); + iterator.skip_bytes(2); - int name_length = entry_length - 8; - nassertr(color_index >= 0 && color_index < (int)_colors.size(), false); - _color_names[color_index] = iterator.get_fixed_string(name_length); + int name_length = entry_length - 8; + nassertr(color_index >= 0 && color_index < (int)_colors.size(), false); + _color_names[color_index] = iterator.get_fixed_string(name_length); + } } check_remaining_size(iterator); @@ -1428,7 +1437,7 @@ extract_color_palette(FltRecordReader &reader) { //////////////////////////////////////////////////////////////////// bool FltHeader:: extract_material(FltRecordReader &reader) { - FltMaterial *material = new FltMaterial(this); + PT(FltMaterial) material = new FltMaterial(this); if (!material->extract_record(reader)) { return false; } @@ -1437,6 +1446,40 @@ extract_material(FltRecordReader &reader) { return true; } +//////////////////////////////////////////////////////////////////// +// Function: FltHeader::extract_14_material_palette +// Access: Private +// Description: Reads the v14.2 material palette. +//////////////////////////////////////////////////////////////////// +bool FltHeader:: +extract_14_material_palette(FltRecordReader &reader) { + nassertr(reader.get_opcode() == FO_14_material_palette, false); + DatagramIterator &iterator = reader.get_iterator(); + + if (_got_14_material_palette) { + nout << "Warning: multiple material palettes found.\n"; + } + _got_14_material_palette = true; + + static const int expected_material_entries = 64; + + _materials.clear(); + for (int i = 0; i < expected_material_entries; i++) { + if (iterator.get_remaining_size() == 0) { + // An early end to the palette is acceptable. + return true; + } + PT(FltMaterial) material = new FltMaterial(this); + if (!material->extract_14_record(i, iterator)) { + return false; + } + add_material(material); + } + + check_remaining_size(iterator); + return true; +} + //////////////////////////////////////////////////////////////////// // Function: FltHeader::extract_texture // Access: Private diff --git a/pandatool/src/flt/fltHeader.h b/pandatool/src/flt/fltHeader.h index 5c0f6480d4..28e87c0638 100644 --- a/pandatool/src/flt/fltHeader.h +++ b/pandatool/src/flt/fltHeader.h @@ -258,6 +258,7 @@ private: // Support for the material palette. + bool _got_14_material_palette; typedef map Materials; Materials _materials; @@ -290,6 +291,7 @@ private: bool extract_vertex(FltRecordReader &reader); bool extract_color_palette(FltRecordReader &reader); bool extract_material(FltRecordReader &reader); + bool extract_14_material_palette(FltRecordReader &reader); bool extract_texture(FltRecordReader &reader); bool extract_texture_map(FltRecordReader &reader); bool extract_light_source(FltRecordReader &reader); diff --git a/pandatool/src/flt/fltMaterial.cxx b/pandatool/src/flt/fltMaterial.cxx index 285021abf3..36647796f8 100644 --- a/pandatool/src/flt/fltMaterial.cxx +++ b/pandatool/src/flt/fltMaterial.cxx @@ -104,3 +104,36 @@ build_record(FltRecordWriter &writer) const { return true; } + +//////////////////////////////////////////////////////////////////// +// Function: FltMaterial::extract_14_record +// Access: Public +// Description: Fills in the information in this record based on the +// information from the current position within the v14 +// material palette. Leaves the iterator at the +// beginning of the next material. +//////////////////////////////////////////////////////////////////// +bool FltMaterial:: +extract_14_record(int index, DatagramIterator &di) { + _material_index = index; + + _ambient[0] = di.get_be_float32(); + _ambient[1] = di.get_be_float32(); + _ambient[2] = di.get_be_float32(); + _diffuse[0] = di.get_be_float32(); + _diffuse[1] = di.get_be_float32(); + _diffuse[2] = di.get_be_float32(); + _specular[0] = di.get_be_float32(); + _specular[1] = di.get_be_float32(); + _specular[2] = di.get_be_float32(); + _emissive[0] = di.get_be_float32(); + _emissive[1] = di.get_be_float32(); + _emissive[2] = di.get_be_float32(); + _shininess = di.get_be_float32(); + _alpha = di.get_be_float32(); + _flags = di.get_be_uint32(); + _material_name = di.get_fixed_string(12); + di.skip_bytes(4 * 28); + + return true; +} diff --git a/pandatool/src/flt/fltMaterial.h b/pandatool/src/flt/fltMaterial.h index aaa1974451..a7c22ab784 100644 --- a/pandatool/src/flt/fltMaterial.h +++ b/pandatool/src/flt/fltMaterial.h @@ -12,6 +12,8 @@ #include +class DatagramIterator; + //////////////////////////////////////////////////////////////////// // Class : FltMaterial // Description : Represents a single material in the material palette. @@ -38,6 +40,9 @@ protected: virtual bool extract_record(FltRecordReader &reader); virtual bool build_record(FltRecordWriter &writer) const; +public: + bool extract_14_record(int index, DatagramIterator &di); + public: virtual TypeHandle get_type() const { return get_class_type(); diff --git a/pandatool/src/flt/fltRecord.cxx b/pandatool/src/flt/fltRecord.cxx index 3d18ae8607..3f90f15850 100644 --- a/pandatool/src/flt/fltRecord.cxx +++ b/pandatool/src/flt/fltRecord.cxx @@ -413,6 +413,7 @@ is_ancillary(FltOpcode opcode) { case FO_local_vertex_pool: case FO_cat_data: + case FO_14_material_palette: case FO_vertex_palette: case FO_vertex_c: case FO_vertex_cn: diff --git a/pandatool/src/flt/fltVertex.cxx b/pandatool/src/flt/fltVertex.cxx index cf3f2bf7bb..3a3ca4335a 100644 --- a/pandatool/src/flt/fltVertex.cxx +++ b/pandatool/src/flt/fltVertex.cxx @@ -171,12 +171,14 @@ extract_record(FltRecordReader &reader) { if (!_packed_color.extract_record(reader)) { return false; } - _color_index = iterator.get_be_uint32(); + if (_header->get_flt_version() >= 15.2) { + _color_index = iterator.get_be_uint32(); - if (_has_normal) { - // If we extracted a normal, our double-word alignment is off; now - // we have a few extra bytes to ignore. - iterator.skip_bytes(4); + if (_has_normal && iterator.get_remaining_size() > 0) { + // If we extracted a normal, our double-word alignment is off; now + // we have a few extra bytes to ignore. + iterator.skip_bytes(4); + } } check_remaining_size(iterator);