mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
*** empty log message ***
This commit is contained in:
parent
c03729fba3
commit
594fc23c3b
@ -17,7 +17,7 @@
|
||||
|
||||
#include <dconfig.h>
|
||||
|
||||
Configure(config_cull);
|
||||
ConfigureDef(config_cull);
|
||||
NotifyCategoryDef(cull, "");
|
||||
|
||||
ConfigureFn(config_cull) {
|
||||
|
@ -8,7 +8,9 @@
|
||||
|
||||
#include <pandabase.h>
|
||||
#include <notifyCategoryProxy.h>
|
||||
#include <dconfig.h>
|
||||
|
||||
ConfigureDecl(config_cull, EXPCL_PANDA, EXPTP_PANDA);
|
||||
NotifyCategoryDecl(cull, EXPCL_PANDA, EXPTP_PANDA);
|
||||
|
||||
extern const bool cull_force_update;
|
||||
|
@ -9,63 +9,6 @@
|
||||
#include <directRenderTraverser.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
|
||||
// Access: Public
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <config_sgraphutil.h> // for implicit_app_traversal
|
||||
#include <config_sgattrib.h> // for support_decals
|
||||
#include <pStatTimer.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
TypeHandle CullTraverser::_type_handle;
|
||||
|
||||
@ -43,16 +44,9 @@ CullTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
||||
const ArcChain &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;
|
||||
|
||||
setup_initial_bins();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -63,6 +57,48 @@ CullTraverser(GraphicsStateGuardian *gsg, TypeHandle graph_type,
|
||||
CullTraverser::
|
||||
~CullTraverser() {
|
||||
// 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
|
||||
// operation.
|
||||
while (!_toplevel_bins.empty()) {
|
||||
@ -73,6 +109,54 @@ CullTraverser::
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
nassertv(!_toplevel_bins.empty());
|
||||
nassertv(!_sub_bins.empty());
|
||||
|
||||
bool is_initial = (_nested_count == 0);
|
||||
if (is_initial) {
|
||||
if (cull_force_update) {
|
||||
@ -157,51 +238,67 @@ traverse(Node *root,
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Function: CullTraverser::setup_initial_bins
|
||||
// Access: Private
|
||||
// Description: Creates all the appropriate rendering bins as
|
||||
// requested from the Configrc file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullTraverser::
|
||||
output(ostream &out) const {
|
||||
int node_count = 0;
|
||||
int used_states = 0;
|
||||
setup_initial_bins() {
|
||||
// We always have "default" and "fixed" hardcoded in, although these
|
||||
// may be overridden by specifing a new bin with the same name in
|
||||
// the Configrc file.
|
||||
|
||||
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++;
|
||||
GeomBinNormal *default_bin = new GeomBinNormal("default");
|
||||
GeomBinFixed *fixed = new GeomBinFixed("fixed");
|
||||
fixed->set_sort(30);
|
||||
|
||||
default_bin->set_traverser(this);
|
||||
fixed->set_traverser(this);
|
||||
|
||||
|
||||
// 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
|
||||
@ -238,15 +335,32 @@ draw() {
|
||||
if (!cs->is_empty()) {
|
||||
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;
|
||||
int draw_order = 0;
|
||||
|
||||
// Check the requested bin for the Geoms in this state.
|
||||
const GeomBinAttribute *bin_attrib;
|
||||
if (get_attribute_into(bin_attrib, cs->get_attributes(),
|
||||
GeomBinTransition::get_class_type())) {
|
||||
requested_bin = get_bin(bin_attrib->get_bin());
|
||||
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);
|
||||
@ -259,7 +373,10 @@ draw() {
|
||||
<< "Drawing " << _sub_bins.size() << " bins.\n";
|
||||
}
|
||||
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";
|
||||
}
|
||||
|
||||
// Insert the new bin by name.
|
||||
bool inserted =
|
||||
_toplevel_bins.insert(ToplevelBins::value_type(bin->get_name(), bin)).second;
|
||||
const string &bin_name = bin->get_name();
|
||||
|
||||
// If this assertion fails, there was already a bin by the same name
|
||||
// in this traverser, an error condition.
|
||||
nassertv(inserted);
|
||||
// Insert the new bin by name.
|
||||
pair<ToplevelBins::iterator, bool> result =
|
||||
_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";
|
||||
}
|
||||
|
||||
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());
|
||||
_toplevel_bins.erase(tbi);
|
||||
|
||||
if (bin_name == "default") {
|
||||
_default_bin = (GeomBin *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -41,10 +41,15 @@ public:
|
||||
const ArcChain &arc_chain = ArcChain());
|
||||
virtual ~CullTraverser();
|
||||
|
||||
INLINE void set_default_bin(GeomBin *bin);
|
||||
INLINE GeomBin *get_default_bin() const;
|
||||
INLINE bool has_bin(const string &name) const;
|
||||
INLINE GeomBin *get_bin(const string &name) const;
|
||||
PUBLISHED:
|
||||
bool has_bin(const string &name) const;
|
||||
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,
|
||||
const AllAttributesWrapper &initial_state,
|
||||
@ -57,11 +62,9 @@ public:
|
||||
INLINE void draw_direct(const ArcChain &arc_chain,
|
||||
const AllAttributesWrapper &initial_state);
|
||||
|
||||
PUBLISHED:
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
void setup_initial_bins();
|
||||
|
||||
void draw();
|
||||
void clean_out_old_states();
|
||||
|
||||
|
@ -15,6 +15,7 @@ GeomBin(const string &name) :
|
||||
_traverser = (CullTraverser *)NULL;
|
||||
_is_attached = false;
|
||||
_sort = 0;
|
||||
_active = true;
|
||||
_parent = (GeomBin *)NULL;
|
||||
}
|
||||
|
||||
@ -30,6 +31,18 @@ get_sort() const {
|
||||
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
|
||||
// Access: Public
|
||||
|
@ -6,10 +6,15 @@
|
||||
#include "geomBin.h"
|
||||
#include "cullTraverser.h"
|
||||
#include "config_cull.h"
|
||||
#include "geomBinNormal.h"
|
||||
#include "geomBinUnsorted.h"
|
||||
#include "geomBinFixed.h"
|
||||
#include "geomBinBackToFront.h"
|
||||
|
||||
#include <indent.h>
|
||||
#include <nodeAttributes.h>
|
||||
#include <graphicsStateGuardian.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
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
|
||||
// Access: Public
|
||||
@ -157,6 +174,72 @@ clear_traverser() {
|
||||
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
|
||||
// Access: Protected, Virtual
|
||||
|
@ -45,6 +45,9 @@ PUBLISHED:
|
||||
INLINE int get_sort() const;
|
||||
void set_sort(int sort);
|
||||
|
||||
virtual void set_active(bool active);
|
||||
INLINE bool is_active() const;
|
||||
|
||||
void set_traverser(CullTraverser *traverser);
|
||||
INLINE bool has_traverser() const;
|
||||
INLINE CullTraverser *get_traverser() const;
|
||||
@ -67,6 +70,9 @@ public:
|
||||
|
||||
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:
|
||||
INLINE void claim_cull_state(CullState *cs);
|
||||
INLINE void disclaim_cull_state(CullState *cs);
|
||||
@ -77,6 +83,7 @@ protected:
|
||||
CullTraverser *_traverser;
|
||||
bool _is_attached;
|
||||
int _sort;
|
||||
bool _active;
|
||||
GeomBin *_parent;
|
||||
|
||||
public:
|
||||
|
@ -43,9 +43,9 @@ set_on(const string &bin, int draw_order) {
|
||||
// represents. It is only valid to call this if is_on()
|
||||
// has returned true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string GeomBinAttribute::
|
||||
INLINE const string &GeomBinAttribute::
|
||||
get_bin() const {
|
||||
nassertr(is_on(), string());
|
||||
nassertr(is_on(), _value);
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
INLINE GeomBinAttribute(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;
|
||||
|
||||
virtual TypeHandle get_handle() const;
|
||||
|
@ -81,6 +81,23 @@ remove_bin(int n) {
|
||||
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
|
||||
// Access: Public, Virtual
|
||||
|
@ -32,6 +32,8 @@ PUBLISHED:
|
||||
INLINE GeomBin *get_bin(int n);
|
||||
PT(GeomBin) remove_bin(int n);
|
||||
|
||||
virtual void set_active(bool active);
|
||||
|
||||
public:
|
||||
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()
|
||||
// has returned true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string GeomBinTransition::
|
||||
INLINE const string &GeomBinTransition::
|
||||
get_bin() const {
|
||||
nassertr(is_on(), string());
|
||||
nassertr(is_on(), _value);
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ PUBLISHED:
|
||||
INLINE static GeomBinTransition off();
|
||||
|
||||
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;
|
||||
|
||||
public:
|
||||
|
@ -61,3 +61,137 @@ downcase(const string &s) {
|
||||
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 <string>
|
||||
#include <vector_string.h>
|
||||
|
||||
// Case-insensitive string comparison, from Stroustrup's C++ third edition.
|
||||
// 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.
|
||||
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
|
||||
// ostream operator.
|
||||
template<class Thing>
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define LOCAL_LIBS \
|
||||
eggbase progbase
|
||||
#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 \
|
||||
interrogatedb:c dtoolutil:c dconfig:c dtool:m pystub
|
||||
#define UNIX_SYS_LIBS \
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <bamFile.h>
|
||||
#include <node.h>
|
||||
#include <renderRelation.h>
|
||||
#include <geomNode.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -25,6 +26,16 @@ BamInfo() {
|
||||
clear_runlines();
|
||||
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;
|
||||
}
|
||||
|
||||
@ -46,10 +57,10 @@ run() {
|
||||
}
|
||||
|
||||
if (_num_scene_graphs > 0) {
|
||||
nout << "\rScene graph statistics:\n";
|
||||
nout << "\nScene graph statistics:\n";
|
||||
_analyzer.write(nout, 2);
|
||||
}
|
||||
nout << "\r";
|
||||
nout << "\n";
|
||||
|
||||
if (!okflag) {
|
||||
// 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 "
|
||||
<< 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";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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[]) {
|
||||
BamInfo prog;
|
||||
prog.parse_command_line(argc, argv);
|
||||
|
@ -34,10 +34,14 @@ private:
|
||||
bool get_info(const Filename &filename);
|
||||
void describe_scene_graph(Node *node);
|
||||
void describe_general_object(TypedWriteable *object);
|
||||
void list_hierarchy(Node *node, int indent_level);
|
||||
|
||||
typedef vector<Filename> Filenames;
|
||||
Filenames _filenames;
|
||||
|
||||
bool _verbose_geoms;
|
||||
bool _verbose_transitions;
|
||||
|
||||
int _num_scene_graphs;
|
||||
SceneGraphAnalyzer _analyzer;
|
||||
};
|
||||
|
@ -9,115 +9,6 @@
|
||||
#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
|
||||
// of the line into value.
|
||||
void
|
||||
|
@ -7,19 +7,10 @@
|
||||
#define PAL_STRING_UTILS_H
|
||||
|
||||
#include <pandatoolbase.h>
|
||||
#include <vector_string.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
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);
|
||||
|
||||
bool parse_image_type_request(const string &word, PNMFileType *&color_type,
|
||||
|
Loading…
x
Reference in New Issue
Block a user