add PandaNode::set_tag() and related functions

This commit is contained in:
David Rose 2003-06-12 22:18:41 +00:00
parent b6ad0bf0aa
commit c03d886691
16 changed files with 1906 additions and 1447 deletions

View File

@ -632,6 +632,117 @@ get_lod() const {
return *_lod;
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::set_tag
// Access: Published
// Description: Associates a user-defined value with a user-defined
// key which is stored on the node. This value has no
// meaning to Panda; but it is stored indefinitely on
// the node until it is requested again. This value
// will be copied to the PandaNode that is created for
// this particular EggGroup if the egg file is loaded as
// a scene.
//
// Each unique key stores a different string value.
// There is no effective limit on the number of
// different keys that may be stored or on the length of
// any one key's value.
////////////////////////////////////////////////////////////////////
INLINE void EggGroup::
set_tag(const string &key, const string &value) {
_tag_data[key] = value;
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::get_tag
// Access: Published
// Description: Retrieves the user-defined value that was previously
// set on this node for the particular key, if any. If
// no value has been previously set, returns the empty
// string.
////////////////////////////////////////////////////////////////////
INLINE string EggGroup::
get_tag(const string &key) const {
TagData::const_iterator ti;
ti = _tag_data.find(key);
if (ti != _tag_data.end()) {
return (*ti).second;
}
return string();
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::has_tag
// Access: Published
// Description: Returns true if a value has been defined on this node
// for the particular key (even if that value is the
// empty string), or false if no value has been set.
////////////////////////////////////////////////////////////////////
INLINE bool EggGroup::
has_tag(const string &key) const {
TagData::const_iterator ti;
ti = _tag_data.find(key);
return (ti != _tag_data.end());
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::clear_tag
// Access: Published
// Description: Removes the value defined for this key on this
// particular node. After a call to clear_tag(),
// has_tag() will return false for the indicated key.
////////////////////////////////////////////////////////////////////
INLINE void EggGroup::
clear_tag(const string &key) {
_tag_data.erase(key);
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::tag_begin
// Access: Public
// Description: Returns an iterator that can, in conjunction with
// tag_end(), be used to traverse the entire set of
// tag keys. Each iterator returns a pair<string,
// string>.
//
// This interface is not safe to use outside of
// PANDAEGG.DLL.
////////////////////////////////////////////////////////////////////
INLINE EggGroup::TagData::const_iterator EggGroup::
tag_begin() const {
return _tag_data.begin();
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::tag_end
// Access: Public
// Description: Returns an iterator that can, in conjunction with
// tag_begin(), be used to traverse the entire set of
// tag keys. Each iterator returns a pair<string,
// string>.
//
// This interface is not safe to use outside of
// PANDAEGG.DLL.
////////////////////////////////////////////////////////////////////
INLINE EggGroup::TagData::const_iterator EggGroup::
tag_end() const {
return _tag_data.end();
}
////////////////////////////////////////////////////////////////////
// Function: EggGrop::tag_size
// Access: Public
// Description: Returns the number of elements between tag_begin()
// and tag_end().
//
// This interface is not safe to use outside of
// PANDAEGG.DLL.
////////////////////////////////////////////////////////////////////
INLINE EggGroup::TagData::size_type EggGroup::
tag_size() const {
return _tag_data.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::vref_begin

View File

@ -65,6 +65,8 @@ operator = (const EggGroup &copy) {
_collision_name = copy._collision_name;
_fps = copy._fps;
_tag_data = copy._tag_data;
unref_all_vertices();
_vref = copy._vref;
@ -287,6 +289,17 @@ write(ostream &out, int indent_level) const {
EggRenderMode::write(out, indent_level + 2);
TagData::const_iterator ti;
for (ti = _tag_data.begin(); ti != _tag_data.end(); ++ti) {
const string &key = (*ti).first;
const string &value = (*ti).second;
indent(out, indent_level + 2) << "<Tag> ";
enquote_string(out, key) << " {\n";
enquote_string(out, value, indent_level + 4) << "\n";
indent(out, indent_level + 2) << "}\n";
}
// We have to write the children nodes before we write the vertex
// references, since we might be referencing a vertex that's defined
// in one of those children nodes!

View File

@ -40,6 +40,7 @@
class EXPCL_PANDAEGG EggGroup : public EggGroupNode, public EggRenderMode, public EggTransform3d {
public:
typedef pmap<PT_EggVertex, double> VertexRef;
typedef pmap<string, string> TagData;
// These bits are all stored somewhere in _flags.
enum GroupType {
@ -184,6 +185,15 @@ public:
INLINE bool has_lod() const;
INLINE const EggSwitchCondition &get_lod() const;
INLINE void set_tag(const string &key, const string &value);
INLINE string get_tag(const string &key) const;
INLINE bool has_tag(const string &key) const;
INLINE void clear_tag(const string &key);
INLINE TagData::const_iterator tag_begin() const;
INLINE TagData::const_iterator tag_end() const;
INLINE TagData::size_type tag_size() const;
void ref_vertex(EggVertex *vert, double membership = 1.0);
void unref_vertex(EggVertex *vert);
void unref_all_vertices();
@ -249,6 +259,7 @@ private:
string _collision_name;
double _fps;
PT(EggSwitchCondition) _lod;
TagData _tag_data;
VertexRef _vref;

File diff suppressed because it is too large Load Diff

View File

@ -567,6 +567,10 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
accept();
return TABLE_V;
}
"<TAG>" {
accept();
return TAG;
}
"<TEXLIST>" {
accept();
return TEXLIST;

File diff suppressed because it is too large Load Diff

View File

@ -2,85 +2,87 @@
# define BISON_Y_TAB_H
# define NUMBER 257
# define STRING 258
# define BEZIERCURVE 259
# define BFACE 260
# define BILLBOARD 261
# define BILLBOARDCENTER 262
# define BUNDLE 263
# define CLOSED 264
# define COLLIDE 265
# define COMMENT 266
# define COORDSYSTEM 267
# define CV 268
# define DART 269
# define DNORMAL 270
# define DRGBA 271
# define DUV 272
# define DXYZ 273
# define DCS 274
# define DISTANCE 275
# define DTREF 276
# define DYNAMICVERTEXPOOL 277
# define EXTERNAL_FILE 278
# define FLIGHT 279
# define GROUP 280
# define HIP 281
# define INTANGENT 282
# define JOINT 283
# define KNOTS 284
# define INCLUDE 285
# define INSTANCE 286
# define LOOP 287
# define MATERIAL 288
# define MATRIX3 289
# define MATRIX4 290
# define MODEL 291
# define MREF 292
# define NORMAL 293
# define NURBSCURVE 294
# define NURBSSURFACE 295
# define OBJECTTYPE 296
# define ORDER 297
# define OUTTANGENT 298
# define POINTLIGHT 299
# define POLYGON 300
# define REF 301
# define RGBA 302
# define ROTATE 303
# define ROTX 304
# define ROTY 305
# define ROTZ 306
# define SANIM 307
# define SCALAR 308
# define SCALE 309
# define SEQUENCE 310
# define SHADING 311
# define SWITCH 312
# define SWITCHCONDITION 313
# define TABLE 314
# define TABLE_V 315
# define TEXLIST 316
# define TEXTURE 317
# define TLENGTHS 318
# define TRANSFORM 319
# define TRANSLATE 320
# define TREF 321
# define TRIM 322
# define TXT 323
# define UKNOTS 324
# define UV 325
# define VKNOTS 326
# define VERTEX 327
# define VERTEXANIM 328
# define VERTEXPOOL 329
# define VERTEXREF 330
# define XFMANIM 331
# define XFMSANIM 332
# define START_EGG 333
# define START_GROUP_BODY 334
# define START_TEXTURE_BODY 335
# define START_PRIMITIVE_BODY 336
# define ULONG 258
# define STRING 259
# define BEZIERCURVE 260
# define BFACE 261
# define BILLBOARD 262
# define BILLBOARDCENTER 263
# define BUNDLE 264
# define CLOSED 265
# define COLLIDE 266
# define COMMENT 267
# define COORDSYSTEM 268
# define CV 269
# define DART 270
# define DNORMAL 271
# define DRGBA 272
# define DUV 273
# define DXYZ 274
# define DCS 275
# define DISTANCE 276
# define DTREF 277
# define DYNAMICVERTEXPOOL 278
# define EXTERNAL_FILE 279
# define FLIGHT 280
# define GROUP 281
# define HIP 282
# define INTANGENT 283
# define JOINT 284
# define KNOTS 285
# define INCLUDE 286
# define INSTANCE 287
# define LOOP 288
# define MATERIAL 289
# define MATRIX3 290
# define MATRIX4 291
# define MODEL 292
# define MREF 293
# define NORMAL 294
# define NURBSCURVE 295
# define NURBSSURFACE 296
# define OBJECTTYPE 297
# define ORDER 298
# define OUTTANGENT 299
# define POINTLIGHT 300
# define POLYGON 301
# define REF 302
# define RGBA 303
# define ROTATE 304
# define ROTX 305
# define ROTY 306
# define ROTZ 307
# define SANIM 308
# define SCALAR 309
# define SCALE 310
# define SEQUENCE 311
# define SHADING 312
# define SWITCH 313
# define SWITCHCONDITION 314
# define TABLE 315
# define TABLE_V 316
# define TAG 317
# define TEXLIST 318
# define TEXTURE 319
# define TLENGTHS 320
# define TRANSFORM 321
# define TRANSLATE 322
# define TREF 323
# define TRIM 324
# define TXT 325
# define UKNOTS 326
# define UV 327
# define VKNOTS 328
# define VERTEX 329
# define VERTEXANIM 330
# define VERTEXPOOL 331
# define VERTEXREF 332
# define XFMANIM 333
# define XFMSANIM 334
# define START_EGG 335
# define START_GROUP_BODY 336
# define START_TEXTURE_BODY 337
# define START_PRIMITIVE_BODY 338
extern YYSTYPE eggyylval;

View File

@ -125,7 +125,7 @@ egg_cleanup_parser() {
%token NURBSCURVE NURBSSURFACE OBJECTTYPE ORDER
%token OUTTANGENT POINTLIGHT POLYGON REF RGBA ROTATE ROTX ROTY ROTZ
%token SANIM SCALAR SCALE SEQUENCE SHADING SWITCH SWITCHCONDITION
%token TABLE TABLE_V TEXLIST TEXTURE TLENGTHS TRANSFORM TRANSLATE
%token TABLE TABLE_V TAG TEXLIST TEXTURE TLENGTHS TRANSFORM TRANSLATE
%token TREF TRIM TXT UKNOTS UV VKNOTS VERTEX VERTEXANIM
%token VERTEXPOOL VERTEXREF
%token XFMANIM XFMSANIM
@ -995,6 +995,11 @@ group_body:
EggGroup *group = DCAST(EggGroup, egg_stack.back());
int value = (int)$4;
group->set_model_flag(value!=0);
}
| group_body TAG optional_name '{' repeated_string '}'
{
EggGroup *group = DCAST(EggGroup, egg_stack.back());
group->set_tag($3, $5);
}
| group_body TEXLIST '{' integer '}'
{

View File

@ -1467,6 +1467,12 @@ create_group_arc(EggGroup *egg_group, PandaNode *parent, PandaNode *node) {
_decals.insert(node);
}
// Copy all the tags from the group onto the node.
EggGroup::TagData::const_iterator ti;
for (ti = egg_group->tag_begin(); ti != egg_group->tag_end(); ++ti) {
node->set_tag((*ti).first, (*ti).second);
}
// If the group specified some property that should propagate down
// to the leaves, we have to remember this node and apply the
// property later, after we've created the actual geometry.

View File

@ -1124,6 +1124,65 @@ compare_to(const NodePath &other) const {
return _head - other._head;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_tag
// Access: Published
// Description: Associates a user-defined value with a user-defined
// key which is stored on the node. This value has no
// meaning to Panda; but it is stored indefinitely on
// the node until it is requested again.
//
// Each unique key stores a different string value.
// There is no effective limit on the number of
// different keys that may be stored or on the length of
// any one key's value.
////////////////////////////////////////////////////////////////////
INLINE void NodePath::
set_tag(const string &key, const string &value) {
nassertv_always(!is_empty());
node()->set_tag(key, value);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::get_tag
// Access: Published
// Description: Retrieves the user-defined value that was previously
// set on this node for the particular key, if any. If
// no value has been previously set, returns the empty
// string.
////////////////////////////////////////////////////////////////////
INLINE string NodePath::
get_tag(const string &key) const {
nassertr_always(!is_empty(), string());
return node()->get_tag(key);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::has_tag
// Access: Published
// Description: Returns true if a value has been defined on this node
// for the particular key (even if that value is the
// empty string), or false if no value has been set.
////////////////////////////////////////////////////////////////////
INLINE bool NodePath::
has_tag(const string &key) const {
nassertr_always(!is_empty(), false);
return node()->has_tag(key);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::clear_tag
// Access: Published
// Description: Removes the value defined for this key on this
// particular node. After a call to clear_tag(),
// has_tag() will return false for the indicated key.
////////////////////////////////////////////////////////////////////
INLINE void NodePath::
clear_tag(const string &key) {
nassertv_always(!is_empty());
node()->clear_tag(key);
}
INLINE ostream &operator << (ostream &out, const NodePath &node_path) {
node_path.output(out);

View File

@ -519,6 +519,11 @@ PUBLISHED:
int flatten_medium();
int flatten_strong();
INLINE void set_tag(const string &key, const string &value);
INLINE string get_tag(const string &key) const;
INLINE bool has_tag(const string &key) const;
INLINE void clear_tag(const string &key);
bool write_bam_file(const string &filename) const;
private:

View File

@ -137,6 +137,7 @@ CData(const PandaNode::CData &copy) :
_state(copy._state),
_effects(copy._effects),
_transform(copy._transform),
_tag_data(copy._tag_data),
_draw_mask(copy._draw_mask),
_fixed_internal_bound(copy._fixed_internal_bound)
{
@ -657,6 +658,72 @@ clear_transform() {
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::set_tag
// Access: Published
// Description: Associates a user-defined value with a user-defined
// key which is stored on the node. This value has no
// meaning to Panda; but it is stored indefinitely on
// the node until it is requested again.
//
// Each unique key stores a different string value.
// There is no effective limit on the number of
// different keys that may be stored or on the length of
// any one key's value.
////////////////////////////////////////////////////////////////////
INLINE void PandaNode::
set_tag(const string &key, const string &value) {
CDWriter cdata(_cycler);
cdata->_tag_data[key] = value;
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::get_tag
// Access: Published
// Description: Retrieves the user-defined value that was previously
// set on this node for the particular key, if any. If
// no value has been previously set, returns the empty
// string.
////////////////////////////////////////////////////////////////////
INLINE string PandaNode::
get_tag(const string &key) const {
CDReader cdata(_cycler);
TagData::const_iterator ti;
ti = cdata->_tag_data.find(key);
if (ti != cdata->_tag_data.end()) {
return (*ti).second;
}
return string();
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::has_tag
// Access: Published
// Description: Returns true if a value has been defined on this node
// for the particular key (even if that value is the
// empty string), or false if no value has been set.
////////////////////////////////////////////////////////////////////
INLINE bool PandaNode::
has_tag(const string &key) const {
CDReader cdata(_cycler);
TagData::const_iterator ti;
ti = cdata->_tag_data.find(key);
return (ti != cdata->_tag_data.end());
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::clear_tag
// Access: Published
// Description: Removes the value defined for this key on this
// particular node. After a call to clear_tag(),
// has_tag() will return false for the indicated key.
////////////////////////////////////////////////////////////////////
INLINE void PandaNode::
clear_tag(const string &key) {
CDWriter cdata(_cycler);
cdata->_tag_data.erase(key);
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::ls
// Access: Published

View File

@ -134,6 +134,13 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
write_up_list(_up, manager, dg);
write_down_list(_down, manager, dg);
write_down_list(_stashed, manager, dg);
dg.add_uint32(_tag_data.size());
TagData::const_iterator ti;
for (ti = _tag_data.begin(); ti != _tag_data.end(); ++ti) {
dg.add_string((*ti).first);
dg.add_string((*ti).second);
}
}
////////////////////////////////////////////////////////////////////
@ -192,6 +199,16 @@ fillin(DatagramIterator &scan, BamReader *manager) {
fillin_up_list(_up, scan, manager);
fillin_down_list(_down, scan, manager);
fillin_down_list(_stashed, scan, manager);
// Read in the tag list.
if (manager->get_file_minor_ver() >= 4) {
int num_tags = scan.get_uint32();
for (int i = 0; i < num_tags; i++) {
string key = scan.get_string();
string value = scan.get_string();
_tag_data[key] = value;
}
}
}
////////////////////////////////////////////////////////////////////
@ -1242,6 +1259,57 @@ copy_children(PandaNode *other) {
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::copy_tags
// Access: Published
// Description: Copies all of the tags stored on the other node onto
// this node. If a particular tag exists on both nodes,
// the contents of this node's value is replaced by that
// of the other.
////////////////////////////////////////////////////////////////////
void PandaNode::
copy_tags(PandaNode *other) {
if (other == this) {
// Trivial.
return;
}
CDWriter cdataw(_cycler);
CDReader cdatar(other->_cycler);
TagData::const_iterator ti;
for (ti = cdatar->_tag_data.begin();
ti != cdatar->_tag_data.end();
++ti) {
cdataw->_tag_data[(*ti).first] = (*ti).second;
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::list_tags
// Access: Published
// Description: Writes a list of all the tag keys assigned to the
// node to the indicated stream. Writes one instance of
// the separator following each key (but does not write
// a terminal separator). The value associated with
// each key is not written.
//
// This is mainly for the benefit of the realtime user,
// to see the list of all of the associated tag keys.
////////////////////////////////////////////////////////////////////
void PandaNode::
list_tags(ostream &out, const string &separator) const {
CDReader cdata(_cycler);
if (!cdata->_tag_data.empty()) {
TagData::const_iterator ti = cdata->_tag_data.begin();
out << (*ti).first;
++ti;
while (ti != cdata->_tag_data.end()) {
out << separator << (*ti).first;
++ti;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaNode::output
// Access: Published, Virtual
@ -1261,6 +1329,11 @@ void PandaNode::
write(ostream &out, int indent_level) const {
indent(out, indent_level) << *this;
CDReader cdata(_cycler);
if (!cdata->_tag_data.empty()) {
out << " [";
list_tags(out, " ");
out << "]";
}
if (!cdata->_transform->is_identity()) {
out << " " << *cdata->_transform;
}
@ -1984,6 +2057,11 @@ void PandaNode::
r_list_descendants(ostream &out, int indent_level) const {
CDReader cdata(_cycler);
indent(out, indent_level) << *this;
if (!cdata->_tag_data.empty()) {
out << " [";
list_tags(out, " ");
out << "]";
}
if (!cdata->_transform->is_identity()) {
out << " " << *cdata->_transform;
}

View File

@ -150,6 +150,13 @@ PUBLISHED:
INLINE const TransformState *get_transform() const;
INLINE void clear_transform();
INLINE void set_tag(const string &key, const string &value);
INLINE string get_tag(const string &key) const;
INLINE bool has_tag(const string &key) const;
INLINE void clear_tag(const string &key);
void copy_tags(PandaNode *other);
void list_tags(ostream &out, const string &separator = "\n") const;
INLINE void set_draw_mask(DrawMask mask);
INLINE DrawMask get_draw_mask() const;
@ -262,6 +269,11 @@ private:
// each NodePathComponent destructs, it removes itself from this
// set.
typedef pset<NodePathComponent *> Paths;
// This is used to maintain a table of keyed data on each node, for
// the user's purposes.
typedef pmap<string, string> TagData;
// This is the data that must be cycled between pipeline stages.
class EXPCL_PANDA CData : public CycleData {
@ -295,6 +307,8 @@ private:
CPT(RenderEffects) _effects;
CPT(TransformState) _transform;
TagData _tag_data;
// This is the draw_mask of this particular node.
DrawMask _draw_mask;

View File

@ -440,10 +440,12 @@ do_flatten_child(PandaNode *grandparent_node, PandaNode *parent_node,
if (new_parent != child_node) {
new_parent->steal_children(child_node);
new_parent->copy_tags(child_node);
}
if (new_parent != parent_node) {
grandparent_node->replace_child(parent_node, new_parent);
new_parent->copy_tags(parent_node);
}
return true;
@ -456,7 +458,7 @@ do_flatten_child(PandaNode *grandparent_node, PandaNode *parent_node,
// together into a single node, leaving the resulting
// node attached to the parent.
//
// Returns a pointer to a PandaNode the reflects the
// Returns a pointer to a PandaNode that reflects the
// combined node (which may be either of the source nodes,
// or a new node altogether) if the siblings are
// successfully collapsed, or NULL if we chickened out.
@ -483,16 +485,20 @@ do_flatten_siblings(PandaNode *parent_node, PandaNode *child1,
if (new_child == child1) {
new_child->steal_children(child2);
parent_node->remove_child(child2);
new_child->copy_tags(child2);
} else if (new_child == child2) {
new_child->steal_children(child1);
parent_node->remove_child(child1);
new_child->copy_tags(child1);
} else {
new_child->steal_children(child1);
new_child->steal_children(child2);
parent_node->remove_child(child2);
parent_node->replace_child(child1, new_child);
new_child->copy_tags(child1);
new_child->copy_tags(child2);
}
return new_child;

View File

@ -34,10 +34,11 @@ static const unsigned short _bam_major_ver = 4;
// Bumped to major version 3 on 12/8/00 to change float64's to float32's.
// Bumped to major version 4 on 4/10/02 to store new scene graph.
static const unsigned short _bam_minor_ver = 3;
static const unsigned short _bam_minor_ver = 4;
// Bumped to minor version 1 on 4/10/03 to add CullFaceAttrib::reverse.
// Bumped to minor version 2 on 4/12/03 to add num_components to texture.
// Bumped to minor version 3 on 4/15/03 to add ImageBuffer::_alpha_file_channel.
// Bumped to minor version 3 on 4/15/03 to add ImageBuffer::_alpha_file_channel
// Bumped to minor version 4 on 6/12/03 to add PandaNode::set_tag().
#endif