54       << 
"The EggGroupNode copy constructor does not copy children!\n";
    65       << 
"The EggGroupNode copy assignment does not copy children!\n";
    67   EggNode::operator =(copy);
    84 write(std::ostream &out, 
int indent_level)
 const {
    92   for (i = begin(); i != end(); ++i) {
    94     if (!child->is_joint()) {
    95       child->write(out, indent_level);
    99   for (i = begin(); i != end(); ++i) {
   101     if (child->is_joint()) {
   102       child->write(out, indent_level);
   110 EggGroupNode::iterator EggGroupNode::
   112   return _children.begin();
   118 EggGroupNode::iterator EggGroupNode::
   120   return _children.end();
   126 EggGroupNode::reverse_iterator EggGroupNode::
   128   return _children.rbegin();
   134 EggGroupNode::reverse_iterator EggGroupNode::
   136   return _children.rend();
   142 EggGroupNode::iterator EggGroupNode::
   143 insert(iterator position, 
PT(
EggNode) x) {
   144   prepare_add_child(x);
   145   return _children.insert((Children::iterator &)position, x);
   151 EggGroupNode::iterator EggGroupNode::
   152 erase(iterator position) {
   153   prepare_remove_child(*position);
   154   return _children.erase((Children::iterator &)position);
   160 EggGroupNode::iterator EggGroupNode::
   161 erase(iterator first, iterator last) {
   163   for (i = first; i != last; ++i) {
   164     prepare_remove_child(*i);
   166   return _children.erase((Children::iterator &)first,
   167                          (Children::iterator &)last);
   176   nassertv(position != end());
   178   prepare_remove_child(*position);
   179   prepare_add_child(x);
   180   *(Children::iterator &)position = x;
   188   return _children.empty();
   194 EggGroupNode::size_type EggGroupNode::
   196   return _children.size();
   204   erase(begin(), end());
   216   _gnc_iterator = begin();
   232   if (_gnc_iterator != end()) {
   233     return *_gnc_iterator++;
   246   if (node->_parent != 
nullptr) {
   247     node->_parent->remove_child(node);
   249   prepare_add_child(node);
   250   _children.push_back(node);
   261   iterator i = find(begin(), end(), ptnode);
   279   Children::iterator ci;
   280   for (ci = other._children.begin();
   281        ci != other._children.end();
   283     other.prepare_remove_child(*ci);
   284     prepare_add_child(*ci);
   287   _children.splice(_children.end(), other._children);
   297   Children::const_iterator ci;
   298   for (ci = _children.begin(); ci != _children.end(); ++ci) {
   300     if (child->get_name() == name) {
   314   Children::const_iterator ci;
   315   for (ci = _children.begin();
   316        ci != _children.end();
   319     if (child->
is_of_type(EggTexture::get_class_type())) {
   322         if (egg_cat.is_debug()) {
   332           if (egg_cat.is_debug()) {
   341     } 
else if (child->
is_of_type(EggFilenameNode::get_class_type())) {
   344         if (egg_cat.is_debug()) {
   352     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   353       if (DCAST(
EggGroupNode, child)->has_absolute_pathnames()) {
   371   Children::iterator ci;
   372   for (ci = _children.begin();
   373        ci != _children.end();
   376     if (child->
is_of_type(EggTexture::get_class_type())) {
   380       tex->set_filename(tex_filename);
   388     } 
else if (child->
is_of_type(EggFilenameNode::get_class_type())) {
   392       fnode->set_filename(filename);
   394     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   395       DCAST(
EggGroupNode, child)->resolve_filenames(searchpath);
   407   Children::iterator ci;
   408   for (ci = _children.begin();
   409        ci != _children.end();
   412     if (child->
is_of_type(EggTexture::get_class_type())) {
   416         tex->set_filename(
Filename(directory, tex_filename));
   426     } 
else if (child->
is_of_type(EggFilenameNode::get_class_type())) {
   430         fnode->set_filename(
Filename(directory, filename));
   433     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   445   Children::iterator ci;
   446   for (ci = _children.begin();
   447        ci != _children.end();
   450     if (child->
is_of_type(EggPrimitive::get_class_type())) {
   454     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   478   r_collect_vertex_normals(collection, threshold, cs);
   484   double cos_angle = cos(deg_2_rad(threshold));
   486   NVertexCollection::iterator ci;
   487   for (ci = collection.begin(); ci != collection.end(); ++ci) {
   493     NVertexGroup::iterator gi;
   495     while (gi != group.end()) {
   496       const NVertexReference &base_ref = (*gi);
   499       new_group.push_back(base_ref);
   502       while (gi != group.end()) {
   503         const NVertexReference &
ref = (*gi);
   504         double dot = base_ref._normal.dot(
ref._normal);
   505         if (dot > cos_angle) {
   507           new_group.push_back(
ref);
   510           leftover_group.push_back(
ref);
   517       do_compute_vertex_normals(new_group);
   520       group.swap(leftover_group);
   542   Children::iterator ci, cnext;
   543   ci = _children.begin();
   544   while (ci != _children.end()) {
   549     if (child->
is_of_type(EggPolygon::get_class_type())) {
   554         prepare_remove_child(child);
   559         size_t num_vertices = polygon->size();
   560         for (
size_t i = 0; i < num_vertices; i++) {
   564           if (vertex->has_normal()) {
   566             new_vertex.clear_normal();
   575     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   576       DCAST(
EggGroupNode, child)->recompute_polygon_normals(cs);
   593   Children::iterator ci;
   594   for (ci = _children.begin(); ci != _children.end(); ++ci) {
   597     if (child->
is_of_type(EggPrimitive::get_class_type())) {
   599       prim->clear_normal();
   602       size_t num_vertices = prim->size();
   603       for (
size_t i = 0; i < num_vertices; i++) {
   607         if (vertex->has_normal()) {
   609           new_vertex.clear_normal();
   617     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   642   r_collect_tangent_binormal(uv_name, collection);
   646   TBNVertexCollection::const_iterator ci;
   647   for (ci = collection.begin(); ci != collection.end(); ++ci) {
   648     const TBNVertexValue &value = (*ci).first;
   651     do_compute_tangent_binormal(value, group);
   663   bool changed = 
false;
   665   for (vector_string::const_iterator si = names.begin();
   669     nout << 
"Computing tangent and binormal for \"" << uv_name << 
"\"\n";
   686   EggTextureCollection::iterator eti;
   688   for (eti = texs.begin(); eti != texs.end(); eti++) {
   690     if ((eggtex->get_env_type() == EggTexture::ET_normal)||
   691         (eggtex->get_env_type() == EggTexture::ET_normal_height)||
   692         (eggtex->get_env_type() == EggTexture::ET_normal_gloss)) {
   694       vector_string::iterator it = find(names.begin(), names.end(), uv);
   695       if (it == names.end()) {
   714   int num_produced = 0;
   718   Children::iterator ci;
   719   for (ci = children_copy.begin();
   720        ci != children_copy.end();
   724     if (child->
is_of_type(EggPolygon::get_class_type())) {
   725       if ((flags & T_polygon) != 0) {
   727         poly->triangulate_in_place((flags & T_convex) != 0);
   730     } 
else if (child->
is_of_type(EggCompositePrimitive::get_class_type())) {
   731       if ((flags & T_composite) != 0) {
   733         comp->triangulate_in_place();
   736     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   737       if ((flags & T_recurse) != 0) {
   738         num_produced += DCAST(
EggGroupNode, child)->triangulate_polygons(flags);
   743   num_produced += std::max(0, (
int)(_children.size() - children_copy.size()));
   753   mesher.
mesh(
this, (flags & T_flat_shaded) != 0);
   755   if ((flags & T_recurse) != 0) {
   756     EggGroupNode::iterator ci;
   757     for (ci = begin(); ci != end(); ++ci) {
   758       if ((*ci)->is_of_type(EggGroupNode::get_class_type())) {
   777   EggGroupNode::iterator ci;
   778   for (ci = begin(); ci != end(); ++ci) {
   779     if ((*ci)->is_of_type(EggGroupNode::get_class_type())) {
   783     } 
else if ((*ci)->is_of_type(EggVertexPool::get_class_type())) {
   787       if (!prim->empty()) {
   788         temp->add_child(prim);
   802   for (
unsigned int ni = 0; ni < strip_prefix.size(); ++ni) {
   803     string axe_name = strip_prefix[ni];
   804     if (this->get_name().substr(0, axe_name.size()) == axe_name) {
   805       string new_name = this->get_name().substr(axe_name.size());
   807       this->set_name(new_name);
   812     EggGroupNode::iterator ci;
   813     for (ci = begin(); ci != end(); ++ci) {
   814       if ((*ci)->is_of_type(EggGroupNode::get_class_type())) {
   816         num_renamed += group_child->
rename_nodes(strip_prefix, recurse);
   818       else if ((*ci)->is_of_type(EggNode::get_class_type())) {
   820         num_renamed += node_child->
rename_node(strip_prefix);
   844   Children::iterator ci, cnext;
   845   ci = _children.begin();
   846   while (ci != _children.end()) {
   851     if (child->
is_of_type(EggVertexPool::get_class_type())) {
   855       if (vpool->
empty()) {
   861     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   863         num_removed += DCAST(
EggGroupNode, child)->remove_unused_vertices(recurse);
   882   Children::iterator ci, cnext;
   883   ci = _children.begin();
   884   while (ci != _children.end()) {
   889     if (child->
is_of_type(EggPrimitive::get_class_type())) {
   896     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   898         num_removed += DCAST(
EggGroupNode, child)->remove_invalid_primitives(recurse);
   918   Children::iterator ci;
   919   for (ci = _children.begin(); ci != _children.end(); ++ci) {
   922     if (child->
is_of_type(EggPrimitive::get_class_type())) {
   925     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   938   Children::iterator ci;
   939   for (ci = _children.begin(); ci != _children.end(); ++ci) {
   942     if (child->
is_of_type(EggPrimitive::get_class_type())) {
   945     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   976   Children::iterator ci;
   977   for (ci = _children.begin(); ci != _children.end(); ++ci) {
   980     if (child->
is_of_type(EggPrimitive::get_class_type())) {
   983       EggPrimitive::Shading shading = EggPrimitive::S_per_vertex;
   985       if (allow_per_primitive) {
   987         if (use_connected_shading) {
   994     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
   997           (use_connected_shading, allow_per_primitive, recurse);
  1014   Children::iterator ci;
  1015   for (ci = _children.begin(); ci != _children.end(); ++ci) {
  1018     if (child->
is_of_type(EggPrimitive::get_class_type())) {
  1021     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1023         DCAST(
EggGroupNode, child)->apply_last_attribute(recurse);
  1040   Children::iterator ci;
  1041   for (ci = _children.begin(); ci != _children.end(); ++ci) {
  1044     if (child->
is_of_type(EggPrimitive::get_class_type())) {
  1047     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1049         DCAST(
EggGroupNode, child)->apply_first_attribute(recurse);
  1062   Children::iterator ci;
  1063   for (ci = _children.begin(); ci != _children.end(); ++ci) {
  1066     if (child->
is_of_type(EggPrimitive::get_class_type())) {
  1069     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1071         DCAST(
EggGroupNode, child)->post_apply_flat_attribute(recurse);
  1083   Children::const_iterator ci;
  1084   for (ci = _children.begin();
  1085        ci != _children.end();
  1087     if ((*ci)->has_primitives()) {
  1101   Children::const_iterator ci;
  1102   for (ci = _children.begin();
  1103        ci != _children.end();
  1108       if (child->joint_has_primitives()) {
  1123   Children::const_iterator ci;
  1124   for (ci = _children.begin();
  1125        ci != _children.end();
  1127     if ((*ci)->has_normals()) {
  1147   Children::iterator ci;
  1148   for (ci = _children.begin(); ci != _children.end(); ++ci) {
  1151     if (child->
is_of_type(EggPrimitive::get_class_type())) {
  1157       EggPrimitive::const_iterator pi;
  1158       for (pi = prim->begin(); pi != prim->end(); ++pi) {
  1159         vertices.push_back(*pi);
  1162       typedef epvector<EggAttributes> Attributes;
  1163       Attributes attributes;
  1165       if (prim->
is_of_type(EggCompositePrimitive::get_class_type())) {
  1171         for (i = 0; i < num_components; i++) {
  1181       bool found_pool = 
false;
  1183       int best_new_vertices = 0;
  1185       Vertices new_vertices;
  1186       EggVertexPools::iterator vpi;
  1187       for (vpi = vertex_pools.begin();
  1188            vpi != vertex_pools.end() && !found_pool;
  1191         int num_new_vertices = 0;
  1193         new_vertices.clear();
  1194         new_vertices.reserve(vertices.size());
  1196         Vertices::const_iterator vi;
  1197         for (vi = vertices.begin();
  1198              vi != vertices.end() && !found_pool;
  1202           new_vertices.push_back(new_vertex);
  1203           if (new_vertex == 
nullptr) {
  1208         if (num_new_vertices == 0) {
  1213         } 
else if (vertex_pool->
size() + num_new_vertices <= max_vertices) {
  1217           if (best_pool == 
nullptr ||
  1218               num_new_vertices < best_new_vertices) {
  1220             best_pool = vertex_pool;
  1221             best_new_vertices = num_new_vertices;
  1227         if (best_pool == 
nullptr) {
  1231           vertex_pools.push_back(best_pool);
  1234         new_vertices.clear();
  1235         new_vertices.reserve(vertices.size());
  1237         Vertices::const_iterator vi;
  1238         for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
  1242           new_vertices.push_back(new_vertex);
  1246       Vertices::const_iterator vi;
  1247       nassertv(new_vertices.size() == vertices.size());
  1248       for (vi = new_vertices.begin(); vi != new_vertices.end(); ++vi) {
  1250         nassertv(new_vertex != 
nullptr);
  1254       if (prim->
is_of_type(EggCompositePrimitive::get_class_type())) {
  1259         nassertv(num_components == (
int)attributes.size());
  1260         for (i = 0; i < num_components; i++) {
  1265     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1267         DCAST(
EggGroupNode, child)->rebuild_vertex_pools(vertex_pools, max_vertices, recurse);
  1283 update_under(
int depth_offset) {
  1284   EggNode::update_under(depth_offset);
  1286   Children::iterator ci;
  1287   for (ci = _children.begin();
  1288        ci != _children.end();
  1290     nassertv((*ci)->get_parent() == 
this);
  1291     (*ci)->update_under(depth_offset);
  1305 r_transform(
const LMatrix4d &mat, 
const LMatrix4d &inv,
  1306             CoordinateSystem to_cs) {
  1307   Children::iterator ci;
  1308   for (ci = _children.begin();
  1309        ci != _children.end();
  1311     (*ci)->r_transform(mat, inv, to_cs);
  1322 r_transform_vertices(
const LMatrix4d &mat) {
  1323   Children::iterator ci;
  1324   for (ci = _children.begin();
  1325        ci != _children.end();
  1327     (*ci)->r_transform_vertices(mat);
  1338 r_mark_coordsys(CoordinateSystem cs) {
  1339   Children::iterator ci;
  1340   for (ci = _children.begin();
  1341        ci != _children.end();
  1343     (*ci)->r_mark_coordsys(cs);
  1351 r_flatten_transforms() {
  1352   Children::iterator ci;
  1353   for (ci = _children.begin();
  1354        ci != _children.end();
  1356     (*ci)->r_flatten_transforms();
  1365   Children::iterator ci;
  1366   for (ci = _children.begin();
  1367        ci != _children.end();
  1369     (*ci)->r_apply_texmats(textures);
  1378 CoordinateSystem EggGroupNode::
  1379 find_coordsys_entry() {
  1380   CoordinateSystem coordsys = CS_default;
  1386   Children::iterator ci, cnext;
  1387   ci = _children.begin();
  1388   while (ci != _children.end()) {
  1393     if (child->
is_of_type(EggCoordinateSystem::get_class_type())) {
  1394       CoordinateSystem new_cs =
  1398       prepare_remove_child(child);
  1399       _children.erase(ci);
  1401       if (new_cs != CS_default) {
  1402         if (coordsys != CS_default && coordsys != new_cs) {
  1403           coordsys = CS_invalid;
  1409     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1410       CoordinateSystem new_cs =
  1412       if (new_cs != CS_default) {
  1413         if (coordsys != CS_default && coordsys != new_cs) {
  1414           coordsys = CS_invalid;
  1440   Children::iterator ci, cnext;
  1441   ci = _children.begin();
  1442   while (ci != _children.end()) {
  1447     if (child->
is_of_type(EggTexture::get_class_type())) {
  1448       PT_EggTexture tex = DCAST(
EggTexture, child);
  1451       prepare_remove_child(tex);
  1452       _children.erase(ci);
  1458     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1482   Children::iterator ci, cnext;
  1483   ci = _children.begin();
  1484   while (ci != _children.end()) {
  1489     if (child->
is_of_type(EggMaterial::get_class_type())) {
  1493       prepare_remove_child(tex);
  1494       _children.erase(ci);
  1500     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1502         DCAST(
EggGroupNode, child)->find_materials(collection);
  1518 r_load_externals(
const DSearchPath &searchpath, CoordinateSystem coordsys,
  1520   bool success = 
true;
  1522   Children::iterator ci;
  1523   for (ci = _children.begin();
  1524        ci != _children.end();
  1527     if (child->
is_of_type(EggExternalReference::get_class_type())) {
  1539           << 
"Could not locate " << filename << 
" in "  1540           << searchpath << 
"\n";
  1547         if (ext_data.
read(filename)) {
  1550           if (record != 
nullptr) {
  1561     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1564         group_child->r_load_externals(searchpath, coordsys, record)
  1581 prepare_add_child(
EggNode *node) {
  1582   nassertv(node != 
nullptr);
  1586   nassertv(node->get_parent() == 
nullptr);
  1588   node->_parent = 
this;
  1603 prepare_remove_child(
EggNode *node) {
  1604   nassertv(node != 
nullptr);
  1606   nassertv(node->get_parent() == 
this);
  1608   node->_parent = 
nullptr;
  1622                          double threshold, CoordinateSystem cs) {
  1627   Children::iterator ci, cnext;
  1628   ci = _children.begin();
  1629   while (ci != _children.end()) {
  1634     if (child->
is_of_type(EggPolygon::get_class_type())) {
  1636       polygon->clear_normal();
  1638       NVertexReference 
ref;
  1639       ref._polygon = polygon;
  1643         prepare_remove_child(child);
  1644         _children.erase(ci);
  1648         size_t num_vertices = polygon->size();
  1649         for (
size_t i = 0; i < num_vertices; i++) {
  1656     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1664         group->r_collect_vertex_normals(collection, threshold, cs);
  1678 do_compute_vertex_normals(
const NVertexGroup &group) {
  1679   nassertv(!group.empty());
  1683   LNormald normal(0.0, 0.0, 0.0);
  1684   NVertexGroup::const_iterator gi;
  1685   for (gi = group.begin(); gi != group.end(); ++gi) {
  1686     const NVertexReference &
ref = (*gi);
  1687     normal += 
ref._normal;
  1690   normal /= (double)group.size();
  1695   for (gi = group.begin(); gi != group.end(); ++gi) {
  1696     const NVertexReference &
ref = (*gi);
  1701     new_vertex.set_normal(normal);
  1705     ref._polygon->set_vertex(
ref._vertex, unique);
  1715 r_collect_tangent_binormal(
const GlobPattern &uv_name,
  1717   Children::iterator ci;
  1718   for (ci = _children.begin(); ci != _children.end(); ++ci) {
  1721     if (child->
is_of_type(EggPolygon::get_class_type())) {
  1724       TBNVertexReference 
ref;
  1725       ref._polygon = polygon;
  1728       size_t num_vertices = polygon->size();
  1729       for (
size_t i = 0; i < num_vertices; i++) {
  1737         if (v1->has_normal() || polygon->has_normal()) {
  1743             string name = uv_obj->get_name();
  1746               TBNVertexValue value;
  1747               value._uv_name = name;
  1749               if (v1->has_normal()) {
  1750                 value._normal = v1->get_normal();
  1752                 value._normal = polygon->get_normal();
  1754               value._uv = v1->
get_uv(name);
  1761               LTexCoordd w1 = v1->
get_uv(name);
  1762               LTexCoordd w2 = v2->
get_uv(name);
  1763               LTexCoordd w3 = v3->
get_uv(name);
  1771               value._facing = 
is_right(w1 - w2, w3 - w1);
  1773               double x1 = p2[0] - p1[0];
  1774               double x2 = p3[0] - p1[0];
  1775               double y1 = p2[1] - p1[1];
  1776               double y2 = p3[1] - p1[1];
  1777               double z1 = p2[2] - p1[2];
  1778               double z2 = p3[2] - p1[2];
  1780               double s1 = w2[0] - w1[0];
  1781               double s2 = w3[0] - w1[0];
  1782               double t1 = w2[1] - w1[1];
  1783               double t2 = w3[1] - w1[1];
  1785               double denom = (s1 * t2 - s2 * t1);
  1787                 ref._sdir.set(0.0, 0.0, 0.0);
  1788                 ref._tdir.set(0.0, 0.0, 0.0);
  1790                 double r = 1.0 / denom;
  1791                 ref._sdir.set((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
  1792                               (t2 * z1 - t1 * z2) * r);
  1793                 ref._tdir.set((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
  1794                               (s1 * z2 - s2 * z1) * r);
  1799               collection[value].push_back(
ref);
  1805     } 
else if (child->
is_of_type(EggGroupNode::get_class_type())) {
  1813         group->r_collect_tangent_binormal(uv_name, collection);
  1825 do_compute_tangent_binormal(
const TBNVertexValue &value,
  1826                             const TBNVertexGroup &group) {
  1827   nassertv(!group.empty());
  1831   LNormald sdir(0.0, 0.0, 0.0);
  1832   LNormald tdir(0.0, 0.0, 0.0);
  1834   TBNVertexGroup::const_iterator gi;
  1835   for (gi = group.begin(); gi != group.end(); ++gi) {
  1836     const TBNVertexReference &
ref = (*gi);
  1845   if (!sdir.normalize()) {
  1846     sdir.set(1.0, 0.0, 0.0);
  1848   if (!tdir.normalize()) {
  1849     tdir = sdir.cross(LNormald(0.0, 0.0, -1.0));
  1852   LNormald tangent = (sdir - value._normal * value._normal.dot(sdir));
  1853   tangent.normalize();
  1855   LNormald binormal = cross(value._normal, tangent);
  1856   if (dot(binormal, tdir) < 0.0f) {
  1857     binormal = -binormal;
  1860   binormal.normalize();
  1865   for (gi = group.begin(); gi != group.end(); ++gi) {
  1866     const TBNVertexReference &
ref = (*gi);
  1871     EggVertexUV *uv_obj = new_vertex.modify_uv_obj(value._uv_name);
  1872     nassertv(uv_obj != 
nullptr);
  1873     uv_obj->set_tangent(tangent);
  1874     uv_obj->set_binormal(binormal);
  1879     ref._polygon->set_vertex(
ref._vertex, unique);
 bool empty() const
Returns true if the pool is empty.
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
The set of UV's that may or may not be assigned to a vertex.
void strip_normals()
Removes all normals from primitives, and the vertices they reference, at this node and below.
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
void make_point_primitives()
Creates PointLight primitives to reference any otherwise unreferences vertices discovered in this gro...
virtual void unify_attributes(Shading shading)
If the shading property is S_per_vertex, ensures that all vertices have a normal and a color,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static bool resolve_egg_filename(Filename &egg_filename, const DSearchPath &searchpath=DSearchPath())
Looks for the indicated filename, first along the indicated searchpath, and then along the model_path...
This is an iterator adaptor that converts any iterator that returns a pair (e.g.
PT(EggNode) EggGroupNode
Removes the indicated child node from the group and returns it.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL map.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The base class for primitives such as triangle strips and triangle fans, which include several compon...
get_depth
Returns the number of nodes above this node in the egg hierarchy.
get_uv_name
Returns the texcoord name that has been specified for this texture, or the empty string if no texcoor...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool joint_has_primitives() const
Returns true if there are any primitives (e.g.
virtual void apply_first_attribute()
Sets the first vertex of the triangle (or each component) to the primitive normal and/or color,...
The <CoordinateSystem> entry at the top of an egg file.
This is an egg node that contains a filename.
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
virtual void apply_last_attribute()
Sets the last vertex of the triangle (or each component) to the primitive normal and/or color,...
virtual bool cleanup()
Cleans up modeling errors in whatever context this makes sense.
void unify_attributes(bool use_connected_shading, bool allow_per_primitive, bool recurse)
Applies per-vertex normal and color to all vertices, if they are in fact per-vertex (and different fo...
A base class for nodes in the hierarchy that are not leaf nodes.
This is a collection of materials by MRef name.
A hierarchy of directories and files that appears to be one continuous file system,...
int triangulate_polygons(int flags)
Replace all higher-order polygons at this point in the scene graph and below with triangles.
void get_connected_shading()
Queries the connected_shading information on all primitives at this node and below,...
void clear()
Removes all of the vertices from the primitive.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_component
Returns the attributes for the nth component triangle.
has_alpha_filename
Returns true if a separate file for the alpha component has been applied, false otherwise.
LTexCoordd get_uv() const
Returns the unnamed UV coordinate pair on the vertex.
Defines a texture map that may be applied to geometry.
void clear_connected_shading()
Resets the connected_shading information on all primitives at this node and below,...
std::string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
void recompute_polygon_normals(CoordinateSystem cs=CS_default)
Recomputes all the polygon normals for polygon geometry at this group node and below so that they acc...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool recompute_tangent_binormal_auto()
This function recomputes the tangent and binormal for any texture coordinate set that affects a norma...
set_auto_resolve_externals
Indicates whether the EggData object will automatically resolve any external references when read() i...
bool add_material(EggMaterial *material)
Explicitly adds a new material to the collection.
get_shading
Returns the shading properties apparent on this particular primitive.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
This is a collection of textures by TRef name.
virtual std::string get_default_extension() const
Returns the default extension for this filename type.
void apply_first_attribute(bool recurse)
Sets the first vertex of the triangle (or each component) to the primitive normal and/or color,...
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const std::string &default_extension=std::string()) const
Searches the given search path for the filename.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
bool add_texture(EggTexture *texture)
Explicitly adds a new texture to the collection.
This is the primary interface into all the egg data, and the root of the egg file structure.
size_type size() const
Returns the number of vertices in the pool.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_vertex
Returns a particular index based on its index number.
A single point, or a collection of points as defined by a single <PointLight> entry.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool matches(const std::string &candidate) const
Returns true if the candidate string matches the pattern, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool read(Filename filename, std::string display_name=std::string())
Opens the indicated filename and reads the egg data contents from it.
get_connected_shading
Determines what sort of shading properties this primitive's connected neighbors have.
This is our own Panda specialization on the default STL vector.
static bool is_right(const LVector2d &v1, const LVector2d &v2)
Returns true if the 2-d v1 is to the right of v2.
void mesh(EggGroupNode *group, bool flat_shaded)
Accepts an EggGroupNode, which contains a set of EggPrimitives–typically, triangles and quads–as chil...
set_vertex
Replaces a particular vertex based on its index number in the list of vertices.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
virtual void write(std::ostream &out, int indent_level) const
Writes the group and all of its children to the indicated output stream in Egg format.
virtual void reverse_vertex_ordering()
Reverses the ordering of the vertices in this primitive, if appropriate, in order to change the direc...
virtual void post_apply_flat_attribute()
Intended as a followup to apply_last_attribute(), this also sets an attribute on the first vertices o...
Collects together unrelated EggPrimitives, determines their edge connectivity, and generates a set of...
The name of a file, such as a texture file or an Egg file.
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool has_primitives() const
Returns true if there are any primitives (e.g.
int rename_nodes(vector_string strip_prefix, bool recurse)
Rename by stripping out the prefix.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int remove_invalid_primitives(bool recurse)
Removes primitives at this level and below which appear to be degenerate; e.g.
bool load_externals(const DSearchPath &searchpath=DSearchPath())
Loads up all the egg files referenced by <File> entries within the egg structure, and inserts their c...
int remove_unused_vertices()
Removes all vertices from the pool that are not referenced by at least one primitive.
void steal_children(EggGroupNode &other)
Moves all the children from the other node to this one.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
void mesh_triangles(int flags)
Combine triangles together into triangle strips, at this group and below.
int remove_unused_vertices(bool recurse)
Removes all vertices from VertexPools within this group or below that are not referenced by at least ...
void add_unused_vertices_to_prim(EggPrimitive *prim)
Adds all of the unused vertices in this vertex pool to the indicated primitive, in ascending order.
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
void apply_last_attribute(bool recurse)
Sets the last vertex of the triangle (or each component) to the primitive normal and/or color,...
EggNode * get_next_child()
Returns the next child in the group's list of children since the last call to get_first_child() or ge...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool is_joint() const
Returns true if this particular node represents a <Joint> entry or not.
int find_used_textures(EggNode *node)
Walks the egg hierarchy beginning at the indicated node, looking for textures that are referenced by ...
virtual bool has_normals() const
Returns true if any of the primitives (e.g.
bool is_local() const
Returns true if the filename is local, e.g.
void ref() const
Explicitly increments the reference count.
void rebuild_vertex_pools(EggVertexPools &vertex_pools, unsigned int max_vertices, bool recurse)
Copies vertices used by the primitives at this group node (and below, if recurse is true) into one or...
bool recompute_polygon_normal(CoordinateSystem cs=CS_default)
Recalculates the normal according to the order of the vertices, and sets it.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_alpha_filename
Returns the separate file assigned for the alpha channel.
EggVertex * find_matching_vertex(const EggVertex ©)
If the EggVertexPool already has a vertex matching the indicated vertex, returns it; otherwise,...
bool is_under_instance() const
Returns true if there is an <Instance> node somewhere in the egg tree at or above this node,...
void replace(iterator position, PT(EggNode) x)
Replaces the node at the indicated position with the indicated node.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
int rename_node(vector_string strip_prefix)
Rename by stripping out the prefix.
set_coordinate_system
Changes the coordinate system of the EggData.
void force_filenames(const Filename &directory)
Similar to resolve_filenames, but each non-absolute filename encountered is arbitrarily taken to be i...
const_uv_iterator uv_begin() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A base class for things that may be directly added into the egg hierarchy.
set_alpha_filename
Specifies a separate file that will be loaded in with the 1- or 3-component texture and applied as th...
bool calculate_normal(LNormald &result, CoordinateSystem cs=CS_default) const
Calculates the true polygon normal–the vector pointing out of the front of the polygon–based on the v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggNode * get_first_child()
Returns the first child in the group's list of children, or NULL if the list of children is empty.
Defines a reference to another egg file which should be inserted at this point.
This class stores a list of directories that can be searched, in order, to locate a particular file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
void add_dependent_file(const Filename &pathname)
Adds the indicated file to the list of files that will be loaded to generate the data in this record.
void copy_grefs_from(const EggVertex &other)
Copies all the group references from the other vertex onto this one.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
bool has_absolute_pathnames() const
Returns true if any nodes at this level and below include a reference to a file via an absolute pathn...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void post_apply_flat_attribute(bool recurse)
Intended as a followup to apply_last_attribute(), this also sets an attribute on the first vertices o...
set_component
Changes the attributes for the nth component triangle.
void resolve_filenames(const DSearchPath &searchpath)
Walks the tree and attempts to resolve any filenames encountered.
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
A collection of vertices.
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive's list of vertices, and returns it.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EggNode * find_child(const std::string &name) const
Returns the child of this node whose name is the indicated string, or NULL if there is no child of th...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void recompute_vertex_normals(double threshold, CoordinateSystem cs=CS_default)
Recomputes all the vertex normals for polygon geometry at this group node and below so that they accu...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void reverse_vertex_ordering()
Reverses the vertex ordering of all polygons defined at this node and below.
void clear_connected_shading()
Resets the connected_shading member in this primitive, so that get_connected_shading() will recompute...
const_uv_iterator uv_end() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex.
This class can be used to test for string matches against standard Unix- shell filename globbing conv...
get_num_components
Returns the number of individual component triangles within the composite.
bool recompute_tangent_binormal(const GlobPattern &uv_name)
This function recomputes the tangent and binormal for the named texture coordinate set for all vertic...