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; 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 // Function: EggGroup::vref_begin

View File

@ -65,6 +65,8 @@ operator = (const EggGroup &copy) {
_collision_name = copy._collision_name; _collision_name = copy._collision_name;
_fps = copy._fps; _fps = copy._fps;
_tag_data = copy._tag_data;
unref_all_vertices(); unref_all_vertices();
_vref = copy._vref; _vref = copy._vref;
@ -287,6 +289,17 @@ write(ostream &out, int indent_level) const {
EggRenderMode::write(out, indent_level + 2); 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 // We have to write the children nodes before we write the vertex
// references, since we might be referencing a vertex that's defined // references, since we might be referencing a vertex that's defined
// in one of those children nodes! // in one of those children nodes!

View File

@ -40,6 +40,7 @@
class EXPCL_PANDAEGG EggGroup : public EggGroupNode, public EggRenderMode, public EggTransform3d { class EXPCL_PANDAEGG EggGroup : public EggGroupNode, public EggRenderMode, public EggTransform3d {
public: public:
typedef pmap<PT_EggVertex, double> VertexRef; typedef pmap<PT_EggVertex, double> VertexRef;
typedef pmap<string, string> TagData;
// These bits are all stored somewhere in _flags. // These bits are all stored somewhere in _flags.
enum GroupType { enum GroupType {
@ -184,6 +185,15 @@ public:
INLINE bool has_lod() const; INLINE bool has_lod() const;
INLINE const EggSwitchCondition &get_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 ref_vertex(EggVertex *vert, double membership = 1.0);
void unref_vertex(EggVertex *vert); void unref_vertex(EggVertex *vert);
void unref_all_vertices(); void unref_all_vertices();
@ -249,6 +259,7 @@ private:
string _collision_name; string _collision_name;
double _fps; double _fps;
PT(EggSwitchCondition) _lod; PT(EggSwitchCondition) _lod;
TagData _tag_data;
VertexRef _vref; 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(); accept();
return TABLE_V; return TABLE_V;
} }
"<TAG>" {
accept();
return TAG;
}
"<TEXLIST>" { "<TEXLIST>" {
accept(); accept();
return TEXLIST; return TEXLIST;

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1467,6 +1467,12 @@ create_group_arc(EggGroup *egg_group, PandaNode *parent, PandaNode *node) {
_decals.insert(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 // If the group specified some property that should propagate down
// to the leaves, we have to remember this node and apply the // to the leaves, we have to remember this node and apply the
// property later, after we've created the actual geometry. // 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; 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) { INLINE ostream &operator << (ostream &out, const NodePath &node_path) {
node_path.output(out); node_path.output(out);

View File

@ -519,6 +519,11 @@ PUBLISHED:
int flatten_medium(); int flatten_medium();
int flatten_strong(); 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; bool write_bam_file(const string &filename) const;
private: private:

View File

@ -137,6 +137,7 @@ CData(const PandaNode::CData &copy) :
_state(copy._state), _state(copy._state),
_effects(copy._effects), _effects(copy._effects),
_transform(copy._transform), _transform(copy._transform),
_tag_data(copy._tag_data),
_draw_mask(copy._draw_mask), _draw_mask(copy._draw_mask),
_fixed_internal_bound(copy._fixed_internal_bound) _fixed_internal_bound(copy._fixed_internal_bound)
{ {
@ -657,6 +658,72 @@ clear_transform() {
transform_changed(); 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 // Function: PandaNode::ls
// Access: Published // Access: Published

View File

@ -134,6 +134,13 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
write_up_list(_up, manager, dg); write_up_list(_up, manager, dg);
write_down_list(_down, manager, dg); write_down_list(_down, manager, dg);
write_down_list(_stashed, 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_up_list(_up, scan, manager);
fillin_down_list(_down, scan, manager); fillin_down_list(_down, scan, manager);
fillin_down_list(_stashed, 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 // Function: PandaNode::output
// Access: Published, Virtual // Access: Published, Virtual
@ -1261,6 +1329,11 @@ void PandaNode::
write(ostream &out, int indent_level) const { write(ostream &out, int indent_level) const {
indent(out, indent_level) << *this; indent(out, indent_level) << *this;
CDReader cdata(_cycler); CDReader cdata(_cycler);
if (!cdata->_tag_data.empty()) {
out << " [";
list_tags(out, " ");
out << "]";
}
if (!cdata->_transform->is_identity()) { if (!cdata->_transform->is_identity()) {
out << " " << *cdata->_transform; out << " " << *cdata->_transform;
} }
@ -1984,6 +2057,11 @@ void PandaNode::
r_list_descendants(ostream &out, int indent_level) const { r_list_descendants(ostream &out, int indent_level) const {
CDReader cdata(_cycler); CDReader cdata(_cycler);
indent(out, indent_level) << *this; indent(out, indent_level) << *this;
if (!cdata->_tag_data.empty()) {
out << " [";
list_tags(out, " ");
out << "]";
}
if (!cdata->_transform->is_identity()) { if (!cdata->_transform->is_identity()) {
out << " " << *cdata->_transform; out << " " << *cdata->_transform;
} }

View File

@ -150,6 +150,13 @@ PUBLISHED:
INLINE const TransformState *get_transform() const; INLINE const TransformState *get_transform() const;
INLINE void clear_transform(); 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 void set_draw_mask(DrawMask mask);
INLINE DrawMask get_draw_mask() const; INLINE DrawMask get_draw_mask() const;
@ -262,6 +269,11 @@ private:
// each NodePathComponent destructs, it removes itself from this // each NodePathComponent destructs, it removes itself from this
// set. // set.
typedef pset<NodePathComponent *> Paths; 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. // This is the data that must be cycled between pipeline stages.
class EXPCL_PANDA CData : public CycleData { class EXPCL_PANDA CData : public CycleData {
@ -295,6 +307,8 @@ private:
CPT(RenderEffects) _effects; CPT(RenderEffects) _effects;
CPT(TransformState) _transform; CPT(TransformState) _transform;
TagData _tag_data;
// This is the draw_mask of this particular node. // This is the draw_mask of this particular node.
DrawMask _draw_mask; DrawMask _draw_mask;

View File

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