support instancing syntax

This commit is contained in:
David Rose 2008-10-30 22:26:57 +00:00
parent d2d151010f
commit 83d21bc2b1
6 changed files with 1083 additions and 898 deletions

View File

@ -121,6 +121,14 @@ EggGroup::
void EggGroup::
set_group_type(GroupType type) {
if (type != get_group_type()) {
#ifndef NDEBUG
if (type != GT_instance) {
// Only valid to change to a non-instance type if we have no
// group refs.
nassertv(_group_refs.empty());
}
#endif
// Make sure the user didn't give us any stray bits.
nassertv((type & ~F_group_type)==0);
_flags = (_flags & ~F_group_type) | type;
@ -259,6 +267,13 @@ write(ostream &out, int indent_level) const {
<< "<Scalar> blenda { " << c[3] << " }\n";
}
GroupRefs::const_iterator gri;
for (gri = _group_refs.begin(); gri != _group_refs.end(); ++gri) {
EggGroup *group_ref = (*gri);
indent(out, indent_level + 2)
<< "<Ref> { " << group_ref->get_name() << " }\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!
@ -767,6 +782,65 @@ test_vref_integrity() const {
#endif // NDEBUG
////////////////////////////////////////////////////////////////////
// Function: EggGroup::add_group_ref
// Access: Published
// Description: Adds a new <Ref> entry to the group. This declares
// an internal reference to another node, and is used to
// implement scene-graph instancing; it is only valid if
// the group_type is GT_instance.
////////////////////////////////////////////////////////////////////
void EggGroup::
add_group_ref(EggGroup *group) {
nassertv(get_group_type() == GT_instance);
_group_refs.push_back(group);
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::get_num_group_refs
// Access: Published
// Description: Returns the number of <Ref> entries within this
// group. See add_group_ref().
////////////////////////////////////////////////////////////////////
int EggGroup::
get_num_group_refs() const {
return _group_refs.size();
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::get_group_ref
// Access: Published
// Description: Returns the nth <Ref> entry within this group. See
// add_group_ref().
////////////////////////////////////////////////////////////////////
EggGroup *EggGroup::
get_group_ref(int n) const {
nassertr(n >= 0 && n < (int)_group_refs.size(), NULL);
return _group_refs[n];
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::remove_group_ref
// Access: Published
// Description: Removes the nth <Ref> entry within this group. See
// add_group_ref().
////////////////////////////////////////////////////////////////////
void EggGroup::
remove_group_ref(int n) {
nassertv(n >= 0 && n < (int)_group_refs.size());
_group_refs.erase(_group_refs.begin() + n);
}
////////////////////////////////////////////////////////////////////
// Function: EggGroup::clear_group_refs
// Access: Published
// Description: Removes all of the <Ref> entries within this group.
// See add_group_ref().
////////////////////////////////////////////////////////////////////
void EggGroup::
clear_group_refs() {
_group_refs.clear();
}

View File

@ -285,6 +285,12 @@ PUBLISHED:
void test_vref_integrity() const { }
#endif // NDEBUG
void add_group_ref(EggGroup *group);
int get_num_group_refs() const;
EggGroup *get_group_ref(int n) const;
void remove_group_ref(int n);
void clear_group_refs();
static GroupType string_group_type(const string &strval);
static DartType string_dart_type(const string &strval);
static DCSType string_dcs_type(const string &strval);
@ -353,6 +359,9 @@ private:
TagData _tag_data;
VertexRef _vref;
typedef pvector< PT(EggGroup) > GroupRefs;
GroupRefs _group_refs;
public:

File diff suppressed because it is too large Load Diff

View File

@ -79,6 +79,10 @@ static Textures textures;
typedef pmap<string, PT_EggMaterial > Materials;
static Materials materials;
// Group names to groups.
typedef pmap<string, PT(EggGroup) > Groups;
static Groups groups;
// We need to be able to save the index number requested for a vertex
// temporarily.
static int vertex_index;
@ -101,6 +105,7 @@ egg_init_parser(istream &in, const string &filename,
vertex_pools.clear();
textures.clear();
materials.clear();
groups.clear();
egg_stack.push_back(tos);
egg_top_node = top_node;
@ -140,6 +145,7 @@ egg_cleanup_parser() {
vertex_pools.clear();
textures.clear();
materials.clear();
groups.clear();
}
%}
@ -208,6 +214,7 @@ egg_cleanup_parser() {
%type <_egg> texture_name
%type <_egg> material_name
%type <_egg> vertex_pool_name
%type <_egg> group_name
%type <_number> real
%type <_number> integer
@ -1137,8 +1144,12 @@ group:
}
'{' group_body '}'
{
$$ = egg_stack.back();
EggGroup *group = DCAST(EggGroup, egg_stack.back());
$$ = group;
egg_stack.pop_back();
if (group->has_name()) {
groups[group->get_name()] = group;
}
Thread::consider_yield();
}
;
@ -1180,8 +1191,12 @@ instance:
}
'{' group_body '}'
{
$$ = egg_stack.back();
EggGroup *group = DCAST(EggGroup, egg_stack.back());
$$ = group;
egg_stack.pop_back();
if (group->has_name()) {
groups[group->get_name()] = group;
}
}
;
@ -1419,6 +1434,15 @@ group_body:
| group_body transform
| group_body group_vertex_ref
| group_body switchcondition
| group_body REF '{' group_name '}'
{
EggGroup *group = DCAST(EggGroup, egg_stack.back());
if (group->get_group_type() != EggGroup::GT_instance) {
eggyyerror("<Ref> valid only within <Instance>");
} else if ($4 != (EggObject *)NULL) {
group->add_group_ref(DCAST(EggGroup, $4));
}
}
| group_body node
{
DCAST(EggGroup, egg_stack.back())->add_child(DCAST(EggNode, $2));
@ -2825,6 +2849,26 @@ vertex_pool_name:
}
;
/*
* group_name
*
* enter:
* exit: Returns an EggGroup pointer, or NULL.
*
*/
group_name:
required_name
{
string name = $1;
Groups::iterator vpi = groups.find(name);
if (vpi == groups.end()) {
eggyyerror("Unknown group " + name);
$$ = PT(EggObject)();
} else {
$$ = (*vpi).second;
}
}
;
/*
* required_name

View File

@ -1758,6 +1758,7 @@ make_lod(EggBin *egg_bin, PandaNode *parent) {
lod_node->add_switch(instance._d->_switch_in, instance._d->_switch_out);
}
_groups[egg_bin] = lod_node;
return create_group_arc(egg_bin, parent, lod_node);
}
@ -1897,6 +1898,19 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
if (node == (PandaNode *)NULL) {
return NULL;
}
// Associate any instances with this node.
int num_group_refs = egg_group->get_num_group_refs();
for (int gri = 0; gri < num_group_refs; ++gri) {
EggGroup *group_ref = egg_group->get_group_ref(gri);
Groups::const_iterator gi = _groups.find(group_ref);
if (gi != _groups.end()) {
PandaNode *node_ref = (*gi).second;
node->add_child(node_ref);
}
}
_groups[egg_group] = node;
return create_group_arc(egg_group, parent, node);
}

View File

@ -224,6 +224,9 @@ private:
Materials _materials;
Materials _materials_bface;
typedef pmap<PT(EggGroup), PT(PandaNode) > Groups;
Groups _groups;
typedef pset<PandaNode *> ExtraNodes;
ExtraNodes _decals;
ExtraNodes _sequences;