18 #include "pandaNode.h"
21 #include "recorderHeader.h"
22 #include "recorderFrame.h"
23 #include "recorderTable.h"
26 #include "bamCacheRecord.h"
27 #include "bamCacheIndex.h"
37 set_program_brief(
"describe the contents of .bam files");
38 set_program_description
39 (
"This program scans one or more Bam files--Panda's Binary Animation "
40 "and Models native binary format--and describes their contents.");
43 add_runline(
"[opts] input.bam [input.bam ... ]");
47 "List the scene graph hierarchy in the bam file.",
48 &BamInfo::dispatch_none, &_ls);
52 "List explicitly each transition in the hierarchy.",
53 &BamInfo::dispatch_none, &_verbose_transitions);
57 "Output verbose information about the each Geom in the Bam file.",
58 &BamInfo::dispatch_none, &_verbose_geoms);
60 _num_scene_graphs = 0;
73 Filenames::const_iterator fi;
74 for (fi = _filenames.begin(); fi != _filenames.end(); ++fi) {
80 if (_num_scene_graphs > 0) {
81 nout <<
"\nScene graph statistics:\n";
82 _analyzer.
write(nout, 2);
101 nout <<
"You must specify the Bam file(s) to read on the command line.\n";
105 ProgramBase::Args::const_iterator ai;
106 for (ai = args.begin(); ai != args.end(); ++ai) {
107 _filenames.push_back(*ai);
121 get_info(
const Filename &filename) {
125 nout <<
"Unable to read.\n";
129 const char *endian =
"little-endian";
131 endian =
"big-endian";
133 int float_width = 32;
140 <<
", " << endian <<
", " << float_width <<
"-bit floats.\n";
157 objects.push_back(
object);
162 nout <<
"Unable to fully resolve file.\n";
169 if (objects.size() == 1 &&
170 objects[0]->is_of_type(PandaNode::get_class_type())) {
171 describe_scene_graph(DCAST(
PandaNode, objects[0]));
173 }
else if (objects.size() == 1 &&
174 objects[0]->is_of_type(Texture::get_class_type())) {
175 describe_texture(DCAST(
Texture, objects[0]));
177 }
else if (objects.size() == 1 &&
178 objects[0]->is_of_type(BamCacheIndex::get_class_type())) {
181 }
else if (!objects.empty() && objects[0]->is_of_type(RecorderHeader::get_class_type())) {
185 nout <<
"file contains " << objects.size() <<
" objects:\n";
186 for (
int i = 0; i < (int)objects.size(); i++) {
187 describe_general_object(objects[i]);
211 root->add_child(node);
214 int num_nodes = _analyzer.get_num_nodes();
215 _analyzer.add_node(node);
216 num_nodes = _analyzer.get_num_nodes() - num_nodes;
218 nout << " " << num_nodes << " nodes, bounding volume is "
219 << *root->get_bounds() << "\n";
221 if (_ls || _verbose_geoms || _verbose_transitions) {
222 list_hierarchy(node, 0);
232 describe_texture(
Texture *tex) {
244 index->write(nout, 2);
255 char time_buffer[1024];
256 strftime(time_buffer, 1024,
"%c",
257 localtime(&header->_start_time));
260 double last_timestamp = 0.0;
262 for (
size_t i = 1; i < objects.size(); i++) {
263 if (objects[i]->is_of_type(RecorderFrame::get_class_type())) {
265 if (frame->_table_changed) {
266 RecorderTable::Recorders::const_iterator ri;
267 for (ri = frame->_table->_recorders.begin();
268 ri != frame->_table->_recorders.end();
270 recorders.insert((*ri).first);
273 last_timestamp = frame->_timestamp;
277 nout <<
"Session, " << last_timestamp
278 <<
" secs, " << objects.size() - 1 <<
" frames, "
279 << time_buffer <<
".\n"
282 ni != recorders.end();
284 nout <<
" " << (*ni);
299 nout <<
" " <<
object->get_type() <<
"\n";
309 list_hierarchy(
PandaNode *node,
int indent_level) {
310 indent(nout, indent_level) << *node;
312 if (_verbose_transitions) {
314 if (!node->get_transform()->is_identity()) {
315 node->get_transform()->write(nout, indent_level);
317 if (!node->get_state()->is_empty()) {
318 node->get_state()->write(nout, indent_level);
320 if (!node->get_effects()->is_empty()) {
321 node->get_effects()->write(nout, indent_level);
325 if (!node->get_transform()->is_identity()) {
326 nout <<
" " << *node->get_transform();
328 if (!node->get_state()->is_empty()) {
329 nout <<
" " << *node->get_state();
331 if (!node->get_effects()->is_empty()) {
332 nout <<
" " << *node->get_effects();
339 DCAST_INTO_V(geom_node, node);
344 for (
int i = 0; i < num_children; i++) {
346 list_hierarchy(child, indent_level + 2);
350 int main(
int argc,
char *argv[]) {
The principle public interface to reading and writing Bam disk files.
void write_verbose(ostream &out, int indent_level) const
Writes a detailed description of all the Geoms in the node.
A basic node of the scene graph or data graph.
bool open_read(const Filename &bam_filename, bool report_errors=true)
Attempts to open the indicated filename for reading.
bool resolve()
This must be called after one or more objects have been read via calls to read_object() in order to r...
bool get_file_stdfloat_double() const
Returns true if the file stores all "standard" floats as 64-bit doubles, or false if they are 32-bit ...
virtual void parse_command_line(int argc, char **argv)
Dispatches on each of the options on the command line, and passes the remaining parameters to handle_...
int get_file_major_ver()
Returns the major version number of the file currently being read, or the system current major versio...
bool is_eof() const
Returns true if the reader has reached end-of-file, false otherwise.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Base class for objects that can be written to and read from Bam files.
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
This is our own Panda specialization on the default STL vector.
This represents the in-memory index that records the list of files stored in the BamCache.
The name of a file, such as a texture file or an Egg file.
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
int get_num_children(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of child nodes this node has.
void write(ostream &out, int indent_level=0) const
Describes all the data collected.
PandaNode * get_child(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the nth child node of this node.
This object represents one frame of data in the recorded session file.
BamEndian get_file_endian() const
Returns the endian preference indicated by the Bam file currently being read or written.
virtual bool is_geom_node() const
A simple downcast check.
int get_file_minor_ver()
Returns the minor version number of the file currently being read, or the system current minor versio...
TypedWritable * read_object()
Reads and returns the next object from the Bam file, or NULL if the end of the file has been reached...
A node that holds Geom objects, renderable pieces of geometry.
bool write(const Filename &fullpath)
Writes the texture to the named filename.