111   LODInstance(
EggNode *egg_node);
   112   bool operator < (
const LODInstance &other)
 const {
   113     return _d->_switch_in < other._d->_switch_in;
   121 LODInstance(
EggNode *egg_node) {
   122   nassertv(egg_node != 
nullptr);
   123   _egg_node = egg_node;
   128   nassertv(egg_group->has_lod());
   145   _dynamic_override = 
false;
   146   _dynamic_override_char_maker = 
nullptr;
   157   _dynamic_override = 
false;
   158   _dynamic_override_char_maker = 
nullptr;
   167   _deferred_nodes.clear();
   171   if (!expand_all_object_types(_data)) {
   179   _data->clear_connected_shading();
   180   _data->remove_unused_vertices(
true);
   181   _data->get_connected_shading();
   182   _data->unify_attributes(
true, egg_flat_shading, 
true);
   187   _data->clear_connected_shading();
   188   _data->remove_unused_vertices(
true);
   189   _data->get_connected_shading();
   194   separate_switches(_data);
   196   if (egg_emulate_bface) {
   197     emulate_bface(_data);
   201   _data->remove_invalid_primitives(
true);
   203   binner.make_bins(_data);
   208   _root = 
new ModelRoot(_data->get_egg_filename(), _data->get_egg_timestamp());
   210   EggGroupNode::const_iterator ci;
   211   for (ci = _data->begin(); ci != _data->end(); ++ci) {
   212     make_node(*ci, _root);
   228   ExtraNodes::const_iterator di;
   229   for (di = _decals.begin(); di != _decals.end(); ++di) {
   231     nassertv(node != 
nullptr);
   239     for (
int i = 0; i < num_children; i++) {
   246             << 
"Decal onto " << parent.
node()->get_name()
   247             << 
" uses base geometry with multiple GeomNodes.\n";
   257         << 
"Ignoring decal onto " << parent.
node()->get_name()
   258         << 
"; no geometry within group.\n";
   264       while (i < num_children) {
   288   ExtraNodes::const_iterator ni;
   289   for (ni = _sequences.begin(); ni != _sequences.end(); ++ni) {
   304   if (egg_bin->empty()) {
   311   EggGroupNode::const_iterator ci = egg_bin->begin();
   312   nassertv(ci != egg_bin->end());
   314   nassertv(first_prim != 
nullptr);
   316   DCAST_INTO_V(render_state, first_prim->get_user_data(EggRenderState::get_class_type()));
   318   if (render_state->_hidden && egg_suppress_hidden) {
   332     egg_bin->
mesh_triangles(render_state->_flat_shaded ? EggGroupNode::T_flat_shaded : 0);
   352   EggVertexPools::iterator vpi;
   353   for (vpi = vertex_pools.begin(); vpi != vertex_pools.end(); ++vpi) {
   358     bool has_overall_color;
   359     LColor overall_color;
   361     if (!egg_flat_colors) {
   365       has_overall_color = 
false;
   372       blend_table = make_blend_table(vertex_pool, egg_bin, character_maker);
   386     for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
   388       DCAST_INTO_V(egg_prim, (*ci));
   389       if (egg_prim->
get_pool() == vertex_pool) {
   390         make_primitive(render_state, egg_prim, unique_primitives, primitives,
   391                        has_overall_color, overall_color);
   395     if (!primitives.empty()) {
   397       if (transform != 
nullptr) {
   405         make_vertex_data(render_state, vertex_pool, egg_bin, mat, blend_table,
   406                          is_dynamic, character_maker, has_overall_color);
   407       nassertv(vertex_data != 
nullptr);
   410       PT(
Geom) geom = 
new Geom(vertex_data);
   413       Primitives::const_iterator pi;
   414       for (pi = primitives.begin(); pi != primitives.end(); ++pi) {
   417         if (primitive->is_indexed()) {
   420           primitive->reserve_num_vertices(primitive->get_num_vertices());
   423         geom->add_primitive(primitive);
   430       if (geom_node == 
nullptr) {
   435           geom_node = DCAST(
GeomNode, parent);
   438           geom_node = 
new GeomNode(egg_bin->get_name());
   439           if (render_state->_hidden) {
   442             parent->add_child(geom_node);
   447       CPT(
RenderState) geom_state = render_state->_state;
   448       if (has_overall_color) {
   449         if (!overall_color.almost_equal(LColor(1.0f, 1.0f, 1.0f, 1.0f))) {
   450           geom_state = geom_state->
add_attrib(ColorAttrib::make_flat(overall_color), -1);
   453         geom_state = geom_state->add_attrib(ColorAttrib::make_vertex(), -1);
   456       geom_node->add_geom(geom, geom_state);
   460   if (geom_node != 
nullptr && egg_show_normals) {
   462     for (vpi = vertex_pools.begin(); vpi != vertex_pools.end(); ++vpi) {
   464       show_normals(vertex_pool, geom_node);
   480   for (
int i = 0; i < num_components; i++) {
   482     case EggTransform::CT_translate2d:
   485         LVecBase3 trans3d(trans2d[0], trans2d[1], 0.0f);
   486         ts = TransformState::make_pos(trans3d)->compose(ts);
   490     case EggTransform::CT_translate3d:
   493         ts = TransformState::make_pos(trans3d)->compose(ts);
   497     case EggTransform::CT_rotate2d:
   499         LRotation rot(LVector3(0.0f, 0.0f, 1.0f),
   501         ts = TransformState::make_quat(rot)->compose(ts);
   505     case EggTransform::CT_rotx:
   507         LRotation rot(LVector3(1.0f, 0.0f, 0.0f),
   509         ts = TransformState::make_quat(rot)->compose(ts);
   513     case EggTransform::CT_roty:
   515         LRotation rot(LVector3(0.0f, 1.0f, 0.0f),
   517         ts = TransformState::make_quat(rot)->compose(ts);
   521     case EggTransform::CT_rotz:
   523         LRotation rot(LVector3(0.0f, 0.0f, 1.0f),
   525         ts = TransformState::make_quat(rot)->compose(ts);
   529     case EggTransform::CT_rotate3d:
   533         ts = TransformState::make_quat(rot)->compose(ts);
   537     case EggTransform::CT_scale2d:
   540         LVecBase3 scale3d(scale2d[0], scale2d[1], 1.0f);
   541         ts = TransformState::make_scale(scale3d)->compose(ts);
   545     case EggTransform::CT_scale3d:
   548         ts = TransformState::make_scale(scale3d)->compose(ts);
   552     case EggTransform::CT_uniform_scale:
   555         ts = TransformState::make_scale(scale)->compose(ts);
   559     case EggTransform::CT_matrix3:
   562         LMatrix4 mat4(m(0, 0), m(0, 1), 0.0, m(0, 2),
   563                        m(1, 0), m(1, 1), 0.0, m(1, 2),
   565                        m(2, 0), m(2, 1), 0.0, m(2, 2));
   567         ts = TransformState::make_mat(mat4)->compose(ts);
   571     case EggTransform::CT_matrix4:
   574         ts = TransformState::make_mat(mat4)->compose(ts);
   578     case EggTransform::CT_invalid:
   584   if (ts->components_given()) {
   593   TransformStates::iterator tsi = _transform_states.insert(TransformStates::value_type(ts->get_mat(), ts)).first;
   595   return (*tsi).second;
   607     new GeomVertexData(vertex_pool->get_name(), format, Geom::UH_static);
   613   for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
   617     if (vert->has_normal()) {
   618       vertex.add_data3d(pos);
   619       vertex.add_data3d(pos + vert->get_normal() * egg_normal_scale);
   620       color.add_data4(1.0f, 0.0f, 0.0f, 1.0f);
   621       color.add_data4(1.0f, 0.0f, 0.0f, 1.0f);
   622       primitive->add_next_vertices(2);
   623       primitive->close_primitive();
   630       if (uv_obj->has_tangent()) {
   631         vertex.add_data3d(pos);
   632         vertex.add_data3d(pos + uv_obj->get_tangent() * egg_normal_scale);
   633         color.add_data4(0.0f, 1.0f, 0.0f, 1.0f);
   634         color.add_data4(0.0f, 1.0f, 0.0f, 1.0f);
   635         primitive->add_next_vertices(2);
   636         primitive->close_primitive();
   638       if (uv_obj->has_binormal()) {
   639         vertex.add_data3d(pos);
   640         vertex.add_data3d(pos + uv_obj->get_binormal() * egg_normal_scale);
   641         color.add_data4(0.0f, 0.0f, 1.0f, 1.0f);
   642         color.add_data4(0.0f, 0.0f, 1.0f, 1.0f);
   643         primitive->add_next_vertices(2);
   644         primitive->close_primitive();
   649   PT(
Geom) geom = 
new Geom(vertex_data);
   650   geom->add_primitive(primitive);
   659                  const LMatrix4d &mat) {
   660   if (egg_load_old_curves) {
   662     make_old_nurbs_curve(egg_curve, parent, mat);
   666   assert(parent != 
nullptr);
   670   if (nurbs == 
nullptr) {
   699     int subdiv_per_segment =
   700       (int)((egg_curve->
get_subdiv() + 0.5) / nurbs->get_num_segments());
   701     rope->set_num_subdiv(max(subdiv_per_segment, 1));
   705   DCAST_INTO_V(render_state, egg_curve->
get_user_data(EggRenderState::get_class_type()));
   706   if (render_state->_hidden && egg_suppress_hidden) {
   711   rope->set_state(render_state->_state);
   712   rope->set_uv_mode(RopeNode::UV_parametric);
   716     rope->set_use_vertex_color(
true);
   717   } 
else if (egg_curve->has_color()) {
   719     rope->set_attrib(ColorAttrib::make_flat(egg_curve->
get_color()));
   722   parent->add_child(rope);
   732                      const LMatrix4d &mat) {
   733   assert(parent != 
nullptr);
   740   nassertv(nurbs != 
nullptr);
   744       << 
"Invalid NURBSCurve order for " << egg_curve->get_name() << 
": "   750   nurbs->set_order(egg_curve->
get_order());
   752   EggPrimitive::const_iterator pi;
   753   for (pi = egg_curve->begin(); pi != egg_curve->end(); ++pi) {
   754     nurbs->append_cv(LCAST(PN_stdfloat, (*pi)->get_pos4() * mat));
   758   if (num_knots != nurbs->get_num_knots()) {
   760       << 
"Invalid NURBSCurve number of knots for "   761       << egg_curve->get_name() << 
": got " << num_knots
   762       << 
" knots, expected " << nurbs->get_num_knots() << 
"\n";
   767   for (
int i = 0; i < num_knots; i++) {
   768     nurbs->set_knot(i, egg_curve->
get_knot(i));
   772   case EggCurve::CT_xyz:
   773     curve->set_curve_type(PCT_XYZ);
   776   case EggCurve::CT_hpr:
   777     curve->set_curve_type(PCT_HPR);
   781     curve->set_curve_type(PCT_T);
   787   curve->set_name(egg_curve->get_name());
   789   if (!curve->recompute()) {
   791       << 
"Invalid NURBSCurve " << egg_curve->get_name() << 
"\n";
   796   parent->add_child(curve);
   804                    const LMatrix4d &mat) {
   805   assert(parent != 
nullptr);
   809   if (nurbs == 
nullptr) {
   819     int u_subdiv_per_segment =
   820       (int)((egg_surface->
get_u_subdiv() + 0.5) / nurbs->get_num_u_segments());
   821     sheet->set_num_u_subdiv(max(u_subdiv_per_segment, 1));
   824     int v_subdiv_per_segment =
   825       (int)((egg_surface->
get_v_subdiv() + 0.5) / nurbs->get_num_v_segments());
   826     sheet->set_num_v_subdiv(max(v_subdiv_per_segment, 1));
   830   DCAST_INTO_V(render_state, egg_surface->
get_user_data(EggRenderState::get_class_type()));
   831   if (render_state->_hidden && egg_suppress_hidden) {
   836   sheet->set_state(render_state->_state);
   840     sheet->set_use_vertex_color(
true);
   841   } 
else if (egg_surface->has_color()) {
   843     sheet->set_attrib(ColorAttrib::make_flat(egg_surface->
get_color()));
   846   parent->add_child(sheet);
   858   EggTextureCollection::iterator ti;
   859   for (ti = tc.begin(); ti != tc.end(); ++ti) {
   860     PT_EggTexture egg_tex = (*ti);
   863     if (load_texture(def, egg_tex)) {
   866       _textures[egg_tex] = def;
   876 load_texture(TextureDef &def, 
EggTexture *egg_tex) {
   878   int wanted_channels = 0;
   879   bool wanted_alpha = 
false;
   880   switch (egg_tex->get_format()) {
   881   case EggTexture::F_red:
   882   case EggTexture::F_green:
   883   case EggTexture::F_blue:
   884   case EggTexture::F_alpha:
   885   case EggTexture::F_luminance:
   887     wanted_alpha = 
false;
   890   case EggTexture::F_luminance_alpha:
   891   case EggTexture::F_luminance_alphamask:
   896   case EggTexture::F_rgb:
   897   case EggTexture::F_rgb12:
   898   case EggTexture::F_rgb8:
   899   case EggTexture::F_rgb5:
   900   case EggTexture::F_rgb332:
   902     wanted_alpha = 
false;
   905   case EggTexture::F_rgba:
   906   case EggTexture::F_rgbm:
   907   case EggTexture::F_rgba12:
   908   case EggTexture::F_rgba8:
   909   case EggTexture::F_rgba4:
   910   case EggTexture::F_rgba5:
   915   case EggTexture::F_unspecified:
   922   if (_record != 
nullptr) {
   931   if (egg_preload_simple_textures) {
   932     options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_preload_simple);
   935   if (!egg_ignore_filters && !egg_ignore_mipmaps) {
   936     switch (egg_tex->get_minfilter()) {
   937     case EggTexture::FT_nearest:
   938     case EggTexture::FT_linear:
   939     case EggTexture::FT_unspecified:
   942     case EggTexture::FT_nearest_mipmap_nearest:
   943     case EggTexture::FT_linear_mipmap_nearest:
   944     case EggTexture::FT_nearest_mipmap_linear:
   945     case EggTexture::FT_linear_mipmap_linear:
   946       options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_generate_mipmaps);
   951     options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_multiview);
   958   if (egg_tex->get_compression_mode() == EggTexture::CM_on) {
   959     options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_compression);
   963   switch (egg_tex->get_texture_type()) {
   964   case EggTexture::TT_unspecified:
   965   case EggTexture::TT_1d_texture:
   966     options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_1d);
   969   case EggTexture::TT_2d_texture:
   983   case EggTexture::TT_3d_texture:
   988   case EggTexture::TT_cube_map:
   994   if (tex == 
nullptr) {
  1009   if (aux != 
nullptr &&
  1010       aux->
is_of_type(EggTexture::get_class_type())) {
  1013     if (aux_egg_tex->
get_alpha_mode() != EggTexture::AM_unspecified) {
  1016     if (aux_egg_tex->get_format() != EggTexture::F_unspecified) {
  1017       egg_tex->set_format(aux_egg_tex->get_format());
  1019     if (aux_egg_tex->get_minfilter() != EggTexture::FT_unspecified) {
  1020       egg_tex->set_minfilter(aux_egg_tex->get_minfilter());
  1022     if (aux_egg_tex->get_magfilter() != EggTexture::FT_unspecified) {
  1023       egg_tex->set_magfilter(aux_egg_tex->get_magfilter());
  1030   apply_texture_attributes(tex, egg_tex);
  1034   def._texture = DCAST(
TextureAttrib, TextureAttrib::make())->add_on_stage(stage, tex);
  1036   def._egg_tex = egg_tex;
  1047   if (egg_tex->get_compression_mode() != EggTexture::CM_default) {
  1048     tex->
set_compression(convert_compression_mode(egg_tex->get_compression_mode()));
  1057   if (wrap_u != EggTexture::WM_unspecified) {
  1058     sampler.
set_wrap_u(convert_wrap_mode(wrap_u));
  1060   if (wrap_v != EggTexture::WM_unspecified) {
  1061     sampler.
set_wrap_v(convert_wrap_mode(wrap_v));
  1063   if (wrap_w != EggTexture::WM_unspecified) {
  1064     sampler.
set_wrap_w(convert_wrap_mode(wrap_w));
  1071   switch (egg_tex->get_minfilter()) {
  1072   case EggTexture::FT_nearest:
  1076   case EggTexture::FT_linear:
  1077     if (egg_ignore_filters) {
  1078       egg2pg_cat.warning()
  1079         << 
"Ignoring minfilter request\n";
  1086   case EggTexture::FT_nearest_mipmap_nearest:
  1087     if (egg_ignore_filters) {
  1088       egg2pg_cat.warning()
  1089         << 
"Ignoring minfilter request\n";
  1091     } 
else if (egg_ignore_mipmaps) {
  1092       egg2pg_cat.warning()
  1093         << 
"Ignoring mipmap request\n";
  1096       sampler.
set_minfilter(SamplerState::FT_nearest_mipmap_nearest);
  1100   case EggTexture::FT_linear_mipmap_nearest:
  1101     if (egg_ignore_filters) {
  1102       egg2pg_cat.warning()
  1103         << 
"Ignoring minfilter request\n";
  1105     } 
else if (egg_ignore_mipmaps) {
  1106       egg2pg_cat.warning()
  1107         << 
"Ignoring mipmap request\n";
  1110       sampler.
set_minfilter(SamplerState::FT_linear_mipmap_nearest);
  1114   case EggTexture::FT_nearest_mipmap_linear:
  1115     if (egg_ignore_filters) {
  1116       egg2pg_cat.warning()
  1117         << 
"Ignoring minfilter request\n";
  1119     } 
else if (egg_ignore_mipmaps) {
  1120       egg2pg_cat.warning()
  1121         << 
"Ignoring mipmap request\n";
  1124       sampler.
set_minfilter(SamplerState::FT_nearest_mipmap_linear);
  1128   case EggTexture::FT_linear_mipmap_linear:
  1129     if (egg_ignore_filters) {
  1130       egg2pg_cat.warning()
  1131         << 
"Ignoring minfilter request\n";
  1133     } 
else if (egg_ignore_mipmaps) {
  1134       egg2pg_cat.warning()
  1135         << 
"Ignoring mipmap request\n";
  1138       sampler.
set_minfilter(SamplerState::FT_linear_mipmap_linear);
  1142   case EggTexture::FT_unspecified:
  1146   switch (egg_tex->get_magfilter()) {
  1147   case EggTexture::FT_nearest:
  1148   case EggTexture::FT_nearest_mipmap_nearest:
  1149   case EggTexture::FT_nearest_mipmap_linear:
  1153   case EggTexture::FT_linear:
  1154   case EggTexture::FT_linear_mipmap_nearest:
  1155   case EggTexture::FT_linear_mipmap_linear:
  1156     if (egg_ignore_filters) {
  1157       egg2pg_cat.warning()
  1158         << 
"Ignoring magfilter request\n";
  1165   case EggTexture::FT_unspecified:
  1188     switch (egg_tex->get_format()) {
  1189     case EggTexture::F_red:
  1192     case EggTexture::F_green:
  1195     case EggTexture::F_blue:
  1198     case EggTexture::F_alpha:
  1201     case EggTexture::F_luminance:
  1205     case EggTexture::F_unspecified:
  1209       egg2pg_cat.warning()
  1210         << 
"Ignoring inappropriate format " << egg_tex->get_format()
  1211         << 
" for 1-component texture " << egg_tex->get_name() << 
"\n";
  1215     switch (egg_tex->get_format()) {
  1216     case EggTexture::F_luminance_alpha:
  1220     case EggTexture::F_luminance_alphamask:
  1221       tex->
set_format(Texture::F_luminance_alphamask);
  1224     case EggTexture::F_unspecified:
  1228       egg2pg_cat.warning()
  1229         << 
"Ignoring inappropriate format " << egg_tex->get_format()
  1230         << 
" for 2-component texture " << egg_tex->get_name() << 
"\n";
  1234     switch (egg_tex->get_format()) {
  1235     case EggTexture::F_rgb:
  1238     case EggTexture::F_rgb12:
  1243         egg2pg_cat.warning()
  1244           << 
"Ignoring inappropriate format " << egg_tex->get_format()
  1245           << 
" for 8-bit texture " << egg_tex->get_name() << 
"\n";
  1248     case EggTexture::F_rgb8:
  1249     case EggTexture::F_rgba8:
  1254     case EggTexture::F_rgb5:
  1257     case EggTexture::F_rgb332:
  1261     case EggTexture::F_unspecified:
  1265       egg2pg_cat.warning()
  1266         << 
"Ignoring inappropriate format " << egg_tex->get_format()
  1267         << 
" for 3-component texture " << egg_tex->get_name() << 
"\n";
  1271     switch (egg_tex->get_format()) {
  1272     case EggTexture::F_rgba:
  1275     case EggTexture::F_rgbm:
  1278     case EggTexture::F_rgba12:
  1283         egg2pg_cat.warning()
  1284           << 
"Ignoring inappropriate format " << egg_tex->get_format()
  1285           << 
" for 8-bit texture " << egg_tex->get_name() << 
"\n";
  1288     case EggTexture::F_rgba8:
  1291     case EggTexture::F_rgba4:
  1294     case EggTexture::F_rgba5:
  1298     case EggTexture::F_unspecified:
  1302       egg2pg_cat.warning()
  1303         << 
"Ignoring inappropriate format " << egg_tex->get_format()
  1304         << 
" for 4-component texture " << egg_tex->get_name() << 
"\n";
  1308   switch (egg_tex->get_quality_level()) {
  1309   case EggTexture::QL_unspecified:
  1310   case EggTexture::QL_default:
  1314   case EggTexture::QL_fastest:
  1318   case EggTexture::QL_normal:
  1322   case EggTexture::QL_best:
  1333 Texture::CompressionMode EggLoader::
  1334 convert_compression_mode(EggTexture::CompressionMode compression_mode)
 const {
  1335   switch (compression_mode) {
  1336   case EggTexture::CM_off:
  1337     return Texture::CM_off;
  1339   case EggTexture::CM_on:
  1340     return Texture::CM_on;
  1342   case EggTexture::CM_fxt1:
  1343     return Texture::CM_fxt1;
  1345   case EggTexture::CM_dxt1:
  1346     return Texture::CM_dxt1;
  1348   case EggTexture::CM_dxt2:
  1349     return Texture::CM_dxt2;
  1351   case EggTexture::CM_dxt3:
  1352     return Texture::CM_dxt3;
  1354   case EggTexture::CM_dxt4:
  1355     return Texture::CM_dxt4;
  1357   case EggTexture::CM_dxt5:
  1358     return Texture::CM_dxt5;
  1360   case EggTexture::CM_default:
  1361     return Texture::CM_default;
  1364   egg2pg_cat.warning()
  1365     << 
"Unexpected texture compression flag: " << (int)compression_mode << 
"\n";
  1366   return Texture::CM_default;
  1373 SamplerState::WrapMode EggLoader::
  1374 convert_wrap_mode(EggTexture::WrapMode wrap_mode)
 const {
  1375   switch (wrap_mode) {
  1376   case EggTexture::WM_clamp:
  1377     return SamplerState::WM_clamp;
  1379   case EggTexture::WM_repeat:
  1380     return SamplerState::WM_repeat;
  1382   case EggTexture::WM_mirror:
  1383     return SamplerState::WM_mirror;
  1385   case EggTexture::WM_mirror_once:
  1386     return SamplerState::WM_mirror_once;
  1388   case EggTexture::WM_border_color:
  1389     return SamplerState::WM_border_color;
  1391   case EggTexture::WM_unspecified:
  1392     return SamplerState::WM_repeat;
  1395   egg2pg_cat.warning()
  1396     << 
"Unexpected texture wrap flag: " << (int)wrap_mode << 
"\n";
  1397   return SamplerState::WM_repeat;
  1404 make_texture_stage(
const EggTexture *egg_tex) {
  1411       (egg_tex->get_env_type() == EggTexture::ET_unspecified ||
  1412        egg_tex->get_env_type() == EggTexture::ET_modulate) &&
  1413       egg_tex->get_combine_mode(EggTexture::CC_rgb) == EggTexture::CM_unspecified &&
  1414       egg_tex->get_combine_mode(EggTexture::CC_alpha) == EggTexture::CM_unspecified &&
  1419     return TextureStage::get_default();
  1424   switch (egg_tex->get_env_type()) {
  1425   case EggTexture::ET_modulate:
  1426     stage->set_mode(TextureStage::M_modulate);
  1429   case EggTexture::ET_decal:
  1430     stage->set_mode(TextureStage::M_decal);
  1433   case EggTexture::ET_blend:
  1434     stage->set_mode(TextureStage::M_blend);
  1437   case EggTexture::ET_replace:
  1438     stage->set_mode(TextureStage::M_replace);
  1441   case EggTexture::ET_add:
  1442     stage->set_mode(TextureStage::M_add);
  1445   case EggTexture::ET_blend_color_scale:
  1446     stage->set_mode(TextureStage::M_blend_color_scale);
  1449   case EggTexture::ET_modulate_glow:
  1450     stage->set_mode(TextureStage::M_modulate_glow);
  1453   case EggTexture::ET_modulate_gloss:
  1454     stage->set_mode(TextureStage::M_modulate_gloss);
  1457   case EggTexture::ET_normal:
  1458     stage->set_mode(TextureStage::M_normal);
  1461   case EggTexture::ET_normal_height:
  1462     stage->set_mode(TextureStage::M_normal_height);
  1465   case EggTexture::ET_glow:
  1466     stage->set_mode(TextureStage::M_glow);
  1469   case EggTexture::ET_gloss:
  1470     stage->set_mode(TextureStage::M_gloss);
  1473   case EggTexture::ET_height:
  1474     stage->set_mode(TextureStage::M_height);
  1477   case EggTexture::ET_selector:
  1478     stage->set_mode(TextureStage::M_selector);
  1481   case EggTexture::ET_normal_gloss:
  1482     stage->set_mode(TextureStage::M_normal_gloss);
  1485   case EggTexture::ET_unspecified:
  1489   switch (egg_tex->get_combine_mode(EggTexture::CC_rgb)) {
  1490   case EggTexture::CM_replace:
  1491     stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
  1492                            get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
  1493                            get_combine_operand(egg_tex, EggTexture::CC_rgb, 0));
  1496   case EggTexture::CM_modulate:
  1497   case EggTexture::CM_add:
  1498   case EggTexture::CM_add_signed:
  1499   case EggTexture::CM_subtract:
  1500   case EggTexture::CM_dot3_rgb:
  1501   case EggTexture::CM_dot3_rgba:
  1502     stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
  1503                            get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
  1504                            get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
  1505                            get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
  1506                            get_combine_operand(egg_tex, EggTexture::CC_rgb, 1));
  1509   case EggTexture::CM_interpolate:
  1510     stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
  1511                            get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
  1512                            get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
  1513                            get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
  1514                            get_combine_operand(egg_tex, EggTexture::CC_rgb, 1),
  1515                            get_combine_source(egg_tex, EggTexture::CC_rgb, 2),
  1516                            get_combine_operand(egg_tex, EggTexture::CC_rgb, 2));
  1519   case EggTexture::CM_unspecified:
  1523   switch (egg_tex->get_combine_mode(EggTexture::CC_alpha)) {
  1524   case EggTexture::CM_replace:
  1525     stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
  1526                              get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
  1527                              get_combine_operand(egg_tex, EggTexture::CC_alpha, 0));
  1530   case EggTexture::CM_modulate:
  1531   case EggTexture::CM_add:
  1532   case EggTexture::CM_add_signed:
  1533   case EggTexture::CM_subtract:
  1534     stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
  1535                              get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
  1536                              get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
  1537                              get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
  1538                              get_combine_operand(egg_tex, EggTexture::CC_alpha, 1));
  1541   case EggTexture::CM_interpolate:
  1542     stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
  1543                              get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
  1544                              get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
  1545                              get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
  1546                              get_combine_operand(egg_tex, EggTexture::CC_alpha, 1),
  1547                              get_combine_source(egg_tex, EggTexture::CC_alpha, 2),
  1548                              get_combine_operand(egg_tex, EggTexture::CC_alpha, 2));
  1551   case EggTexture::CM_unspecified:
  1552   case EggTexture::CM_dot3_rgb:
  1553   case EggTexture::CM_dot3_rgba:
  1560       InternalName::get_texcoord_name(egg_tex->
get_uv_name());
  1561     stage->set_texcoord_name(name);
  1593 separate_switches(
EggNode *egg_node) {
  1594   bool parent_has_switch = 
false;
  1595   if (egg_node->
is_of_type(EggGroup::get_class_type())) {
  1597     parent_has_switch = egg_group->get_switch_flag();
  1600   if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
  1603     EggGroupNode::iterator ci;
  1604     ci = egg_group->begin();
  1605     while (ci != egg_group->end()) {
  1606       EggGroupNode::iterator cnext;
  1611       if (parent_has_switch &&
  1612           child->is_of_type(EggPrimitive::get_class_type())) {
  1615         egg_group->
replace(ci, new_group.p());
  1616         new_group->add_child(child);
  1619       separate_switches(child);
  1632 emulate_bface(
EggNode *egg_node) {
  1633   if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
  1637     EggGroupNode::iterator ci;
  1638     for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  1640       if (child->is_of_type(EggPolygon::get_class_type())) {
  1646           dup_poly->reverse_vertex_ordering();
  1647           if (dup_poly->has_normal()) {
  1648             dup_poly->set_normal(-dup_poly->get_normal());
  1652           EggPolygon::iterator vi;
  1653           for (vi = dup_poly->begin(); vi != dup_poly->end(); ++vi) {
  1655             if (vertex->has_normal()) {
  1657               dup_vertex.set_normal(-dup_vertex.get_normal());
  1659               if (new_vertex != vertex) {
  1661                 dup_poly->replace(vi, new_vertex);
  1665           dup_prims->add_child(dup_poly);
  1669       emulate_bface(child);
  1683   if (egg_node->
is_of_type(EggBin::get_class_type())) {
  1684     return make_node(DCAST(
EggBin, egg_node), parent);
  1685   } 
else if (egg_node->
is_of_type(EggGroup::get_class_type())) {
  1686     return make_node(DCAST(
EggGroup, egg_node), parent);
  1687   } 
else if (egg_node->
is_of_type(EggTable::get_class_type())) {
  1688     return make_node(DCAST(
EggTable, egg_node), parent);
  1689   } 
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
  1690     return make_node(DCAST(
EggGroupNode, egg_node), parent);
  1704   switch (egg_bin->get_bin_number()) {
  1705   case EggBinner::BN_polyset:
  1706   case EggBinner::BN_patches:
  1707     make_polyset(egg_bin, parent, 
nullptr, _dynamic_override, _dynamic_override_char_maker);
  1710   case EggBinner::BN_lod:
  1711     return make_lod(egg_bin, parent);
  1713   case EggBinner::BN_nurbs_surface:
  1715       nassertr(!egg_bin->empty(), 
nullptr);
  1718       DCAST_INTO_R(egg_nurbs, child, 
nullptr);
  1720       make_nurbs_surface(egg_nurbs, parent, mat);
  1724   case EggBinner::BN_nurbs_curve:
  1726       nassertr(!egg_bin->empty(), 
nullptr);
  1729       DCAST_INTO_R(egg_nurbs, child, 
nullptr);
  1731       make_nurbs_curve(egg_nurbs, parent, mat);
  1735   case EggBinner::BN_none:
  1748   PT(
LODNode) lod_node = LODNode::make_default_lod(egg_bin->get_name());
  1752   EggGroup::const_iterator ci;
  1753   for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
  1754     LODInstance instance(*ci);
  1755     instances.push_back(instance);
  1760   sort(instances.begin(), instances.end());
  1762   if (!instances.empty()) {
  1765     lod_node->set_center(LCAST(PN_stdfloat, instances[0]._d->_center));
  1768   for (
size_t i = 0; i < instances.size(); i++) {
  1770     const LODInstance &instance = instances[i];
  1771     make_node(instance._egg_node, lod_node);
  1775     nassertr(lod_node->get_center().almost_equal
  1776              (LCAST(PN_stdfloat, instance._d->_center), 0.01), 
nullptr);
  1779     lod_node->add_switch(instance._d->_switch_in, instance._d->_switch_out);
  1782   _groups[egg_bin] = lod_node;
  1783   return create_group_arc(egg_bin, parent, lod_node);
  1793   if (egg_group->get_dart_type() != EggGroup::DT_none) {
  1795     bool structured = (egg_group->get_dart_type() == EggGroup::DT_structured);
  1799     node = char_maker.make_node();
  1803       _dynamic_override = 
true;
  1804       _dynamic_override_char_maker = &char_maker;
  1805       EggGroup::const_iterator ci;
  1806       for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  1807         make_node(*ci, node);
  1809       _dynamic_override_char_maker = 
nullptr;
  1810       _dynamic_override = 
false;
  1813   } 
else if (egg_group->get_cs_type() != EggGroup::CST_none) {
  1817     make_collision_solids(egg_group, egg_group, (
CollisionNode *)node.p());
  1822     if ((egg_group->get_collide_flags() & EggGroup::CF_keep) != 0) {
  1827       parent->add_child(combined);
  1828       combined->add_child(node);
  1831       EggGroup::const_iterator ci;
  1832       for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  1833         make_node(*ci, combined);
  1837     node = create_group_arc(egg_group, parent, node);
  1840   } 
else if (egg_group->get_portal_flag()) {
  1847     set_portal_polygon(egg_group, pnode);
  1849       egg2pg_cat.warning()
  1850         << 
"Portal " << egg_group->get_name() << 
" has no vertices!\n";
  1853   } 
else if (egg_group->get_occluder_flag()) {
  1860     set_occluder_polygon(egg_group, pnode);
  1862       egg2pg_cat.warning()
  1863         << 
"Occluder " << egg_group->get_name() << 
" has no vertices!\n";
  1866   } 
else if (egg_group->get_polylight_flag()) {
  1874     if (!make_sphere(egg_group, EggGroup::CF_none, center, radius, color)) {
  1875       egg2pg_cat.warning()
  1876         << 
"Polylight " << egg_group->get_name() << 
" make_sphere failed!\n";
  1887   } 
else if (egg_group->get_switch_flag()) {
  1888     if (egg_group->get_switch_fps() != 0.0) {
  1891       ((
SequenceNode *)node.p())->set_frame_rate(egg_group->get_switch_fps());
  1892       _sequences.insert(node);
  1895       node = 
new SwitchNode(egg_group->get_name());
  1898     EggGroup::const_iterator ci;
  1899     for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  1900       make_node(*ci, node);
  1902   } 
else if (egg_group->has_scrolling_uvs()) {
  1903     node = 
new UvScrollNode(egg_group->get_name(), egg_group->get_scroll_u(), egg_group->get_scroll_v(), egg_group->get_scroll_w(), egg_group->get_scroll_r());
  1905     EggGroup::const_iterator ci;
  1906     for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  1907       make_node(*ci, node);
  1910   } 
else if (egg_group->get_model_flag() || egg_group->
has_dcs_type()) {
  1912     node = 
new ModelNode(egg_group->get_name());
  1913     switch (egg_group->get_dcs_type()) {
  1914     case EggGroup::DC_net:
  1915       DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_net);
  1918     case EggGroup::DC_no_touch:
  1919       DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_no_touch);
  1922     case EggGroup::DC_local:
  1923     case EggGroup::DC_default:
  1924       DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_local);
  1927     case EggGroup::DC_none:
  1928     case EggGroup::DC_unspecified:
  1932     EggGroup::const_iterator ci;
  1933     for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  1934       make_node(*ci, node);
  1942     bool all_polysets = 
false;
  1943     bool any_hidden = 
false;
  1948       check_for_polysets(egg_group, all_polysets, any_hidden);
  1951     if (all_polysets && !any_hidden) {
  1952       node = 
new GeomNode(egg_group->get_name());
  1954       node = 
new PandaNode(egg_group->get_name());
  1957     EggGroup::const_iterator ci;
  1958     for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  1959       make_node(*ci, node);
  1963   if (node == 
nullptr) {
  1969   for (
int gri = 0; gri < num_group_refs; ++gri) {
  1971     Groups::const_iterator gi = _groups.find(group_ref);
  1972     if (gi != _groups.end()) {
  1974       node->add_child(node_ref);
  1978   _groups[egg_group] = node;
  1979   return create_group_arc(egg_group, parent, node);
  1989   parent->add_child(node);
  1999   switch (egg_group->get_billboard_type()) {
  2000   case EggGroup::BT_point_camera_relative:
  2001     node->
set_effect(BillboardEffect::make_point_eye());
  2004   case EggGroup::BT_point_world_relative:
  2005     node->
set_effect(BillboardEffect::make_point_world());
  2008   case EggGroup::BT_axis:
  2009     node->
set_effect(BillboardEffect::make_axis());
  2012   case EggGroup::BT_none:
  2016   if (egg_group->get_decal_flag()) {
  2017     if (egg_ignore_decals) {
  2019         << 
"Ignoring decal flag on " << egg_group->get_name() << 
"\n";
  2026     _decals.insert(node);
  2030   EggGroup::TagData::const_iterator ti;
  2032     node->
set_tag((*ti).first, (*ti).second);
  2035   if (egg_group->get_blend_mode() != EggGroup::BM_unspecified &&
  2036       egg_group->get_blend_mode() != EggGroup::BM_none) {
  2038     ColorBlendAttrib::Mode mode = get_color_blend_mode(egg_group->get_blend_mode());
  2039     ColorBlendAttrib::Operand a = get_color_blend_operand(egg_group->get_blend_operand_a());
  2040     ColorBlendAttrib::Operand b = get_color_blend_operand(egg_group->get_blend_operand_b());
  2042     node->
set_attrib(ColorBlendAttrib::make(mode, a, b, color));
  2049   if (egg_group->has_collide_mask()) {
  2050     def._from_collide_mask = egg_group->get_collide_mask();
  2051     def._into_collide_mask = egg_group->get_collide_mask();
  2053       DeferredNodeProperty::F_has_from_collide_mask |
  2054       DeferredNodeProperty::F_has_into_collide_mask;
  2056   if (egg_group->has_from_collide_mask()) {
  2057     def._from_collide_mask = egg_group->get_from_collide_mask();
  2058     def._flags |= DeferredNodeProperty::F_has_from_collide_mask;
  2060   if (egg_group->has_into_collide_mask()) {
  2061     def._into_collide_mask = egg_group->get_into_collide_mask();
  2062     def._flags |= DeferredNodeProperty::F_has_into_collide_mask;
  2065   if (def._flags != 0) {
  2066     _deferred_nodes[node] = def;
  2077   if (egg_table->get_table_type() != EggTable::TT_bundle) {
  2080     return make_node(DCAST(
EggGroupNode, egg_table), parent);
  2086   parent->add_child(node);
  2098   EggGroupNode::const_iterator ci;
  2099   for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  2100     make_node(*ci, node);
  2103   parent->add_child(node);
  2112 check_for_polysets(
EggGroup *egg_group, 
bool &all_polysets, 
bool &any_hidden) {
  2113   all_polysets = (!egg_group->empty());
  2116   EggGroup::const_iterator ci;
  2117   for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  2118     if ((*ci)->is_of_type(EggBin::get_class_type())) {
  2120       if (egg_bin->get_bin_number() == EggBinner::BN_polyset) {
  2123         EggGroup::const_iterator bci = egg_bin->begin();
  2124         nassertv(bci != egg_bin->end());
  2126         DCAST_INTO_V(first_prim, (*bci));
  2128         DCAST_INTO_V(render_state, first_prim->get_user_data(EggRenderState::get_class_type()));
  2130         if (render_state->_hidden) {
  2134         all_polysets = 
false;
  2137     } 
else if ((*ci)->is_of_type(EggGroup::get_class_type())) {
  2141       all_polysets = 
false;
  2157                  bool ignore_color) {
  2158   VertexPoolTransform vpt;
  2159   vpt._vertex_pool = vertex_pool;
  2160   vpt._bake_in_uvs = render_state->_bake_in_uvs;
  2161   vpt._transform = transform;
  2163   VertexPoolData::iterator di;
  2164   di = _vertex_pool_data.find(vpt);
  2165   if (di != _vertex_pool_data.end()) {
  2166     return (*di).second;
  2172      Geom::NT_stdfloat, Geom::C_point);
  2175     array_format->add_column
  2176       (InternalName::get_normal(), 3,
  2177        Geom::NT_stdfloat, Geom::C_normal);
  2180   if (!ignore_color) {
  2184     array_format->add_column(InternalName::get_color(), 1,
  2185                              Geom::NT_packed_dabc, Geom::C_color);
  2187     array_format->add_column(InternalName::get_color(), 4,
  2188                              Geom::NT_uint8, Geom::C_color);
  2192   vector_string uv_names, uvw_names, tbn_names;
  2193   vertex_pool->
get_uv_names(uv_names, uvw_names, tbn_names);
  2194   vector_string::const_iterator ni;
  2195   for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
  2196     string name = (*ni);
  2198     PT(
InternalName) iname = InternalName::get_texcoord_name(name);
  2200     if (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end()) {
  2202       array_format->add_column
  2203         (iname, 3, Geom::NT_stdfloat, Geom::C_texcoord);
  2205       array_format->add_column
  2206         (iname, 2, Geom::NT_stdfloat, Geom::C_texcoord);
  2209   for (ni = tbn_names.begin(); ni != tbn_names.end(); ++ni) {
  2210     string name = (*ni);
  2212     PT(
InternalName) iname_t = InternalName::get_tangent_name(name);
  2213     PT(
InternalName) iname_b = InternalName::get_binormal_name(name);
  2215     array_format->add_column
  2216       (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector);
  2217     array_format->add_column
  2218       (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector);
  2221   vector_string aux_names;
  2223   for (ni = aux_names.begin(); ni != aux_names.end(); ++ni) {
  2224     string name = (*ni);
  2226     array_format->add_column
  2227       (iname, 4, Geom::NT_stdfloat, Geom::C_other);
  2233   string name = _data->get_egg_filename().get_basename_wo_extension();
  2244     temp_format->set_animation(animation);
  2248       (InternalName::get_transform_blend(), 1,
  2249        Geom::NT_uint16, Geom::C_index, 0, 2);
  2250     temp_format->add_array(anim_array_format);
  2254     for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
  2257       EggMorphVertexList::const_iterator mvi;
  2258       for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
  2259         slider_names[(*mvi).get_name()].set_bit(vertex->
get_index());
  2260         record_morph(anim_array_format, character_maker, (*mvi).
get_name(),
  2261                      InternalName::get_vertex(), 3);
  2263       if (vertex->has_normal()) {
  2264         EggMorphNormalList::const_iterator mni;
  2265         for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
  2266           slider_names[(*mni).get_name()].set_bit(vertex->
get_index());
  2267           record_morph(anim_array_format, character_maker, (*mni).
get_name(),
  2268                        InternalName::get_normal(), 3);
  2271       if (!ignore_color && vertex->has_color()) {
  2272         EggMorphColorList::const_iterator mci;
  2273         for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
  2274           slider_names[(*mci).get_name()].set_bit(vertex->
get_index());
  2275           record_morph(anim_array_format, character_maker, (*mci).
get_name(),
  2276                        InternalName::get_color(), 4);
  2282         string name = egg_uv->get_name();
  2283         bool has_w = (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end());
  2284         PT(
InternalName) iname = InternalName::get_texcoord_name(name);
  2286         EggMorphTexCoordList::const_iterator mti;
  2287         for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
  2288           slider_names[(*mti).get_name()].set_bit(vertex->
get_index());
  2289           record_morph(anim_array_format, character_maker, (*mti).
get_name(),
  2290                        iname, has_w ? 3 : 2);
  2295     if (!slider_names.empty()) {
  2301       for (si = slider_names.begin(); si != slider_names.end(); ++si) {
  2303         slider_table->add_slider(slider, (*si).second);
  2309     name = character_maker->
get_name();
  2312   temp_format->maybe_align_columns_for_animation();
  2315     GeomVertexFormat::register_format(temp_format);
  2323   vertex_data->reserve_num_rows(vertex_pool->
size());
  2325   vertex_data->set_transform_blend_table(blend_table);
  2326   if (slider_table != 
nullptr) {
  2327     vertex_data->set_slider_table(SliderTable::register_table(slider_table));
  2332   for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
  2341       EggMorphVertexList::const_iterator mvi;
  2342       for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
  2345           InternalName::get_morph(InternalName::get_vertex(), morph.get_name());
  2347         gvw.
add_data3d(morph.get_offset() * transform);
  2351     if (vertex->has_normal()) {
  2353       LNormald orig_normal = vertex->get_normal();
  2354       LNormald transformed_normal = normalize(orig_normal * transform);
  2358         EggMorphNormalList::const_iterator mni;
  2359         for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
  2362             InternalName::get_morph(InternalName::get_normal(), morph.get_name());
  2364           LNormald morphed_normal = orig_normal + morph.get_offset();
  2365           LNormald transformed_morphed_normal = normalize(morphed_normal * transform);
  2366           LVector3d delta = transformed_morphed_normal - transformed_normal;
  2372     if (!ignore_color && vertex->has_color()) {
  2377         EggMorphColorList::const_iterator mci;
  2378         for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
  2381             InternalName::get_morph(InternalName::get_color(), morph.get_name());
  2391       LTexCoord3d orig_uvw = egg_uv->
get_uvw();
  2392       LTexCoord3d uvw = egg_uv->
get_uvw();
  2394       string name = egg_uv->get_name();
  2395       PT(
InternalName) iname = InternalName::get_texcoord_name(name);
  2398       BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname);
  2399       if (buv != render_state->_bake_in_uvs.end()) {
  2401         uvw = uvw * (*buv).second->get_transform3d();
  2407         EggMorphTexCoordList::const_iterator mti;
  2408         for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
  2411             InternalName::get_morph(iname, morph.get_name());
  2413           LTexCoord3d duvw = morph.get_offset();
  2414           if (buv != render_state->_bake_in_uvs.end()) {
  2415             LTexCoord3d new_uvw = orig_uvw + duvw;
  2416             duvw = (new_uvw * (*buv).second->get_transform3d()) - uvw;
  2424       if (egg_uv->has_tangent() && egg_uv->has_binormal()) {
  2425         PT(
InternalName) iname = InternalName::get_tangent_name(name);
  2428           LVector3d tangent = egg_uv->get_tangent();
  2429           LVector3d binormal = egg_uv->get_binormal();
  2431           gvw.
set_column(InternalName::get_binormal_name(name));
  2440       LVecBase4d aux = egg_aux->
get_aux();
  2442       string name = egg_aux->get_name();
  2451       gvw.
set_column(InternalName::get_transform_blend());
  2456   bool inserted = _vertex_pool_data.insert
  2457     (VertexPoolData::value_type(vpt, vertex_data)).second;
  2458   nassertr(inserted, vertex_data);
  2475   for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
  2484       nassertr(vt != 
nullptr, 
nullptr);
  2489       double quantize = egg_vertex_membership_quantize;
  2490       EggVertex::GroupRef::const_iterator gri;
  2494         if (quantize != 0.0) {
  2495           membership = cfloor(membership / quantize + 0.5) * quantize;
  2499         nassertr(vt != 
nullptr, 
nullptr);
  2503     if (egg_vertex_max_num_joints >= 0) {
  2508     int table_index = blend_table->add_blend(blend);
  2525              int num_components) {
  2527     InternalName::get_morph(column_name, morph_name);
  2530       (delta_name, num_components,
  2531        Geom::NT_stdfloat, Geom::C_morph_delta);
  2543                bool has_overall_color, 
const LColor &overall_color) {
  2545   if (egg_prim->
is_of_type(EggPolygon::get_class_type())) {
  2546     if (egg_prim->size() == 3) {
  2550   } 
else if (egg_prim->
is_of_type(EggTriangleStrip::get_class_type())) {
  2553   } 
else if (egg_prim->
is_of_type(EggTriangleFan::get_class_type())) {
  2556   } 
else if (egg_prim->
is_of_type(EggLine::get_class_type())) {
  2557     if (egg_prim->size() == 2) {
  2558       primitive = 
new GeomLines(Geom::UH_static);
  2563   } 
else if (egg_prim->
is_of_type(EggPoint::get_class_type())) {
  2566   } 
else if (egg_prim->
is_of_type(EggPatch::get_class_type())) {
  2567     int num_vertices = egg_prim->size();
  2568     primitive = 
new GeomPatches(num_vertices, Geom::UH_static);
  2571   if (primitive == 
nullptr) {
  2573     egg2pg_cat.warning()
  2574       << 
"Ignoring " << egg_prim->get_type() << 
"\n";
  2578   if (render_state->_flat_shaded) {
  2579     primitive->set_shade_model(GeomPrimitive::SM_flat_first_vertex);
  2581   } 
else if (egg_prim->
get_shading() == EggPrimitive::S_overall) {
  2582     primitive->set_shade_model(GeomPrimitive::SM_uniform);
  2585     primitive->set_shade_model(GeomPrimitive::SM_smooth);
  2590   PrimitiveUnifier pu(primitive);
  2591   std::pair<UniquePrimitives::iterator, bool> result =
  2592     unique_primitives.insert(UniquePrimitives::value_type(pu, primitive));
  2594   if (result.second) {
  2596     primitives.push_back(primitive);
  2598     if (egg2pg_cat.is_debug()) {
  2600         << 
"First primitive of type " << primitive->get_type()
  2601         << 
": " << primitive << 
"\n";
  2609   if (orig_prim->
get_num_vertices() + egg_prim->size() <= (
unsigned int)egg_max_indices) {
  2610     primitive = orig_prim;
  2612   } 
else if (orig_prim != primitive) {
  2614     (*result.first).second = primitive;
  2616     if (egg2pg_cat.is_debug()) {
  2618         << 
"Next primitive of type " << primitive->get_type()
  2619         << 
": " << primitive << 
"\n";
  2621     primitives.push_back(primitive);
  2625   EggPrimitive::const_iterator vi;
  2626   for (vi = egg_prim->begin(); vi != egg_prim->end(); ++vi) {
  2627     primitive->add_vertex((*vi)->get_index());
  2629   primitive->close_primitive();
  2639   PT(
EggPolygon) poly = find_first_polygon(egg_group);
  2640   if (poly != 
nullptr) {
  2643     EggPolygon::const_iterator vi;
  2644     for (vi = poly->begin(); vi != poly->end(); ++vi) {
  2645       LVertexd vert = (*vi)->
get_pos3() * mat;
  2656   PT(
EggPolygon) poly = find_first_polygon(egg_group);
  2657   if (poly != 
nullptr) {
  2658     if (poly->size() != 4) {
  2660         << 
"Invalid number of vertices for " << egg_group->get_name() << 
"\n";
  2664       LPoint3d v0 = (*poly)[0]->get_pos3() * mat;
  2665       LPoint3d v1 = (*poly)[1]->get_pos3() * mat;
  2666       LPoint3d v2 = (*poly)[2]->get_pos3() * mat;
  2667       LPoint3d v3 = (*poly)[3]->get_pos3() * mat;
  2669                           LCAST(PN_stdfloat, v1),
  2670                           LCAST(PN_stdfloat, v2),
  2671                           LCAST(PN_stdfloat, v3));
  2684 find_first_polygon(
EggGroup *egg_group) {
  2686   EggGroup::const_iterator ci;
  2687   for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  2688     if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
  2695   for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  2696     if ((*ci)->is_of_type(EggGroup::get_class_type())) {
  2698       PT(
EggPolygon) found = find_first_polygon(child_group);
  2699       if (found != 
nullptr) {
  2715 make_sphere(
EggGroup *egg_group, EggGroup::CollideFlags flags,
  2716             LPoint3 ¢er, PN_stdfloat &radius, LColor &color) {
  2717   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
  2718   if (geom_group != 
nullptr) {
  2722     EggGroup::const_iterator ci;
  2723     for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
  2724       if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
  2726         EggPrimitive::const_iterator pi;
  2727         for (pi = prim->begin(); pi != prim->end(); ++pi) {
  2728           vertices.insert(*pi);
  2734     int num_vertices = 0;
  2735     LPoint3d d_center(0.0, 0.0, 0.0);
  2738     for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
  2744     if (num_vertices > 0) {
  2745       d_center /= (double)num_vertices;
  2749       double radius2 = 0.0;
  2750       for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
  2753                 LVector3d v = p3 - d_center;
  2754         radius2 = max(radius2, v.length_squared());
  2757       center = LCAST(PN_stdfloat, d_center);
  2758       radius = sqrtf(radius2);
  2761       vi = vertices.begin();
  2775 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
  2776          LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
  2777   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
  2778   if (geom_group != 
nullptr) {
  2782     EggGroup::const_iterator ci;
  2783     for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
  2784       if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
  2786         EggPrimitive::const_iterator pi;
  2787         for (pi = prim->begin(); pi != prim->end(); ++pi) {
  2788           vertices.insert(*pi);
  2795     vi = vertices.begin();
  2797     if (vi == vertices.end()) {
  2805     LVertexd min_pd = vertex->
get_pos3();
  2806     LVertexd max_pd = min_pd;
  2809     for (++vi; vi != vertices.end(); ++vi) {
  2811       const LVertexd &pos = vertex->
get_pos3();
  2812       min_pd.set(min(min_pd[0], pos[0]),
  2813                  min(min_pd[1], pos[1]),
  2814                  min(min_pd[2], pos[2]));
  2815       max_pd.set(max(max_pd[0], pos[0]),
  2816                  max(max_pd[1], pos[1]),
  2817                  max(max_pd[2], pos[2]));
  2820     min_p = LCAST(PN_stdfloat, min_pd);
  2821     max_p = LCAST(PN_stdfloat, max_pd);
  2822     return (min_pd != max_pd);
  2834   if (egg_group->get_cs_type() != EggGroup::CST_none) {
  2835     start_group = egg_group;
  2838   switch (start_group->get_cs_type()) {
  2839   case EggGroup::CST_none:
  2843   case EggGroup::CST_plane:
  2844     make_collision_plane(egg_group, cnode, start_group->get_collide_flags());
  2847   case EggGroup::CST_polygon:
  2848     make_collision_polygon(egg_group, cnode, start_group->get_collide_flags());
  2851   case EggGroup::CST_polyset:
  2852     make_collision_polyset(egg_group, cnode, start_group->get_collide_flags());
  2855   case EggGroup::CST_sphere:
  2856     make_collision_sphere(egg_group, cnode, start_group->get_collide_flags());
  2859   case EggGroup::CST_box:
  2860     make_collision_box(egg_group, cnode, start_group->get_collide_flags());
  2863   case EggGroup::CST_inv_sphere:
  2864     make_collision_inv_sphere(egg_group, cnode, start_group->get_collide_flags());
  2867   case EggGroup::CST_tube:
  2868     make_collision_capsule(egg_group, cnode, start_group->get_collide_flags());
  2871   case EggGroup::CST_floor_mesh:
  2872     make_collision_floor_mesh(egg_group, cnode, start_group->get_collide_flags());
  2876   if ((start_group->get_collide_flags() & EggGroup::CF_descend) != 0) {
  2878     EggGroup::const_iterator ci;
  2879     for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  2880       if ((*ci)->is_of_type(EggGroup::get_class_type())) {
  2881         make_collision_solids(start_group, DCAST(
EggGroup, *ci), cnode);
  2885     egg2pg_cat.warning()
  2886       << 
"Using <Collide> without 'descend' is deprecated.  'descend' "  2887       << 
"will become the default in a future version of Panda3D.\n";
  2897                      EggGroup::CollideFlags flags) {
  2898   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
  2899   if (geom_group != 
nullptr) {
  2900     EggGroup::const_iterator ci;
  2901     for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
  2902       if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
  2904           create_collision_plane(DCAST(
EggPolygon, *ci), egg_group);
  2905         if (csplane != 
nullptr) {
  2906           apply_collision_flags(csplane, flags);
  2910       } 
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
  2914           make_collision_plane(temp_group, cnode, flags);
  2930                        EggGroup::CollideFlags flags) {
  2932   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
  2935   if (geom_group != 
nullptr) {
  2936     create_collision_floor_mesh(cnode, geom_group,flags);
  2946                        EggGroup::CollideFlags flags) {
  2948   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
  2949   if (geom_group != 
nullptr) {
  2950     EggGroup::const_iterator ci;
  2951     for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
  2952       if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
  2953         create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
  2955       } 
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
  2959           make_collision_polygon(temp_group, cnode, flags);
  2974                        EggGroup::CollideFlags flags) {
  2975   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
  2976   if (geom_group != 
nullptr) {
  2977     EggGroup::const_iterator ci;
  2978     for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
  2979       if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
  2980         create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
  2982       } 
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
  2986           make_collision_polyset(temp_group, cnode, flags);
  2999                       EggGroup::CollideFlags flags) {
  3003   if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
  3006     apply_collision_flags(cssphere, flags);
  3017                    EggGroup::CollideFlags flags) {
  3021   if (make_box(egg_group, flags, min_p, max_p, dummycolor)) {
  3024     apply_collision_flags(csbox, flags);
  3035                           EggGroup::CollideFlags flags) {
  3039   if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
  3042     apply_collision_flags(cssphere, flags);
  3053                        EggGroup::CollideFlags flags) {
  3054   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
  3055   if (geom_group != 
nullptr) {
  3059     EggGroup::const_iterator ci;
  3060     for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
  3061       if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
  3063         EggPrimitive::const_iterator pi;
  3064         for (pi = prim->begin(); pi != prim->end(); ++pi) {
  3065           vertices.insert(*pi);
  3072     size_t num_vertices = vertices.size();
  3073     if (num_vertices != 0) {
  3075       vpos.reserve(num_vertices);
  3077       LPoint3d center(0.0, 0.0, 0.0);
  3079       for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
  3081         const LPoint3d &pos = vtx->
get_pos3();
  3082         vpos.push_back(pos);
  3085       center /= (double)num_vertices;
  3091       double radius2 = 0.0;
  3092       LPoint3d far_a = center;
  3093       for (i = 0; i < num_vertices; i++) {
  3094         double dist2 = (vpos[i] - center).length_squared();
  3095         if (dist2 > radius2) {
  3105       LPoint3d far_b = center;
  3106       for (i = 0; i < num_vertices; i++) {
  3107         double dist2 = (vpos[i] - far_a).length_squared();
  3108         if (dist2 > radius2) {
  3125       LPoint3d cap_a_center(0.0, 0.0, 0.0);
  3126       LPoint3d cap_b_center(0.0, 0.0, 0.0);
  3132       double center_length = (far_a - far_b).length() / 4.0;
  3133       double center_length2 = center_length * center_length;
  3135       for (i = 0; i < num_vertices; i++) {
  3136         double dist2 = (vpos[i] - center).length_squared();
  3137         if (dist2 > center_length2) {
  3140           double dist_a2 = (vpos[i] - far_a).length_squared();
  3141           double dist_b2 = (vpos[i] - far_b).length_squared();
  3142           if (dist_a2 < dist_b2) {
  3144             cap_a_center += vpos[i];
  3148             cap_b_center += vpos[i];
  3154       if (num_a > 0 && num_b > 0) {
  3155         cap_a_center /= (double)num_a;
  3156         cap_b_center /= (double)num_b;
  3160         LVector3d axis = cap_b_center - cap_a_center;
  3165         if (IS_THRESHOLD_ZERO(axis[0], 0.01)) {
  3168         if (IS_THRESHOLD_ZERO(axis[1], 0.01)) {
  3171         if (IS_THRESHOLD_ZERO(axis[2], 0.01)) {
  3183         look_at(mat, axis, LVector3d(0.0, 0.0, 1.0), CS_zup_right);
  3184         mat.set_row(3, center);
  3186         inv_mat.invert_from(mat);
  3188         for (i = 0; i < num_vertices; i++) {
  3189           vpos[i] = vpos[i] * inv_mat;
  3192         double max_radius2 = 0.0;
  3195         for (i = 0; i < num_vertices; i++) {
  3196           LVector2d v(vpos[i][0], vpos[i][2]);
  3197           double radius2 = v.length_squared();
  3198           if (radius2 > max_radius2) {
  3199             max_radius2 = radius2;
  3209         for (i = 0; i < num_vertices; i++) {
  3210           LVector2d v(vpos[i][0], vpos[i][2]);
  3211           double radius2 = v.length_squared();
  3213           if (vpos[i][1] < min_y) {
  3216             double factor = sqrt(max_radius2 - radius2);
  3217             min_y = min(min_y, vpos[i][1] + factor);
  3219           } 
else if (vpos[i][1] > max_y) {
  3220             double factor = sqrt(max_radius2 - radius2);
  3221             max_y = max(max_y, vpos[i][1] - factor);
  3225         double length = max_y - min_y;
  3226         double radius = sqrt(max_radius2);
  3229         LVector3d half = axis * (length / 2.0);
  3230         LPoint3d point_a = center - half;
  3231         LPoint3d point_b = center + half;
  3234           new CollisionCapsule(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
  3236         apply_collision_flags(cscapsule, flags);
  3248 apply_collision_flags(
CollisionSolid *solid, EggGroup::CollideFlags flags) {
  3249   if ((flags & EggGroup::CF_intangible) != 0) {
  3252   if ((flags & EggGroup::CF_level) != 0) {
  3262 find_collision_geometry(
EggGroup *egg_group, EggGroup::CollideFlags flags) {
  3263   if ((flags & EggGroup::CF_descend) != 0) {
  3270   EggGroup::const_iterator ci;
  3271   for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  3272     if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
  3280   for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  3281     if ((*ci)->is_of_type(EggGroup::get_class_type())) {
  3283       if (child_group->get_cs_type() == egg_group->get_cs_type()) {
  3300       << 
"Ignoring degenerate collision plane in " << parent_group->get_name()
  3306     egg2pg_cat.warning()
  3307       << 
"Non-planar polygon defining collision plane in "  3308       << parent_group->get_name()
  3313   if (!egg_poly->empty()) {
  3314     EggPolygon::const_iterator vi;
  3315     vi = egg_poly->begin();
  3317     LVertexd vert = (*vi)->get_pos3();
  3318     vertices.push_back(LCAST(PN_stdfloat, vert));
  3320     LVertexd last_vert = vert;
  3322     while (vi != egg_poly->end()) {
  3323       vert = (*vi)->get_pos3();
  3324       if (!vert.almost_equal(last_vert)) {
  3325         vertices.push_back(LCAST(PN_stdfloat, vert));
  3333   if (vertices.size() < 3) {
  3336   LPlane plane(vertices[0], vertices[1], vertices[2]);
  3347                           EggGroup::CollideFlags flags) {
  3353       << 
"Ignoring degenerate collision polygon in "  3354       << parent_group->get_name()
  3359   if (group->size() != 1) {
  3361       << 
"Triangulating concave or non-planar collision polygon in "  3362       << parent_group->get_name()
  3366   EggGroup::iterator ci;
  3367   for (ci = group->begin(); ci != group->end(); ++ci) {
  3371     if (!poly->empty()) {
  3372       EggPolygon::const_iterator vi;
  3375       LVertexd vert = (*vi)->get_pos3();
  3376       vertices.push_back(LCAST(PN_stdfloat, vert));
  3378       LVertexd last_vert = vert;
  3380       while (vi != poly->end()) {
  3381         vert = (*vi)->get_pos3();
  3382         if (!vert.almost_equal(last_vert)) {
  3383           vertices.push_back(LCAST(PN_stdfloat, vert));
  3391     if (vertices.size() >= 3) {
  3392       const LVertex *vertices_begin = &vertices[0];
  3393       const LVertex *vertices_end = vertices_begin + vertices.size();
  3396       if (cspoly->is_valid()) {
  3397         apply_collision_flags(cspoly, flags);
  3411                           EggGroup::CollideFlags flags) {
  3415   pool.local_object();
  3416   EggGroup::const_iterator egi;
  3417   for (egi = parent_group->begin(); egi != parent_group->end(); ++egi) {
  3418     if ((*egi)->is_of_type(EggPolygon::get_class_type())) {
  3422           << 
"Ignoring degenerate collision polygon in "  3423           << parent_group->get_name()
  3430   if(group->size() == 0) {
  3432       << 
"empty collision solid\n";
  3438   EggGroup::iterator ci;
  3439   for (ci = group->begin(); ci != group->end(); ++ci) {
  3441     if (poly->get_num_vertices() == 3) {
  3442       CollisionFloorMesh::TriangleIndices tri;
  3445       tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
  3446       tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
  3447       tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
  3449       triangles.push_back(tri);
  3450     } 
else if (poly->get_num_vertices() == 4) {
  3453       CollisionFloorMesh::TriangleIndices tri;
  3454       CollisionFloorMesh::TriangleIndices tri2;
  3457       tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
  3458       tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
  3459       tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
  3461       triangles.push_back(tri);
  3466       tri2.p3=pool.create_unique_vertex(*poly->
get_vertex(3))->get_index();
  3469       triangles.push_back(tri2);
  3478   for (vi = pool.begin(); vi != pool.end(); vi++) {
  3479     csfloor->add_vertex(LCAST(PN_stdfloat,(*vi)->get_pos3()));
  3484   for (ti = triangles.begin(); ti != triangles.end(); ti++) {
  3485     CollisionFloorMesh::TriangleIndices triangle = *ti;
  3486     csfloor->add_triangle(triangle.p1, triangle.p2, triangle.p3);
  3501   DeferredNodes::const_iterator dni;
  3502   dni = _deferred_nodes.find(node);
  3504   if (dni != _deferred_nodes.end()) {
  3510   next_prop.apply_to_node(node);
  3513   for (
int i = 0; i < num_children; i++) {
  3514     apply_deferred_nodes(node->
get_child(i), next_prop);
  3527 expand_all_object_types(
EggNode *egg_node) {
  3528   if (egg_node->
is_of_type(EggGroup::get_class_type())) {
  3531     if (egg_group->get_num_object_types() != 0) {
  3534       if (!expand_object_types(egg_group, expanded, expanded_history)) {
  3542   if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
  3544     EggGroupNode::const_iterator ci;
  3545     ci = egg_group_node->begin();
  3546     while (ci != egg_group_node->end()) {
  3547       EggGroupNode::const_iterator cnext = ci;
  3550       if (!expand_all_object_types(*ci)) {
  3552         egg_group_node->erase(ci);
  3573   int num_object_types = egg_group->get_num_object_types();
  3576   vector_string object_types;
  3578   for (i = 0; i < num_object_types; i++) {
  3579     object_types.push_back(egg_group->get_object_type(i));
  3581   egg_group->clear_object_types();
  3583   for (i = 0; i < num_object_types; i++) {
  3584     string object_type = object_types[i];
  3588     if (!new_expanded.insert(object_type).second) {
  3590         << 
"Cycle in ObjectType expansions:\n";
  3592       for (pi = expanded_history.begin();
  3593            pi != expanded_history.end();
  3595         egg2pg_cat.error(
false)
  3598       egg2pg_cat.error(
false) << object_type << 
"\n";
  3604       new_expanded_history.push_back(object_type);
  3606       if (!do_expand_object_type(egg_group, new_expanded,
  3607                                  new_expanded_history, object_type)) {
  3623                       const string &object_type) {
  3628     (
"egg-object-type-" + 
downcase(object_type), 
"");
  3629   string egg_syntax = egg_object_type;
  3631   if (!egg_object_type.has_value()) {
  3634     if (cmp_nocase_uh(object_type, 
"barrier") == 0) {
  3635       egg_syntax = 
"<Collide> { Polyset descend }";
  3637     } 
else if (cmp_nocase_uh(object_type, 
"solidpoly") == 0) {
  3638       egg_syntax = 
"<Collide> { Polyset descend solid }";
  3640     } 
else if (cmp_nocase_uh(object_type, 
"turnstile") == 0) {
  3641       egg_syntax = 
"<Collide> { Polyset descend turnstile }";
  3643     } 
else if (cmp_nocase_uh(object_type, 
"sphere") == 0) {
  3644       egg_syntax = 
"<Collide> { Sphere descend }";
  3646     } 
else if (cmp_nocase_uh(object_type, 
"tube") == 0) {
  3647       egg_syntax = 
"<Collide> { Tube descend }";
  3649     } 
else if (cmp_nocase_uh(object_type, 
"trigger") == 0) {
  3650       egg_syntax = 
"<Collide> { Polyset descend intangible }";
  3652     } 
else if (cmp_nocase_uh(object_type, 
"trigger_sphere") == 0) {
  3653       egg_syntax = 
"<Collide> { Sphere descend intangible }";
  3655     } 
else if (cmp_nocase_uh(object_type, 
"eye_trigger") == 0) {
  3656       egg_syntax = 
"<Collide> { Polyset descend intangible center }";
  3658     } 
else if (cmp_nocase_uh(object_type, 
"bubble") == 0) {
  3659       egg_syntax = 
"<Collide> { Sphere keep descend }";
  3661     } 
else if (cmp_nocase_uh(object_type, 
"ghost") == 0) {
  3662       egg_syntax = 
"<Scalar> collide-mask { 0 }";
  3664     } 
else if (cmp_nocase_uh(object_type, 
"dcs") == 0) {
  3665       egg_syntax = 
"<DCS> { 1 }";
  3667     } 
else if (cmp_nocase_uh(object_type, 
"model") == 0) {
  3668       egg_syntax = 
"<Model> { 1 }";
  3670     } 
else if (cmp_nocase_uh(object_type, 
"none") == 0) {
  3674     } 
else if (cmp_nocase_uh(object_type, 
"backstage") == 0) {
  3680         << 
"Unknown ObjectType " << object_type << 
"\n";
  3682       egg2pg_cat.debug() << 
"returning true\n";
  3687   if (!egg_syntax.empty()) {
  3688     if (!egg_group->
parse_egg(egg_syntax)) {
  3690         << 
"Error while parsing definition for ObjectType "  3691         << object_type << 
"\n";
  3697       if (egg_group->get_num_object_types() != 0) {
  3698         if (!expand_object_types(egg_group, expanded, expanded_history)) {
  3712 TextureStage::CombineMode EggLoader::
  3714                  EggTexture::CombineChannel channel) {
  3715   switch (egg_tex->get_combine_mode(channel)) {
  3716   case EggTexture::CM_unspecified:
  3719   case EggTexture::CM_modulate:
  3720     return TextureStage::CM_modulate;
  3722   case EggTexture::CM_replace:
  3723     return TextureStage::CM_replace;
  3725   case EggTexture::CM_add:
  3726     return TextureStage::CM_add;
  3728   case EggTexture::CM_add_signed:
  3729     return TextureStage::CM_add_signed;
  3731   case EggTexture::CM_interpolate:
  3732     return TextureStage::CM_interpolate;
  3734   case EggTexture::CM_subtract:
  3735     return TextureStage::CM_subtract;
  3737   case EggTexture::CM_dot3_rgb:
  3738     return TextureStage::CM_dot3_rgb;
  3740   case EggTexture::CM_dot3_rgba:
  3741     return TextureStage::CM_dot3_rgba;
  3744   return TextureStage::CM_undefined;
  3751 TextureStage::CombineSource EggLoader::
  3752 get_combine_source(
const EggTexture *egg_tex,
  3753                    EggTexture::CombineChannel channel, 
int n) {
  3754   switch (egg_tex->get_combine_source(channel, n)) {
  3755   case EggTexture::CS_unspecified:
  3760       return TextureStage::CS_previous;
  3762       return TextureStage::CS_texture;
  3764       return TextureStage::CS_constant;
  3768   case EggTexture::CS_texture:
  3769     return TextureStage::CS_texture;
  3771   case EggTexture::CS_constant:
  3772     return TextureStage::CS_constant;
  3774   case EggTexture::CS_primary_color:
  3775     return TextureStage::CS_primary_color;
  3777   case EggTexture::CS_previous:
  3778     return TextureStage::CS_previous;
  3780   case EggTexture::CS_constant_color_scale:
  3781     return TextureStage::CS_constant_color_scale;
  3783   case EggTexture::CS_last_saved_result:
  3784     return TextureStage::CS_last_saved_result;
  3787   return TextureStage::CS_undefined;
  3794 TextureStage::CombineOperand EggLoader::
  3795 get_combine_operand(
const EggTexture *egg_tex,
  3796                     EggTexture::CombineChannel channel, 
int n) {
  3797   switch (egg_tex->get_combine_operand(channel, n)) {
  3798   case EggTexture::CO_unspecified:
  3799     if (channel == EggTexture::CC_rgb) {
  3802       return n < 2 ? TextureStage::CO_src_color : TextureStage::CO_src_alpha;
  3805       return TextureStage::CO_src_alpha;
  3808   case EggTexture::CO_src_color:
  3809     return TextureStage::CO_src_color;
  3811   case EggTexture::CO_one_minus_src_color:
  3812     return TextureStage::CO_one_minus_src_color;
  3814   case EggTexture::CO_src_alpha:
  3815     return TextureStage::CO_src_alpha;
  3817   case EggTexture::CO_one_minus_src_alpha:
  3818     return TextureStage::CO_one_minus_src_alpha;
  3821   return TextureStage::CO_undefined;
  3828 ColorBlendAttrib::Mode EggLoader::
  3829 get_color_blend_mode(EggGroup::BlendMode mode) {
  3831   case EggGroup::BM_unspecified:
  3832   case EggGroup::BM_none:
  3833     return ColorBlendAttrib::M_none;
  3834   case EggGroup::BM_add:
  3835     return ColorBlendAttrib::M_add;
  3836   case EggGroup::BM_subtract:
  3837     return ColorBlendAttrib::M_subtract;
  3838   case EggGroup::BM_inv_subtract:
  3839     return ColorBlendAttrib::M_inv_subtract;
  3840   case EggGroup::BM_min:
  3841     return ColorBlendAttrib::M_min;
  3842   case EggGroup::BM_max:
  3843     return ColorBlendAttrib::M_max;
  3846   return ColorBlendAttrib::M_none;
  3853 ColorBlendAttrib::Operand EggLoader::
  3854 get_color_blend_operand(EggGroup::BlendOperand operand) {
  3856   case EggGroup::BO_zero:
  3857     return ColorBlendAttrib::O_zero;
  3858   case EggGroup::BO_unspecified:
  3859   case EggGroup::BO_one:
  3860     return ColorBlendAttrib::O_one;
  3861   case EggGroup::BO_incoming_color:
  3862     return ColorBlendAttrib::O_incoming_color;
  3863   case EggGroup::BO_one_minus_incoming_color:
  3864     return ColorBlendAttrib::O_one_minus_incoming_color;
  3865   case EggGroup::BO_fbuffer_color:
  3866     return ColorBlendAttrib::O_fbuffer_color;
  3867   case EggGroup::BO_one_minus_fbuffer_color:
  3868     return ColorBlendAttrib::O_one_minus_fbuffer_color;
  3869   case EggGroup::BO_incoming_alpha:
  3870     return ColorBlendAttrib::O_incoming_alpha;
  3871   case EggGroup::BO_one_minus_incoming_alpha:
  3872     return ColorBlendAttrib::O_one_minus_incoming_alpha;
  3873   case EggGroup::BO_fbuffer_alpha:
  3874     return ColorBlendAttrib::O_fbuffer_alpha;
  3875   case EggGroup::BO_one_minus_fbuffer_alpha:
  3876     return ColorBlendAttrib::O_one_minus_fbuffer_alpha;
  3877   case EggGroup::BO_constant_color:
  3878     return ColorBlendAttrib::O_constant_color;
  3879   case EggGroup::BO_one_minus_constant_color:
  3880     return ColorBlendAttrib::O_one_minus_constant_color;
  3881   case EggGroup::BO_constant_alpha:
  3882     return ColorBlendAttrib::O_constant_alpha;
  3883   case EggGroup::BO_one_minus_constant_alpha:
  3884     return ColorBlendAttrib::O_one_minus_constant_alpha;
  3885   case EggGroup::BO_incoming_color_saturate:
  3886     return ColorBlendAttrib::O_incoming_color_saturate;
  3887   case EggGroup::BO_color_scale:
  3888     return ColorBlendAttrib::O_color_scale;
  3889   case EggGroup::BO_one_minus_color_scale:
  3890     return ColorBlendAttrib::O_one_minus_color_scale;
  3891   case EggGroup::BO_alpha_scale:
  3892     return ColorBlendAttrib::O_alpha_scale;
  3893   case EggGroup::BO_one_minus_alpha_scale:
  3894     return ColorBlendAttrib::O_one_minus_alpha_scale;
  3897   return ColorBlendAttrib::O_zero;
  3903 bool EggLoader::VertexPoolTransform::
  3904 operator < (
const EggLoader::VertexPoolTransform &other)
 const {
  3905   if (_vertex_pool != other._vertex_pool) {
  3906     return _vertex_pool < other._vertex_pool;
  3908   int compare = _transform.compare_to(other._transform, 0.001);
  3913   if (_bake_in_uvs.size() != other._bake_in_uvs.size()) {
  3914     return _bake_in_uvs.size() < other._bake_in_uvs.size();
  3917   BakeInUVs::const_iterator ai, bi;
  3918   ai = _bake_in_uvs.begin();
  3919   bi = other._bake_in_uvs.begin();
  3920   while (ai != _bake_in_uvs.end()) {
  3921     nassertr(bi != other._bake_in_uvs.end(), 
false);
  3922     if ((*ai) != (*bi)) {
  3923       return (*ai) < (*bi);
  3928   nassertr(bi == other._bake_in_uvs.end(), 
false);
 PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
 
get_rgb_scale
Returns the rgb_scale value that has been specified for the texture, or 1 if no rgb_scale value has b...
 
A node of this type is created automatically at the root of each model file that is loaded.
 
TagData::const_iterator tag_begin() const
Returns an iterator that can, in conjunction with tag_end(), be used to traverse the entire set of ta...
 
get_stage_name
Returns the stage name that has been specified for this texture, or the tref name if no texture stage...
 
get_multiview
Returns the current setting of the multiview flag.
 
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so.
 
The set of UV's that may or may not be assigned to a vertex.
 
GroupRef::size_type gref_size() const
Returns the number of elements between gref_begin() and gref_end().
 
AlphaMode get_alpha_mode() const
Returns the alpha mode that was set, or AM_unspecified if nothing was set.
 
int get_num_children(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of children of the referenced node.
 
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_num_vertices
Returns the number of vertices in the occluder polygon.
 
get_alpha_file_channel
Returns the particular channel that has been specified for the alpha-file image, or 0 if no channel h...
 
A basic node of the scene graph or data graph.
 
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
 
GroupRef::const_iterator gref_end() const
Returns an iterator that can, in conjunction with gref_begin(), be used to traverse the entire set of...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void set_vertices(const LPoint3 &v0, const LPoint3 &v1, const LPoint3 &v2, const LPoint3 &v3)
Replaces the four vertices of the occluder polygon.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is an iterator adaptor that converts any iterator that returns a pair (e.g.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_order
Returns the order of the curve.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_filename
Sets the name of the file that contains the image's contents.
 
This is our own Panda specialization on the default STL map.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
has_alpha_scale
Returns true if an alpha_scale has been specified for the texture, false otherwise.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
int get_num_dimensions() const
Returns the maximum number of dimensions used by any vertex in the pool.
 
The base class for primitives such as triangle strips and triangle fans, which include several compon...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_alpha_fullpath
Returns the full pathname to the alpha file, if it is known; otherwise, returns the same thing as get...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
VertexSlider * egg_to_slider(const std::string &name)
Returns the VertexSlider corresponding to the indicated egg slider name.
 
static Texture * load_cube_map(const Filename &filename_pattern, bool read_mipmaps=false, const LoaderOptions &options=LoaderOptions())
Loads a cube map texture that is specified with a series of 6 pages, numbered 0 through 5.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This class keeps track of all the state we must make note of during the graph traversal,...
 
get_uv_name
Returns the texcoord name that has been specified for this texture, or the empty string if no texcoor...
 
has_priority
Returns true if a priority value for multitexture importance has been specified for the texture,...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Defines a series of disconnected points.
 
size_t add_solid(const CollisionSolid *solid)
Adds the indicated solid to the node.
 
virtual bool cleanup() override
Cleans up modeling errors in whatever context this makes sense.
 
bool is_planar() const
Returns true if all of the polygon's vertices lie within the same plane, false otherwise.
 
set_min_lod
Sets the minimum level of detail that will be used when sampling this texture.
 
A virtual base class for parametric curves.
 
bool is_empty() const
Returns true if the NodePath contains no nodes.
 
CurveType get_curve_type() const
Returns the indicated type of the curve.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_anisotropic_degree
Specifies the level of anisotropic filtering to apply to the SamplerState.
 
get_read_mipmaps
Returns the current setting of the read_mipmaps flag.
 
TagData::const_iterator tag_end() const
Returns an iterator that can, in conjunction with tag_begin(), be used to traverse the entire set of ...
 
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded.
 
CPT(TransformState) EggLoader
Creates a TransformState object corresponding to the indicated EggTransform.
 
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
 
Specifies parameters that may be passed to the loader.
 
set_lod_bias
Sets the value that will be added to the level of detail when sampling the texture.
 
A base class for nodes in the hierarchy that are not leaf nodes.
 
const LTexCoord3d & get_uvw() const
Returns the texture coordinate triple, if get_num_dimensions() is 3.
 
The abstract base class for all things that can collide with other things in the world,...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
int triangulate_polygons(int flags)
Replace all higher-order polygons at this point in the scene graph and below with triangles.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
has_alpha_filename
Returns true if a separate file for the alpha component has been applied, false otherwise.
 
Defines a texture map that may be applied to geometry.
 
bool has_vertex_color() const
Returns true if any vertex on the primitive has a specific color set, false otherwise.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
A cuboid collision volume or object.
 
This class is an abstraction for evaluating NURBS curves.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Defines a series of triangle fans.
 
has_border_color
Returns true if a border color has been specified for the texture.
 
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void loop(bool restart)
Starts the entire animation looping.
 
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
 
int get_v_subdiv() const
Returns the requested number of subdivisions in the U direction, or 0 if no particular subdivisions h...
 
get_min_lod
Returns the minimum mipmap level that has been specified for this texture.
 
get_num_vertices
Returns the number of indices used by all the primitives in this object.
 
void check_overall_color(bool &has_overall_color, LColor &overall_color) const
Scans the vertex pool for different colors on different vertices.
 
set_bface_flag
Sets the backfacing flag of the polygon.
 
const_aux_iterator aux_end() const
Returns an iterator that allows walking through the complete set of auxiliary data on the vertex.
 
A base class for things which need to inherit from both TypedObject and from ReferenceCount.
 
get_shading
Returns the shading properties apparent on this particular primitive.
 
string downcase(const string &s)
Returns the input string with all uppercase letters converted to lowercase.
 
A node that automatically cycles through rendering each one of its children according to its frame ra...
 
get_border_color
Returns the border color if one has been specified, or (0, 0, 0, 1) otherwise.
 
This class draws a visible representation of the NURBS curve stored in its NurbsCurveEvaluator.
 
void set_data1i(int data)
Sets the write row to a particular 1-component value, and advances the write row.
 
This is a collection of textures by TRef name.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Defines a series of triangle strips.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
GroupRef::const_iterator gref_begin() const
Returns an iterator that can, in conjunction with gref_end(), be used to traverse the entire set of g...
 
This is an abstract base class that retains some slider value, which is a linear value that typically...
 
set_magfilter
Sets the filtering method that should be used when viewing the SamplerState up close.
 
set_wrap_w
The W wrap direction is only used for 3-d SamplerStates.
 
void apply_first_attribute(bool recurse)
Sets the first vertex of the triangle (or each component) to the primitive normal and/or color,...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
has_stage_name
Returns true if a stage name has been explicitly specified for this texture, false otherwise.
 
This class is an abstraction for evaluating NURBS surfaces.
 
A spherical collision volume or object.
 
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
 
set_anisotropic_degree
Sets the degree of anisotropic filtering for this texture.
 
void set_external_index(int external_index)
Sets a special index number that is associated with the EggVertex (but is not written to the egg file...
 
std::string get_name() const
Returns the name of the character.
 
A single <Dxyz> or <Duv> or some such entry.
 
This abstract class defines the interface only for a Nurbs-style curve, with knots and coordinates in...
 
This is the primary interface into all the egg data, and the root of the egg file structure.
 
void set_radius(PN_stdfloat r)
Set radius of the spherical light volume.
 
void set_effective_normal(const LVector3 &effective_normal)
Records a false normal for this CollisionSolid that will be reported by the collision system with all...
 
LColor get_color() const
Returns the color set on this particular attribute.
 
get_num_group_refs
Returns the number of <Ref> entries within this group.
 
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
 
size_type size() const
Returns the number of vertices in the pool.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void add_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row.
 
bool has_normals() const
Returns true if any vertex in the pool has a normal defined, false if none of them do.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
iterator end() const
Returns an iterator that can be used to traverse through all the vertices in the pool.
 
set_texture_num_views
Specifies the expected number of views to load for the texture.
 
get_vertex
Returns a particular index based on its index number.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_num_knots
Returns the number of knots.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_minfilter
Sets the filtering method that should be used when viewing the SamplerState from a distance.
 
has_color
Returns true if a blend color has been specified for the texture.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
bool parse_egg(const std::string &egg_syntax)
Parses the egg syntax given in the indicate string as if it had been read from the egg file within th...
 
void set_pos(const LPoint3 &position)
Set this light's position.
 
A node in the scene graph that can hold an occluder polygon, which must be a rectangle.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_tag
Associates a user-defined value with a user-defined key which is stored on the node.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_transform
Sets the transform that will be applied to this node and below.
 
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is our own Panda specialization on the default STL vector.
 
iterator begin() const
Returns an iterator that can be used to traverse through all the vertices in the pool.
 
This class is used within this package only to record the render state that should be assigned to eac...
 
virtual bool determine_decal()
Walks back up the hierarchy, looking for an EggGroup at this level or above that has the "decal" flag...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
 
WrapMode determine_wrap_w() const
Determines the appropriate wrap in the W direction.
 
void set_data3d(double x, double y, double z)
Sets the write row to a particular 3-component value, and advances the write row.
 
WrapMode determine_wrap_v() const
Determines the appropriate wrap in the V direction.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_anisotropic_degree
Returns the anisotropic filtering degree that has been specified for this texture,...
 
Stores the total set of VertexSliders that the vertices in a particular GeomVertexData object might d...
 
void reparent_to(const NodePath &other, int sort=0, Thread *current_thread=Thread::get_current_thread())
Removes the referenced node of the NodePath from its current parent and attaches it to the referenced...
 
A node in the scene graph that can hold a Portal Polygon, which is a rectangle.
 
set_wrap_u
This setting determines what happens when the SamplerState is sampled with a U value outside the rang...
 
int get_index() const
Returns the index number of the vertex within its pool.
 
get_num_children
Returns the number of child nodes this node has.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void get_uv_names(vector_string &uv_names, vector_string &uvw_names, vector_string &tbn_names) const
Returns the list of UV names that are defined by any vertices in the pool, as well as the subset of U...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void start_sequences()
Starts all of the SequenceNodes we created looping.
 
void set_data4d(double x, double y, double z, double w)
Sets the write row to a particular 4-component value, and advances the write row.
 
void set_panda()
Specifies that vertex animation is to be performed by Panda.
 
int get_subdiv() const
Returns the requested number of subdivisions, or 0 if no particular subdivisions have been requested.
 
This node is placed at key points within the scene graph to indicate the roots of "models": subtrees ...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Defines a series of "patches", fixed-size groupings of vertices that must be processed by a tessellat...
 
This class draws a visible representation of the NURBS surface stored in its NurbsSurfaceEvaluator.
 
get_num_vertices
Returns the number of vertices in the portal polygon.
 
get_lod_bias
Returns the maximum mipmap level that has been specified for this texture.
 
get_max_lod
Returns the maximum mipmap level that has been specified for this texture.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is a convenience class to specialize ConfigVariable as a string type.
 
void add_data4d(double x, double y, double z, double w)
Sets the write row to a particular 4-component value, and advances the write row.
 
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
has_anisotropic_degree
Returns true if a value for the anisotropic filtering degree has been specified for this texture,...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_format
Changes the format value for the texture components.
 
void add_attrib(const RenderAttrib *attrib)
A convenience function to add the indicated render attribute to the aggregate state.
 
int remove_unused_vertices()
Removes all vertices from the pool that are not referenced by at least one primitive.
 
EggUserData * get_user_data() const
Returns the user data pointer most recently stored on this object, or NULL if nothing was previously ...
 
bool triangulate_into(EggGroupNode *container, bool convex_also) const
Subdivides the polygon into triangles and adds each one to the indicated container.
 
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
 
void steal_children(EggGroupNode &other)
Moves all the children from the other node to this one.
 
get_num_components
Returns the number of color components for each texel of the texture image.
 
This implements a solid consisting of a cylinder with hemispherical endcaps, also known as a capsule ...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void mesh_triangles(int flags)
Combine triangles together into triangle strips, at this group and below.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
A container for geometry primitives.
 
A Nonuniform Rational B-Spline.
 
bool triangulate_into(EggGroupNode *container) const
Subdivides the composite primitive into triangles and adds those triangles to the indicated container...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void compose(const DeferredNodeProperty &other)
Composes this state with the next one encountered on a lower node during the apply traversal.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void set_alpha_mode(AlphaMode mode)
Specifies precisely how the transparency for this geometry should be achieved, or if it should be use...
 
has_rgb_scale
Returns true if an rgb_scale has been specified for the texture, false otherwise.
 
PT(TextureStage) EggLoader
Creates a TextureStage object suitable for rendering the indicated texture.
 
double get_vertex_membership(const EggVertex *vert) const
Returns the amount of membership of the indicated vertex in this group.
 
The set of named auxiliary data that may or may not be assigned to a vertex.
 
void set_effect(const RenderEffect *effect)
Adds the indicated render effect to the scene graph on this node.
 
A parametric NURBS curve.
 
A special binner used only within this package to pre-process the egg tree for the loader and group t...
 
has_min_lod
Returns true if a value for the minimum mipmap level has been specified for this texture,...
 
static Texture * load_texture(const Filename &filename, int primary_file_num_channels=0, bool read_mipmaps=false, const LoaderOptions &options=LoaderOptions())
Loads the given filename up into a texture, if it has not already been loaded, and returns the new te...
 
get_component_width
Returns the number of bytes stored for each color component of a texel.
 
void add_data3d(double x, double y, double z)
Sets the write row to a particular 3-component value, and advances the write row.
 
int find_used_textures(EggNode *node)
Walks the egg hierarchy beginning at the indicated node, looking for textures that are referenced by ...
 
void add_stashed(PandaNode *child_node, int sort=0, Thread *current_thread=Thread::get_current_thread())
Adds a new child to the node, directly as a stashed child.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
const_aux_iterator aux_begin() const
Returns an iterator that allows walking through the complete set of auxiliary data on the vertex.
 
const Filename & get_fullpath() const
Returns the full pathname to the file, if it is known; otherwise, returns the same thing as get_filen...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Encodes a string name in a hash table, mapping it to a pointer.
 
static SparseArray lower_on(int on_bits)
Returns a SparseArray whose lower on_bits bits are on.
 
void set_attrib(const RenderAttrib *attrib, int override=0)
Adds the indicated render attribute to the scene graph on this node.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This object represents a solid made entirely of triangles, which will only be tested again z axis ali...
 
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
 
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...
 
Defines a series of disconnected line segments.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_knot
Returns the nth knot value defined.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_border_color
Specifies the solid color of the SamplerState's border.
 
Represents a set of settings that indicate how a texture is sampled.
 
void set_surface(NurbsSurfaceEvaluator *surface)
Sets the particular surface represented by the SheetNode.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_default_sampler
This sets the default sampler state for this texture, containing the wrap and filter properties speci...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_alpha_filename
Returns the separate file assigned for the alpha channel.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_blend_color
Returns the blend color if one has been specified, or (0, 0, 0, 0) if one has not.
 
void replace(iterator position, PT(EggNode) x)
Replaces the node at the indicated position with the indicated node.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
set_compression
Requests that this particular Texture be compressed when it is loaded into texture memory.
 
get_alpha_scale
Returns the alpha_scale value that has been specified for the texture, or 1 if no alpha_scale value h...
 
PandaNode * node() const
Returns the referenced node of the path.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Converts an EggTable hierarchy, beginning with a <Bundle> entry, into an AnimBundle hierarchy.
 
get_priority
Returns the multitexture importance value that has been specified for the texture,...
 
set_coordinate_system
Changes the coordinate system of the EggData.
 
set_quality_level
Sets a hint to the renderer about the desired performance / quality tradeoff for this particular text...
 
get_pool
Returns the vertex pool associated with the vertices of the primitive, or NULL if the primitive has n...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
bool has_column() const
Returns true if a valid data type has been successfully set, or false if the data type does not exist...
 
has_uv_name
Returns true if a texcoord name has been explicitly specified for this texture, false otherwise.
 
get_saved_result
Returns the current setting of the saved_result flag.
 
const_uv_iterator uv_begin() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex.
 
WrapMode determine_wrap_u() const
Determines the appropriate wrap in the U direction.
 
A base class for things that may be directly added into the egg hierarchy.
 
Defines a series of line strips.
 
void sort_by_external_index()
Re-orders (and re-numbers) the vertices in this vertex pool so that they appear in increasing order b...
 
A node in the scene graph that can hold any number of CollisionSolids.
 
A parametric NURBS surface.
 
EggNode * get_first_child()
Returns the first child in the group's list of children, or NULL if the list of children is empty.
 
bool has_dcs_type() const
Returns true if the specified DCS type is not DC_none and not DC_unspecified.
 
set_wrap_v
This setting determines what happens when the SamplerState is sampled with a V value outside the rang...
 
set_max_lod
Sets the maximum level of detail that will be used when sampling this texture.
 
Defines a series of disconnected triangles.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
LPoint4d get_pos4() const
This is always valid, regardless of the value of get_num_dimensions.
 
void reparent_decals()
For each node representing a decal base geometry (i.e.
 
bool set_column(int column)
Sets up the writer to use the nth data type of the GeomVertexFormat, numbering from 0.
 
get_group_ref
Returns the nth <Ref> entry within this group.
 
int get_external_index() const
Returns the number set by set_external_index().
 
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
 
get_multitexture_sort
Returns an integer that represents the depth to which this texture is layered on all other textures i...
 
void set_color(const LColor &color)
Set the light's color...
 
This is our own Panda specialization on the default STL set.
 
get_bface_flag
Retrieves the backfacing flag of the polygon.
 
void set_row(int row)
Sets the start row to the indicated value.
 
void copy_grefs_from(const EggVertex &other)
Copies all the group references from the other vertex onto this one.
 
get_num_views
Returns the specified number of views specified for the 3-D multiview texture.
 
set_tangible
Sets the current state of the 'tangible' flag.
 
static Texture * load_3d_texture(const Filename &filename_pattern, bool read_mipmaps=false, const LoaderOptions &options=LoaderOptions())
Loads a 3-D texture that is specified with a series of n pages, all numbered in sequence,...
 
get_child
Returns the nth child node of this node.
 
void set_prev_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that represents this node's "previous" position, one frame ago,...
 
has_max_lod
Returns true if a value for the maximum mipmap level has been specified for this texture,...
 
VertexTransform * egg_to_transform(EggNode *egg_node)
Returns a JointVertexTransform suitable for applying the animation associated with the given egg node...
 
set_curve
Sets the particular curve represented by the RopeNode.
 
Converts an EggGroup hierarchy, beginning with a group with <Dart> set, to a character node with join...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void clear_vertices()
Resets the vertices of the portal to the empty list.
 
has_lod_bias
Returns true if a value for the maximum mipmap level has been specified for this texture,...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
This is a node that contains a pointer to an AnimBundle.
 
virtual bool is_geom_node() const
A simple downcast check.
 
void get_aux_names(vector_string &aux_names) const
Returns the list of auxiliary data names that are defined by any vertices in the pool.
 
set_double_sided
If true, the back-face will also be used to occlude.
 
This corresponds to a <SwitchCondition> entry within a group.
 
Defines the properties of a named stage of the multitexture pipeline.
 
void add_vertex(const LPoint3 &vertex)
Adds a new vertex to the portal polygon.
 
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...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
 
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
 
A collection of vertices.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
NodePath get_child(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns a NodePath representing the nth child of the referenced node.
 
A SwitchCondition that switches the levels-of-detail based on distance from the camera's eyepoint.
 
A node that holds Geom objects, renderable pieces of geometry.
 
void make_polyset(EggBin *egg_bin, PandaNode *parent, const LMatrix4d *transform, bool is_dynamic, CharacterMaker *character_maker)
Creates a polyset–that is, a Geom–from the primitives that have already been grouped into a bin.
 
void add_geom(Geom *geom, const RenderState *state=RenderState::make_empty())
Adds a new Geom to the node.
 
A node that renders only one of its children, according to the user's indication.
 
has_num_views
Returns true if the number of views has been specified for the 3-D multiview texture,...
 
const_uv_iterator uv_end() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex.
 
const LMatrix4d & get_vertex_to_node() const
Returns the transformation matrix suitable for converting the vertices as read from the egg file into...
 
static TextureStage * get_stage(TextureStage *temp)
Returns a TextureStage pointer that represents the same TextureStage described by temp,...
 
get_color
Returns the blend color if one has been specified, or (0, 0, 0, 1) otherwise.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
An inverted sphere: this is a sphere whose collision surface is the inside surface of the sphere.
 
const LVecBase4d & get_aux() const
Returns the auxiliary data quadruple.
 
A type of group node that holds related subnodes.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
int get_u_subdiv() const
Returns the requested number of subdivisions in the U direction, or 0 if no particular subdivisions h...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.