mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
*** empty log message ***
This commit is contained in:
parent
c03729fba3
commit
594fc23c3b
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include <dconfig.h>
|
#include <dconfig.h>
|
||||||
|
|
||||||
Configure(config_cull);
|
ConfigureDef(config_cull);
|
||||||
NotifyCategoryDef(cull, "");
|
NotifyCategoryDef(cull, "");
|
||||||
|
|
||||||
ConfigureFn(config_cull) {
|
ConfigureFn(config_cull) {
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
#include <pandabase.h>
|
#include <pandabase.h>
|
||||||
#include <notifyCategoryProxy.h>
|
#include <notifyCategoryProxy.h>
|
||||||
|
#include <dconfig.h>
|
||||||
|
|
||||||
|
ConfigureDecl(config_cull, EXPCL_PANDA, EXPTP_PANDA);
|
||||||
NotifyCategoryDecl(cull, EXPCL_PANDA, EXPTP_PANDA);
|
NotifyCategoryDecl(cull, EXPCL_PANDA, EXPTP_PANDA);
|
||||||
|
|
||||||
extern const bool cull_force_update;
|
extern const bool cull_force_update;
|
||||||
|
@ -9,63 +9,6 @@
|
|||||||
#include <directRenderTraverser.h>
|
#include <directRenderTraverser.h>
|
||||||
#include <graphicsStateGuardian.h>
|
#include <graphicsStateGuardian.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: CullTraverser::set_default_bin
|
|
||||||
// Access: Public
|
|
||||||
// Description: Specifies the default GeomBin that any geometry will
|
|
||||||
// be assigned to if the scene graph doesn't specify
|
|
||||||
// otherwise. There must always be some default GeomBin
|
|
||||||
// in effect.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void CullTraverser::
|
|
||||||
set_default_bin(GeomBin *bin) {
|
|
||||||
nassertv(bin != (GeomBin *)NULL);
|
|
||||||
nassertv(bin->is_attached());
|
|
||||||
nassertv(bin->get_traverser() == this);
|
|
||||||
_default_bin = bin;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: CullTraverser::get_default_bin
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the default GeomBin that any geometry will
|
|
||||||
// be assigned to if the scene graph doesn't specify
|
|
||||||
// otherwise.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE GeomBin *CullTraverser::
|
|
||||||
get_default_bin() const {
|
|
||||||
return _default_bin;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: CullTraverser::has_bin
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns true if a bin by the given name has been
|
|
||||||
// attached to the CullTraverser, false otherwise.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE bool CullTraverser::
|
|
||||||
has_bin(const string &name) const {
|
|
||||||
return (_toplevel_bins.count(name) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: CullTraverser::get_bin
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the GeomBin that was previously attached to
|
|
||||||
// the CullTraverser that shares the indicated name, or
|
|
||||||
// the default bin if no GeomBin with a matching name
|
|
||||||
// was added.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE GeomBin *CullTraverser::
|
|
||||||
get_bin(const string &name) const {
|
|
||||||
ToplevelBins::const_iterator tbi;
|
|
||||||
tbi = _toplevel_bins.find(name);
|
|
||||||
if (tbi == _toplevel_bins.end()) {
|
|
||||||
return get_default_bin();
|
|
||||||
}
|
|
||||||
return (*tbi).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: CullTraverser::draw_geom
|
// Function: CullTraverser::draw_geom
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <config_sgraphutil.h> // for implicit_app_traversal
|
#include <config_sgraphutil.h> // for implicit_app_traversal
|
||||||
#include <config_sgattrib.h> // for support_decals
|
#include <config_sgattrib.h> // for support_decals
|
||||||
#include <pStatTimer.h>
|
#include <pStatTimer.h>
|
||||||
|
#include <string_utils.h>
|
||||||
|
|
||||||
TypeHandle CullTraverser::_type_handle;
|
TypeHandle CullTraverser::_type_handle;
|
||||||
|
|
||||||
@ -43,16 +44,9 @@ CullTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
|||||||
const ArcChain &arc_chain) :
|
const ArcChain &arc_chain) :
|
||||||
RenderTraverser(gsg, graph_type, arc_chain)
|
RenderTraverser(gsg, graph_type, arc_chain)
|
||||||
{
|
{
|
||||||
GeomBinNormal *default_bin = new GeomBinNormal("default");
|
|
||||||
GeomBinFixed *fixed = new GeomBinFixed("fixed");
|
|
||||||
fixed->set_sort(30);
|
|
||||||
|
|
||||||
default_bin->set_traverser(this);
|
|
||||||
fixed->set_traverser(this);
|
|
||||||
|
|
||||||
_default_bin = default_bin;
|
|
||||||
|
|
||||||
_nested_count = 0;
|
_nested_count = 0;
|
||||||
|
|
||||||
|
setup_initial_bins();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -63,6 +57,48 @@ CullTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
|||||||
CullTraverser::
|
CullTraverser::
|
||||||
~CullTraverser() {
|
~CullTraverser() {
|
||||||
// We should detach each of our associated bins when we destruct.
|
// We should detach each of our associated bins when we destruct.
|
||||||
|
clear_bins();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CullTraverser::has_bin
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if a bin by the given name has been
|
||||||
|
// attached to the CullTraverser, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CullTraverser::
|
||||||
|
has_bin(const string &name) const {
|
||||||
|
return (_toplevel_bins.count(name) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CullTraverser::get_bin
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the GeomBin that was previously attached to
|
||||||
|
// the CullTraverser that shares the indicated name, or
|
||||||
|
// NULL if no GeomBin with a matching name was added.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
GeomBin *CullTraverser::
|
||||||
|
get_bin(const string &name) const {
|
||||||
|
ToplevelBins::const_iterator tbi;
|
||||||
|
tbi = _toplevel_bins.find(name);
|
||||||
|
if (tbi == _toplevel_bins.end()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (*tbi).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CullTraverser::clear_bins
|
||||||
|
// Access: Public
|
||||||
|
// Description: Disassociates all the GeomBins previously associated
|
||||||
|
// with this traverser (and deletes them, if they have
|
||||||
|
// no other references). You must add new GeomBins
|
||||||
|
// before rendering by calling set_traverser() on the
|
||||||
|
// appropriate bins.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CullTraverser::
|
||||||
|
clear_bins() {
|
||||||
// We can't just run a for loop, because this is a self-modifying
|
// We can't just run a for loop, because this is a self-modifying
|
||||||
// operation.
|
// operation.
|
||||||
while (!_toplevel_bins.empty()) {
|
while (!_toplevel_bins.empty()) {
|
||||||
@ -73,6 +109,54 @@ CullTraverser::
|
|||||||
}
|
}
|
||||||
|
|
||||||
nassertv(_sub_bins.empty());
|
nassertv(_sub_bins.empty());
|
||||||
|
nassertv(_default_bin == (GeomBin *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CullTraverser::output
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CullTraverser::
|
||||||
|
output(ostream &out) const {
|
||||||
|
int node_count = 0;
|
||||||
|
int used_states = 0;
|
||||||
|
|
||||||
|
States::const_iterator si;
|
||||||
|
for (si = _states.begin(); si != _states.end(); ++si) {
|
||||||
|
const CullState *cs = (*si);
|
||||||
|
int c = cs->count_current_nodes();
|
||||||
|
if (c != 0) {
|
||||||
|
node_count += c;
|
||||||
|
used_states++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out << node_count << " nodes with " << used_states << " states; "
|
||||||
|
<< _states.size() - used_states << " unused states.";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CullTraverser::output
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CullTraverser::
|
||||||
|
write(ostream &out, int indent_level) const {
|
||||||
|
/*
|
||||||
|
States::const_iterator si;
|
||||||
|
for (si = _states.begin(); si != _states.end(); ++si) {
|
||||||
|
const CullState *cs = (*si);
|
||||||
|
cs->write(out, indent_level);
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
ToplevelBins::const_iterator tbi;
|
||||||
|
for (tbi = _toplevel_bins.begin(); tbi != _toplevel_bins.end(); ++tbi) {
|
||||||
|
(*tbi).second->write(out, indent_level);
|
||||||
|
}
|
||||||
|
_lookup.write(out, indent_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -97,9 +181,6 @@ traverse(Node *root,
|
|||||||
<< *root << "\n";
|
<< *root << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
nassertv(!_toplevel_bins.empty());
|
|
||||||
nassertv(!_sub_bins.empty());
|
|
||||||
|
|
||||||
bool is_initial = (_nested_count == 0);
|
bool is_initial = (_nested_count == 0);
|
||||||
if (is_initial) {
|
if (is_initial) {
|
||||||
if (cull_force_update) {
|
if (cull_force_update) {
|
||||||
@ -157,51 +238,67 @@ traverse(Node *root,
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: CullTraverser::output
|
// Function: CullTraverser::setup_initial_bins
|
||||||
// Access: Public
|
// Access: Private
|
||||||
// Description:
|
// Description: Creates all the appropriate rendering bins as
|
||||||
|
// requested from the Configrc file.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CullTraverser::
|
void CullTraverser::
|
||||||
output(ostream &out) const {
|
setup_initial_bins() {
|
||||||
int node_count = 0;
|
// We always have "default" and "fixed" hardcoded in, although these
|
||||||
int used_states = 0;
|
// may be overridden by specifing a new bin with the same name in
|
||||||
|
// the Configrc file.
|
||||||
|
|
||||||
States::const_iterator si;
|
GeomBinNormal *default_bin = new GeomBinNormal("default");
|
||||||
for (si = _states.begin(); si != _states.end(); ++si) {
|
GeomBinFixed *fixed = new GeomBinFixed("fixed");
|
||||||
const CullState *cs = (*si);
|
fixed->set_sort(30);
|
||||||
int c = cs->count_current_nodes();
|
|
||||||
if (c != 0) {
|
default_bin->set_traverser(this);
|
||||||
node_count += c;
|
fixed->set_traverser(this);
|
||||||
used_states++;
|
|
||||||
|
|
||||||
|
// Now get the config options.
|
||||||
|
Config::ConfigTable::Symbol cull_bins;
|
||||||
|
config_cull.GetAll("cull-bin", cull_bins);
|
||||||
|
|
||||||
|
Config::ConfigTable::Symbol::iterator bi;
|
||||||
|
for (bi = cull_bins.begin(); bi != cull_bins.end(); ++bi) {
|
||||||
|
ConfigString def = (*bi).Val();
|
||||||
|
|
||||||
|
// This is a string in three tokens, separated by whitespace:
|
||||||
|
// bin_name sort type
|
||||||
|
|
||||||
|
vector_string words;
|
||||||
|
extract_words(def, words);
|
||||||
|
|
||||||
|
if (words.size() != 3) {
|
||||||
|
cull_cat.error()
|
||||||
|
<< "Invalid cull-bin definition: " << def << "\n"
|
||||||
|
<< "Definition should be three words: bin_name sort type\n";
|
||||||
|
} else {
|
||||||
|
int sort;
|
||||||
|
if (!string_to_int(words[1], sort)) {
|
||||||
|
cull_cat.error()
|
||||||
|
<< "Invalid cull-bin definition: " << def << "\n"
|
||||||
|
<< "Sort token " << words[1] << " is not an integer.\n";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
TypeHandle type = GeomBin::parse_bin_type(words[2]);
|
||||||
|
if (type == TypeHandle::none()) {
|
||||||
|
cull_cat.error()
|
||||||
|
<< "Invalid cull-bin definition: " << def << "\n"
|
||||||
|
<< "Bin type " << words[2] << " is not known.\n";
|
||||||
|
} else {
|
||||||
|
PT(GeomBin) bin = GeomBin::make_bin(type, words[0]);
|
||||||
|
nassertv(bin != (GeomBin *)NULL);
|
||||||
|
bin->set_sort(sort);
|
||||||
|
bin->set_traverser(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out << node_count << " nodes with " << used_states << " states; "
|
|
||||||
<< _states.size() - used_states << " unused states.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: CullTraverser::output
|
|
||||||
// Access: Public
|
|
||||||
// Description:
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void CullTraverser::
|
|
||||||
write(ostream &out, int indent_level) const {
|
|
||||||
/*
|
|
||||||
States::const_iterator si;
|
|
||||||
for (si = _states.begin(); si != _states.end(); ++si) {
|
|
||||||
const CullState *cs = (*si);
|
|
||||||
cs->write(out, indent_level);
|
|
||||||
out << "\n";
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
ToplevelBins::const_iterator tbi;
|
|
||||||
for (tbi = _toplevel_bins.begin(); tbi != _toplevel_bins.end(); ++tbi) {
|
|
||||||
(*tbi).second->write(out, indent_level);
|
|
||||||
}
|
|
||||||
_lookup.write(out, indent_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: CullTraverser::draw
|
// Function: CullTraverser::draw
|
||||||
@ -238,15 +335,32 @@ draw() {
|
|||||||
if (!cs->is_empty()) {
|
if (!cs->is_empty()) {
|
||||||
cs->apply_to(_initial_state);
|
cs->apply_to(_initial_state);
|
||||||
|
|
||||||
// Check the requested bin for the Geoms in this state.
|
static string default_bin_name = "default";
|
||||||
|
string bin_name = default_bin_name;
|
||||||
GeomBin *requested_bin = _default_bin;
|
GeomBin *requested_bin = _default_bin;
|
||||||
int draw_order = 0;
|
int draw_order = 0;
|
||||||
|
|
||||||
|
// Check the requested bin for the Geoms in this state.
|
||||||
const GeomBinAttribute *bin_attrib;
|
const GeomBinAttribute *bin_attrib;
|
||||||
if (get_attribute_into(bin_attrib, cs->get_attributes(),
|
if (get_attribute_into(bin_attrib, cs->get_attributes(),
|
||||||
GeomBinTransition::get_class_type())) {
|
GeomBinTransition::get_class_type())) {
|
||||||
requested_bin = get_bin(bin_attrib->get_bin());
|
|
||||||
draw_order = bin_attrib->get_draw_order();
|
draw_order = bin_attrib->get_draw_order();
|
||||||
|
bin_name = bin_attrib->get_bin();
|
||||||
|
requested_bin = get_bin(bin_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requested_bin == (GeomBin *)NULL) {
|
||||||
|
// If we don't have a bin by this name, create one.
|
||||||
|
cull_cat.warning()
|
||||||
|
<< "Bin " << bin_name << " is unknown; creating a default bin.\n";
|
||||||
|
|
||||||
|
if (bin_name == "fixed") {
|
||||||
|
requested_bin = new GeomBinFixed(bin_name);
|
||||||
|
requested_bin->set_sort(20);
|
||||||
|
} else {
|
||||||
|
requested_bin = new GeomBinNormal(bin_name);
|
||||||
|
}
|
||||||
|
requested_bin->set_traverser(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
requested_bin->record_current_state(_gsg, cs, draw_order, this);
|
requested_bin->record_current_state(_gsg, cs, draw_order, this);
|
||||||
@ -259,7 +373,10 @@ draw() {
|
|||||||
<< "Drawing " << _sub_bins.size() << " bins.\n";
|
<< "Drawing " << _sub_bins.size() << " bins.\n";
|
||||||
}
|
}
|
||||||
for (sbi = _sub_bins.begin(); sbi != _sub_bins.end(); ++sbi) {
|
for (sbi = _sub_bins.begin(); sbi != _sub_bins.end(); ++sbi) {
|
||||||
(*sbi).second->draw(this);
|
GeomBin *bin = (*sbi).second;
|
||||||
|
if (bin->is_active()) {
|
||||||
|
bin->draw(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -565,13 +682,28 @@ attach_toplevel_bin(GeomBin *bin) {
|
|||||||
<< "Attaching toplevel bin " << *bin << "\n";
|
<< "Attaching toplevel bin " << *bin << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the new bin by name.
|
const string &bin_name = bin->get_name();
|
||||||
bool inserted =
|
|
||||||
_toplevel_bins.insert(ToplevelBins::value_type(bin->get_name(), bin)).second;
|
|
||||||
|
|
||||||
// If this assertion fails, there was already a bin by the same name
|
// Insert the new bin by name.
|
||||||
// in this traverser, an error condition.
|
pair<ToplevelBins::iterator, bool> result =
|
||||||
nassertv(inserted);
|
_toplevel_bins.insert(ToplevelBins::value_type(bin_name, bin));
|
||||||
|
|
||||||
|
if (!result.second) {
|
||||||
|
// There was already a bin by the same name name in this
|
||||||
|
// traverser. We should therefore detach this bin.
|
||||||
|
GeomBin *other_bin = (*result.first).second;
|
||||||
|
if (other_bin != bin) {
|
||||||
|
other_bin->clear_traverser();
|
||||||
|
}
|
||||||
|
|
||||||
|
result =
|
||||||
|
_toplevel_bins.insert(ToplevelBins::value_type(bin_name, bin));
|
||||||
|
nassertv(result.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bin_name == "default") {
|
||||||
|
_default_bin = bin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -612,9 +744,15 @@ detach_toplevel_bin(GeomBin *bin) {
|
|||||||
<< "Detaching toplevel bin " << *bin << "\n";
|
<< "Detaching toplevel bin " << *bin << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ToplevelBins::iterator tbi = _toplevel_bins.find(bin->get_name());
|
const string &bin_name = bin->get_name();
|
||||||
|
|
||||||
|
ToplevelBins::iterator tbi = _toplevel_bins.find(bin_name);
|
||||||
nassertv(tbi != _toplevel_bins.end());
|
nassertv(tbi != _toplevel_bins.end());
|
||||||
_toplevel_bins.erase(tbi);
|
_toplevel_bins.erase(tbi);
|
||||||
|
|
||||||
|
if (bin_name == "default") {
|
||||||
|
_default_bin = (GeomBin *)NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -41,10 +41,15 @@ public:
|
|||||||
const ArcChain &arc_chain = ArcChain());
|
const ArcChain &arc_chain = ArcChain());
|
||||||
virtual ~CullTraverser();
|
virtual ~CullTraverser();
|
||||||
|
|
||||||
INLINE void set_default_bin(GeomBin *bin);
|
PUBLISHED:
|
||||||
INLINE GeomBin *get_default_bin() const;
|
bool has_bin(const string &name) const;
|
||||||
INLINE bool has_bin(const string &name) const;
|
GeomBin *get_bin(const string &name) const;
|
||||||
INLINE GeomBin *get_bin(const string &name) const;
|
void clear_bins();
|
||||||
|
|
||||||
|
void output(ostream &out) const;
|
||||||
|
void write(ostream &out, int indent_level = 0) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
virtual void traverse(Node *root,
|
virtual void traverse(Node *root,
|
||||||
const AllAttributesWrapper &initial_state,
|
const AllAttributesWrapper &initial_state,
|
||||||
@ -57,11 +62,9 @@ public:
|
|||||||
INLINE void draw_direct(const ArcChain &arc_chain,
|
INLINE void draw_direct(const ArcChain &arc_chain,
|
||||||
const AllAttributesWrapper &initial_state);
|
const AllAttributesWrapper &initial_state);
|
||||||
|
|
||||||
PUBLISHED:
|
|
||||||
void output(ostream &out) const;
|
|
||||||
void write(ostream &out, int indent_level = 0) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setup_initial_bins();
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
void clean_out_old_states();
|
void clean_out_old_states();
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ GeomBin(const string &name) :
|
|||||||
_traverser = (CullTraverser *)NULL;
|
_traverser = (CullTraverser *)NULL;
|
||||||
_is_attached = false;
|
_is_attached = false;
|
||||||
_sort = 0;
|
_sort = 0;
|
||||||
|
_active = true;
|
||||||
_parent = (GeomBin *)NULL;
|
_parent = (GeomBin *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +31,18 @@ get_sort() const {
|
|||||||
return _sort;
|
return _sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomBin::get_active
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the active flag of this particular bin. If
|
||||||
|
// the flag is false, the contents of the bin are not
|
||||||
|
// rendered.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GeomBin::
|
||||||
|
is_active() const {
|
||||||
|
return _active;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomBin::has_traverser
|
// Function: GeomBin::has_traverser
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -6,10 +6,15 @@
|
|||||||
#include "geomBin.h"
|
#include "geomBin.h"
|
||||||
#include "cullTraverser.h"
|
#include "cullTraverser.h"
|
||||||
#include "config_cull.h"
|
#include "config_cull.h"
|
||||||
|
#include "geomBinNormal.h"
|
||||||
|
#include "geomBinUnsorted.h"
|
||||||
|
#include "geomBinFixed.h"
|
||||||
|
#include "geomBinBackToFront.h"
|
||||||
|
|
||||||
#include <indent.h>
|
#include <indent.h>
|
||||||
#include <nodeAttributes.h>
|
#include <nodeAttributes.h>
|
||||||
#include <graphicsStateGuardian.h>
|
#include <graphicsStateGuardian.h>
|
||||||
|
#include <string_utils.h>
|
||||||
|
|
||||||
TypeHandle GeomBin::_type_handle;
|
TypeHandle GeomBin::_type_handle;
|
||||||
|
|
||||||
@ -105,6 +110,18 @@ set_sort(int sort) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomBin::set_active
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Sets the active flag of this particular bin. If the
|
||||||
|
// flag is false, the contents of the bin are not
|
||||||
|
// rendered.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GeomBin::
|
||||||
|
set_active(bool active) {
|
||||||
|
_active = active;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomBin::set_traverser
|
// Function: GeomBin::set_traverser
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -157,6 +174,72 @@ clear_traverser() {
|
|||||||
return keep;
|
return keep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomBin::parse_bin_type
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Converts from the given string representation to one
|
||||||
|
// of the derived GeomBin type handles. Returns
|
||||||
|
// TypeHandle::none() if the string does not match any
|
||||||
|
// known bin type.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
TypeHandle GeomBin::
|
||||||
|
parse_bin_type(const string &bin_type) {
|
||||||
|
if (cmp_nocase_uh(bin_type, "normal") == 0) {
|
||||||
|
return GeomBinNormal::get_class_type();
|
||||||
|
|
||||||
|
} else if (cmp_nocase_uh(bin_type, "unsorted") == 0) {
|
||||||
|
return GeomBinUnsorted::get_class_type();
|
||||||
|
|
||||||
|
} else if (cmp_nocase_uh(bin_type, "state_sorted") == 0) {
|
||||||
|
// For now, GeomBinUnsorted stands in surprisingly well for
|
||||||
|
// GeomBinStateSorted. This is because the states are already
|
||||||
|
// reasonably sorted as they come out of the CullTraverser, so it
|
||||||
|
// doesn't matter much whether the bin sorts it further.
|
||||||
|
return GeomBinUnsorted::get_class_type();
|
||||||
|
|
||||||
|
} else if (cmp_nocase_uh(bin_type, "statesorted") == 0) {
|
||||||
|
return GeomBinUnsorted::get_class_type();
|
||||||
|
|
||||||
|
} else if (cmp_nocase_uh(bin_type, "fixed") == 0) {
|
||||||
|
return GeomBinFixed::get_class_type();
|
||||||
|
|
||||||
|
} else if (cmp_nocase_uh(bin_type, "back_to_front") == 0) {
|
||||||
|
return GeomBinBackToFront::get_class_type();
|
||||||
|
|
||||||
|
} else if (cmp_nocase_uh(bin_type, "backtofront") == 0) {
|
||||||
|
return GeomBinBackToFront::get_class_type();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return TypeHandle::none();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomBin::make_bin
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Creates and returns a new GeomBin of the appropriate
|
||||||
|
// type as indicated by the TypeHandle. Returns NULL if
|
||||||
|
// the TypeHandle does not reflect a known GeomBin type.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(GeomBin) GeomBin::
|
||||||
|
make_bin(TypeHandle type, const string &name) {
|
||||||
|
if (type == GeomBinNormal::get_class_type()) {
|
||||||
|
return new GeomBinNormal(name);
|
||||||
|
|
||||||
|
} else if (type == GeomBinUnsorted::get_class_type()) {
|
||||||
|
return new GeomBinUnsorted(name);
|
||||||
|
|
||||||
|
} else if (type == GeomBinFixed::get_class_type()) {
|
||||||
|
return new GeomBinFixed(name);
|
||||||
|
|
||||||
|
} else if (type == GeomBinBackToFront::get_class_type()) {
|
||||||
|
return new GeomBinBackToFront(name);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomBin::attach
|
// Function: GeomBin::attach
|
||||||
// Access: Protected, Virtual
|
// Access: Protected, Virtual
|
||||||
|
@ -45,6 +45,9 @@ PUBLISHED:
|
|||||||
INLINE int get_sort() const;
|
INLINE int get_sort() const;
|
||||||
void set_sort(int sort);
|
void set_sort(int sort);
|
||||||
|
|
||||||
|
virtual void set_active(bool active);
|
||||||
|
INLINE bool is_active() const;
|
||||||
|
|
||||||
void set_traverser(CullTraverser *traverser);
|
void set_traverser(CullTraverser *traverser);
|
||||||
INLINE bool has_traverser() const;
|
INLINE bool has_traverser() const;
|
||||||
INLINE CullTraverser *get_traverser() const;
|
INLINE CullTraverser *get_traverser() const;
|
||||||
@ -67,6 +70,9 @@ public:
|
|||||||
|
|
||||||
virtual void draw(CullTraverser *trav)=0;
|
virtual void draw(CullTraverser *trav)=0;
|
||||||
|
|
||||||
|
static TypeHandle parse_bin_type(const string &bin_type);
|
||||||
|
static PT(GeomBin) make_bin(TypeHandle type, const string &name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
INLINE void claim_cull_state(CullState *cs);
|
INLINE void claim_cull_state(CullState *cs);
|
||||||
INLINE void disclaim_cull_state(CullState *cs);
|
INLINE void disclaim_cull_state(CullState *cs);
|
||||||
@ -77,6 +83,7 @@ protected:
|
|||||||
CullTraverser *_traverser;
|
CullTraverser *_traverser;
|
||||||
bool _is_attached;
|
bool _is_attached;
|
||||||
int _sort;
|
int _sort;
|
||||||
|
bool _active;
|
||||||
GeomBin *_parent;
|
GeomBin *_parent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -43,9 +43,9 @@ set_on(const string &bin, int draw_order) {
|
|||||||
// represents. It is only valid to call this if is_on()
|
// represents. It is only valid to call this if is_on()
|
||||||
// has returned true.
|
// has returned true.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE string GeomBinAttribute::
|
INLINE const string &GeomBinAttribute::
|
||||||
get_bin() const {
|
get_bin() const {
|
||||||
nassertr(is_on(), string());
|
nassertr(is_on(), _value);
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ public:
|
|||||||
INLINE GeomBinAttribute(const string &bin, int draw_order = 0);
|
INLINE GeomBinAttribute(const string &bin, int draw_order = 0);
|
||||||
|
|
||||||
INLINE void set_on(const string &bin, int draw_order = 0);
|
INLINE void set_on(const string &bin, int draw_order = 0);
|
||||||
INLINE string get_bin() const;
|
INLINE const string &get_bin() const;
|
||||||
INLINE int get_draw_order() const;
|
INLINE int get_draw_order() const;
|
||||||
|
|
||||||
virtual TypeHandle get_handle() const;
|
virtual TypeHandle get_handle() const;
|
||||||
|
@ -81,6 +81,23 @@ remove_bin(int n) {
|
|||||||
return sub_bin;
|
return sub_bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomBinGroup::set_active
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Sets the active flag of this particular bin, and all
|
||||||
|
// of its child bins. If the flag is false, the
|
||||||
|
// contents of the bin are not rendered.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GeomBinGroup::
|
||||||
|
set_active(bool active) {
|
||||||
|
GeomBin::set_active(active);
|
||||||
|
|
||||||
|
SubBins::iterator sbi;
|
||||||
|
for (sbi = _sub_bins.begin(); sbi != _sub_bins.end(); ++sbi) {
|
||||||
|
(*sbi)->set_active(active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomBinGroup::clear_current_states
|
// Function: GeomBinGroup::clear_current_states
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -32,6 +32,8 @@ PUBLISHED:
|
|||||||
INLINE GeomBin *get_bin(int n);
|
INLINE GeomBin *get_bin(int n);
|
||||||
PT(GeomBin) remove_bin(int n);
|
PT(GeomBin) remove_bin(int n);
|
||||||
|
|
||||||
|
virtual void set_active(bool active);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual int choose_bin(CullState *cs) const=0;
|
virtual int choose_bin(CullState *cs) const=0;
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ set_on(const string &bin, int draw_order) {
|
|||||||
// represents. It is only valid to call this if is_on()
|
// represents. It is only valid to call this if is_on()
|
||||||
// has returned true.
|
// has returned true.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE string GeomBinTransition::
|
INLINE const string &GeomBinTransition::
|
||||||
get_bin() const {
|
get_bin() const {
|
||||||
nassertr(is_on(), string());
|
nassertr(is_on(), _value);
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ PUBLISHED:
|
|||||||
INLINE static GeomBinTransition off();
|
INLINE static GeomBinTransition off();
|
||||||
|
|
||||||
INLINE void set_on(const string &bin, int draw_order);
|
INLINE void set_on(const string &bin, int draw_order);
|
||||||
INLINE string get_bin() const;
|
INLINE const string &get_bin() const;
|
||||||
INLINE int get_draw_order() const;
|
INLINE int get_draw_order() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -61,3 +61,137 @@ downcase(const string &s) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: extract_words
|
||||||
|
// Description: Divides the string into a number of words according
|
||||||
|
// to whitespace. The words vector should be cleared by
|
||||||
|
// the user before calling; otherwise, the list of words
|
||||||
|
// in the string will be appended to the end of whatever
|
||||||
|
// was there before.
|
||||||
|
//
|
||||||
|
// The return value is the number of words extracted.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int
|
||||||
|
extract_words(const string &str, vector_string &words) {
|
||||||
|
int num_words = 0;
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
while (pos < str.length() && isspace(str[pos])) {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
while (pos < str.length()) {
|
||||||
|
size_t word_start = pos;
|
||||||
|
while (pos < str.length() && !isspace(str[pos])) {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
words.push_back(str.substr(word_start, pos - word_start));
|
||||||
|
num_words++;
|
||||||
|
|
||||||
|
while (pos < str.length() && isspace(str[pos])) {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_words;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: trim_left
|
||||||
|
// Description: Returns a new string representing the contents of the
|
||||||
|
// given string with the leading whitespace removed.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
string
|
||||||
|
trim_left(const string &str) {
|
||||||
|
size_t begin = 0;
|
||||||
|
while (begin < str.size() && isspace(str[begin])) {
|
||||||
|
begin++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.substr(begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: trim_right
|
||||||
|
// Description: Returns a new string representing the contents of the
|
||||||
|
// given string with the trailing whitespace removed.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
string
|
||||||
|
trim_right(const string &str) {
|
||||||
|
size_t begin = 0;
|
||||||
|
size_t end = str.size();
|
||||||
|
while (end > begin && isspace(str[end - 1])) {
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.substr(begin, end - begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: string_to_int
|
||||||
|
// Description: A string-interface wrapper around the C library
|
||||||
|
// strtol(). This parses the ASCII representation of an
|
||||||
|
// integer, and then sets tail to everything that
|
||||||
|
// follows the first valid integer read. If, on exit,
|
||||||
|
// str == tail, there was no valid integer in the
|
||||||
|
// source string; if !tail.empty(), there was garbage
|
||||||
|
// after the integer.
|
||||||
|
//
|
||||||
|
// It is legal if str and tail refer to the same string.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int
|
||||||
|
string_to_int(const string &str, string &tail) {
|
||||||
|
const char *nptr = str.c_str();
|
||||||
|
char *endptr;
|
||||||
|
int result = strtol(nptr, &endptr, 10);
|
||||||
|
tail = endptr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: string_to_int
|
||||||
|
// Description: Another flavor of string_to_int(), this one returns
|
||||||
|
// true if the string is a perfectly valid integer (and
|
||||||
|
// sets result to that value), or false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool
|
||||||
|
string_to_int(const string &str, int &result) {
|
||||||
|
string tail;
|
||||||
|
result = string_to_int(str, tail);
|
||||||
|
return tail.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: string_to_double
|
||||||
|
// Description: A string-interface wrapper around the C library
|
||||||
|
// strtol(). This parses the ASCII representation of an
|
||||||
|
// floating-point number, and then sets tail to
|
||||||
|
// everything that follows the first valid integer read.
|
||||||
|
// If, on exit, str == tail, there was no valid integer
|
||||||
|
// in the source string; if !tail.empty(), there was
|
||||||
|
// garbage after the number.
|
||||||
|
//
|
||||||
|
// It is legal if str and tail refer to the same string.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
double
|
||||||
|
string_to_double(const string &str, string &tail) {
|
||||||
|
const char *nptr = str.c_str();
|
||||||
|
char *endptr;
|
||||||
|
double result = strtod(nptr, &endptr);
|
||||||
|
tail = endptr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: string_to_double
|
||||||
|
// Description: Another flavor of string_to_double(), this one
|
||||||
|
// returns true if the string is a perfectly valid
|
||||||
|
// number (and sets result to that value), or false
|
||||||
|
// otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool
|
||||||
|
string_to_double(const string &str, double &result) {
|
||||||
|
string tail;
|
||||||
|
result = string_to_double(str, tail);
|
||||||
|
return tail.empty();
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <pandabase.h>
|
#include <pandabase.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector_string.h>
|
||||||
|
|
||||||
// Case-insensitive string comparison, from Stroustrup's C++ third edition.
|
// Case-insensitive string comparison, from Stroustrup's C++ third edition.
|
||||||
// Works like strcmp().
|
// Works like strcmp().
|
||||||
@ -20,6 +21,19 @@ EXPCL_PANDA int cmp_nocase_uh(const string &s, const string &s2);
|
|||||||
// Returns the string converted to lowercase.
|
// Returns the string converted to lowercase.
|
||||||
EXPCL_PANDA string downcase(const string &s);
|
EXPCL_PANDA string downcase(const string &s);
|
||||||
|
|
||||||
|
// Separates the string into words according to whitespace.
|
||||||
|
EXPCL_PANDA int extract_words(const string &str, vector_string &words);
|
||||||
|
|
||||||
|
// Trims leading and/or trailing whitespace from the string.
|
||||||
|
EXPCL_PANDA string trim_left(const string &str);
|
||||||
|
EXPCL_PANDA string trim_right(const string &str);
|
||||||
|
|
||||||
|
// Functions to parse numeric values out of a string.
|
||||||
|
EXPCL_PANDA int string_to_int(const string &str, string &tail);
|
||||||
|
EXPCL_PANDA bool string_to_int(const string &str, int &result);
|
||||||
|
EXPCL_PANDA double string_to_double(const string &str, string &tail);
|
||||||
|
EXPCL_PANDA bool string_to_double(const string &str, double &result);
|
||||||
|
|
||||||
// Convenience function to make a string from anything that has an
|
// Convenience function to make a string from anything that has an
|
||||||
// ostream operator.
|
// ostream operator.
|
||||||
template<class Thing>
|
template<class Thing>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#define LOCAL_LIBS \
|
#define LOCAL_LIBS \
|
||||||
eggbase progbase
|
eggbase progbase
|
||||||
#define OTHER_LIBS \
|
#define OTHER_LIBS \
|
||||||
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 \
|
graph:c putil:c express:c panda:m pandaexpress:m \
|
||||||
interrogatedb:c dtoolutil:c dconfig:c dtool:m pystub
|
interrogatedb:c dtoolutil:c dconfig:c dtool:m pystub
|
||||||
#define UNIX_SYS_LIBS \
|
#define UNIX_SYS_LIBS \
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <bamFile.h>
|
#include <bamFile.h>
|
||||||
#include <node.h>
|
#include <node.h>
|
||||||
#include <renderRelation.h>
|
#include <renderRelation.h>
|
||||||
|
#include <geomNode.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -25,6 +26,16 @@ BamInfo() {
|
|||||||
clear_runlines();
|
clear_runlines();
|
||||||
add_runline("[opts] input.bam [input.bam ... ]");
|
add_runline("[opts] input.bam [input.bam ... ]");
|
||||||
|
|
||||||
|
add_option
|
||||||
|
("t", "", 0,
|
||||||
|
"List explicitly each transition in the hierarchy.",
|
||||||
|
&BamInfo::dispatch_none, &_verbose_transitions);
|
||||||
|
|
||||||
|
add_option
|
||||||
|
("g", "", 0,
|
||||||
|
"Output verbose information about the each Geom in the Bam file.",
|
||||||
|
&BamInfo::dispatch_none, &_verbose_geoms);
|
||||||
|
|
||||||
_num_scene_graphs = 0;
|
_num_scene_graphs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,10 +57,10 @@ run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_num_scene_graphs > 0) {
|
if (_num_scene_graphs > 0) {
|
||||||
nout << "\rScene graph statistics:\n";
|
nout << "\nScene graph statistics:\n";
|
||||||
_analyzer.write(nout, 2);
|
_analyzer.write(nout, 2);
|
||||||
}
|
}
|
||||||
nout << "\r";
|
nout << "\n";
|
||||||
|
|
||||||
if (!okflag) {
|
if (!okflag) {
|
||||||
// Exit with an error if any of the files was unreadable.
|
// Exit with an error if any of the files was unreadable.
|
||||||
@ -145,6 +156,10 @@ describe_scene_graph(Node *node) {
|
|||||||
|
|
||||||
nout << " " << num_nodes << " nodes, bounding volume is "
|
nout << " " << num_nodes << " nodes, bounding volume is "
|
||||||
<< arc->get_bound() << "\n";
|
<< arc->get_bound() << "\n";
|
||||||
|
|
||||||
|
if (_verbose_geoms || _verbose_transitions) {
|
||||||
|
list_hierarchy(node, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -159,6 +174,37 @@ describe_general_object(TypedWriteable *object) {
|
|||||||
nout << " " << object->get_type() << "\n";
|
nout << " " << object->get_type() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: BamInfo::list_hierarchy
|
||||||
|
// Access: Private
|
||||||
|
// Description: Outputs the hierarchy and all of the verbose GeomNode
|
||||||
|
// information.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void BamInfo::
|
||||||
|
list_hierarchy(Node *node, int indent_level) {
|
||||||
|
indent(nout, indent_level) << *node << "\n";
|
||||||
|
|
||||||
|
if (_verbose_geoms && node->is_of_type(GeomNode::get_class_type())) {
|
||||||
|
GeomNode *geom_node;
|
||||||
|
DCAST_INTO_V(geom_node, node);
|
||||||
|
geom_node->write_verbose(nout, 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";
|
||||||
|
|
||||||
|
if (_verbose_transitions) {
|
||||||
|
arc->write_transitions(nout, indent_level + 2);
|
||||||
|
nout << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
list_hierarchy(arc->get_child(), indent_level + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
BamInfo prog;
|
BamInfo prog;
|
||||||
prog.parse_command_line(argc, argv);
|
prog.parse_command_line(argc, argv);
|
||||||
|
@ -34,10 +34,14 @@ private:
|
|||||||
bool get_info(const Filename &filename);
|
bool get_info(const Filename &filename);
|
||||||
void describe_scene_graph(Node *node);
|
void describe_scene_graph(Node *node);
|
||||||
void describe_general_object(TypedWriteable *object);
|
void describe_general_object(TypedWriteable *object);
|
||||||
|
void list_hierarchy(Node *node, int indent_level);
|
||||||
|
|
||||||
typedef vector<Filename> Filenames;
|
typedef vector<Filename> Filenames;
|
||||||
Filenames _filenames;
|
Filenames _filenames;
|
||||||
|
|
||||||
|
bool _verbose_geoms;
|
||||||
|
bool _verbose_transitions;
|
||||||
|
|
||||||
int _num_scene_graphs;
|
int _num_scene_graphs;
|
||||||
SceneGraphAnalyzer _analyzer;
|
SceneGraphAnalyzer _analyzer;
|
||||||
};
|
};
|
||||||
|
@ -9,115 +9,6 @@
|
|||||||
#include <pnmFileTypeRegistry.h>
|
#include <pnmFileTypeRegistry.h>
|
||||||
|
|
||||||
|
|
||||||
string
|
|
||||||
trim_left(const string &str) {
|
|
||||||
size_t begin = 0;
|
|
||||||
while (begin < str.size() && isspace(str[begin])) {
|
|
||||||
begin++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return str.substr(begin);
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
|
||||||
trim_right(const string &str) {
|
|
||||||
size_t begin = 0;
|
|
||||||
size_t end = str.size();
|
|
||||||
while (end > begin && isspace(str[end - 1])) {
|
|
||||||
end--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return str.substr(begin, end - begin);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: string_to_int
|
|
||||||
// Description: A string-interface wrapper around the C library
|
|
||||||
// strtol(). This parses the ASCII representation of an
|
|
||||||
// integer, and then sets tail to everything that
|
|
||||||
// follows the first valid integer read. If, on exit,
|
|
||||||
// str == tail, there was no valid integer in the
|
|
||||||
// source string; if !tail.empty(), there was garbage
|
|
||||||
// after the integer.
|
|
||||||
//
|
|
||||||
// It is legal if str and tail refer to the same string.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
int
|
|
||||||
string_to_int(const string &str, string &tail) {
|
|
||||||
const char *nptr = str.c_str();
|
|
||||||
char *endptr;
|
|
||||||
int result = strtol(nptr, &endptr, 10);
|
|
||||||
tail = endptr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: string_to_int
|
|
||||||
// Description: Another flavor of string_to_int(), this one returns
|
|
||||||
// true if the string is a perfectly valid integer (and
|
|
||||||
// sets result to that value), or false otherwise.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool
|
|
||||||
string_to_int(const string &str, int &result) {
|
|
||||||
string tail;
|
|
||||||
result = string_to_int(str, tail);
|
|
||||||
return tail.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: string_to_double
|
|
||||||
// Description: A string-interface wrapper around the C library
|
|
||||||
// strtol(). This parses the ASCII representation of an
|
|
||||||
// floating-point number, and then sets tail to
|
|
||||||
// everything that follows the first valid integer read.
|
|
||||||
// If, on exit, str == tail, there was no valid integer
|
|
||||||
// in the source string; if !tail.empty(), there was
|
|
||||||
// garbage after the number.
|
|
||||||
//
|
|
||||||
// It is legal if str and tail refer to the same string.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
double
|
|
||||||
string_to_double(const string &str, string &tail) {
|
|
||||||
const char *nptr = str.c_str();
|
|
||||||
char *endptr;
|
|
||||||
double result = strtod(nptr, &endptr);
|
|
||||||
tail = endptr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: string_to_double
|
|
||||||
// Description: Another flavor of string_to_double(), this one
|
|
||||||
// returns true if the string is a perfectly valid
|
|
||||||
// number (and sets result to that value), or false
|
|
||||||
// otherwise.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool
|
|
||||||
string_to_double(const string &str, double &result) {
|
|
||||||
string tail;
|
|
||||||
result = string_to_double(str, tail);
|
|
||||||
return tail.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
extract_words(const string &str, vector_string &words) {
|
|
||||||
size_t pos = 0;
|
|
||||||
while (pos < str.length() && isspace(str[pos])) {
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
while (pos < str.length()) {
|
|
||||||
size_t word_start = pos;
|
|
||||||
while (pos < str.length() && !isspace(str[pos])) {
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
words.push_back(str.substr(word_start, pos - word_start));
|
|
||||||
|
|
||||||
while (pos < str.length() && isspace(str[pos])) {
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extracts the first word of the string into param, and the remainder
|
// Extracts the first word of the string into param, and the remainder
|
||||||
// of the line into value.
|
// of the line into value.
|
||||||
void
|
void
|
||||||
|
@ -7,19 +7,10 @@
|
|||||||
#define PAL_STRING_UTILS_H
|
#define PAL_STRING_UTILS_H
|
||||||
|
|
||||||
#include <pandatoolbase.h>
|
#include <pandatoolbase.h>
|
||||||
#include <vector_string.h>
|
#include <string_utils.h>
|
||||||
|
|
||||||
class PNMFileType;
|
class PNMFileType;
|
||||||
|
|
||||||
string trim_left(const string &str);
|
|
||||||
string trim_right(const string &str);
|
|
||||||
|
|
||||||
int string_to_int(const string &str, string &tail);
|
|
||||||
bool string_to_int(const string &str, int &result);
|
|
||||||
double string_to_double(const string &str, string &tail);
|
|
||||||
bool string_to_double(const string &str, double &result);
|
|
||||||
|
|
||||||
void extract_words(const string &str, vector_string &words);
|
|
||||||
void extract_param_value(const string &str, string ¶m, string &value);
|
void extract_param_value(const string &str, string ¶m, string &value);
|
||||||
|
|
||||||
bool parse_image_type_request(const string &word, PNMFileType *&color_type,
|
bool parse_image_type_request(const string &word, PNMFileType *&color_type,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user