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) {
1820 make_collision_solids(egg_group, egg_group, (
CollisionNode *)node.p());
1821 node->clear_transform();
1823 if ((egg_group->get_collide_flags() & EggGroup::CF_keep) != 0) {
1828 parent->add_child(combined);
1829 combined->add_child(node);
1832 EggGroup::const_iterator ci;
1833 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1834 make_node(*ci, combined);
1838 node = create_group_arc(egg_group, parent, node);
1841 }
else if (egg_group->get_portal_flag()) {
1848 set_portal_polygon(egg_group, pnode);
1850 egg2pg_cat.warning()
1851 <<
"Portal " << egg_group->get_name() <<
" has no vertices!\n";
1854 }
else if (egg_group->get_occluder_flag()) {
1861 set_occluder_polygon(egg_group, pnode);
1863 egg2pg_cat.warning()
1864 <<
"Occluder " << egg_group->get_name() <<
" has no vertices!\n";
1867 }
else if (egg_group->get_polylight_flag()) {
1875 if (!make_sphere(egg_group, EggGroup::CF_none, center, radius, color)) {
1876 egg2pg_cat.warning()
1877 <<
"Polylight " << egg_group->get_name() <<
" make_sphere failed!\n";
1888 }
else if (egg_group->get_switch_flag()) {
1889 if (egg_group->get_switch_fps() != 0.0) {
1892 ((
SequenceNode *)node.p())->set_frame_rate(egg_group->get_switch_fps());
1893 _sequences.insert(node);
1896 node =
new SwitchNode(egg_group->get_name());
1899 EggGroup::const_iterator ci;
1900 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1901 make_node(*ci, node);
1903 }
else if (egg_group->has_scrolling_uvs()) {
1904 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());
1906 EggGroup::const_iterator ci;
1907 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1908 make_node(*ci, node);
1911 }
else if (egg_group->get_model_flag() || egg_group->
has_dcs_type()) {
1913 node =
new ModelNode(egg_group->get_name());
1914 switch (egg_group->get_dcs_type()) {
1915 case EggGroup::DC_net:
1916 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_net);
1919 case EggGroup::DC_no_touch:
1920 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_no_touch);
1923 case EggGroup::DC_local:
1924 case EggGroup::DC_default:
1925 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_local);
1928 case EggGroup::DC_none:
1929 case EggGroup::DC_unspecified:
1933 EggGroup::const_iterator ci;
1934 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1935 make_node(*ci, node);
1943 bool all_polysets =
false;
1944 bool any_hidden =
false;
1949 check_for_polysets(egg_group, all_polysets, any_hidden);
1952 if (all_polysets && !any_hidden) {
1953 node =
new GeomNode(egg_group->get_name());
1955 node =
new PandaNode(egg_group->get_name());
1958 EggGroup::const_iterator ci;
1959 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1960 make_node(*ci, node);
1964 if (node ==
nullptr) {
1970 for (
int gri = 0; gri < num_group_refs; ++gri) {
1972 Groups::const_iterator gi = _groups.find(group_ref);
1973 if (gi != _groups.end()) {
1975 node->add_child(node_ref);
1979 _groups[egg_group] = node;
1980 return create_group_arc(egg_group, parent, node);
1990 parent->add_child(node);
2000 switch (egg_group->get_billboard_type()) {
2001 case EggGroup::BT_point_camera_relative:
2002 node->
set_effect(BillboardEffect::make_point_eye());
2005 case EggGroup::BT_point_world_relative:
2006 node->
set_effect(BillboardEffect::make_point_world());
2009 case EggGroup::BT_axis:
2010 node->
set_effect(BillboardEffect::make_axis());
2013 case EggGroup::BT_none:
2017 if (egg_group->get_decal_flag()) {
2018 if (egg_ignore_decals) {
2020 <<
"Ignoring decal flag on " << egg_group->get_name() <<
"\n";
2027 _decals.insert(node);
2031 EggGroup::TagData::const_iterator ti;
2033 node->
set_tag((*ti).first, (*ti).second);
2036 if (egg_group->get_blend_mode() != EggGroup::BM_unspecified &&
2037 egg_group->get_blend_mode() != EggGroup::BM_none) {
2039 ColorBlendAttrib::Mode mode = get_color_blend_mode(egg_group->get_blend_mode());
2040 ColorBlendAttrib::Operand a = get_color_blend_operand(egg_group->get_blend_operand_a());
2041 ColorBlendAttrib::Operand b = get_color_blend_operand(egg_group->get_blend_operand_b());
2043 node->
set_attrib(ColorBlendAttrib::make(mode, a, b, color));
2050 if (egg_group->has_collide_mask()) {
2051 def._from_collide_mask = egg_group->get_collide_mask();
2052 def._into_collide_mask = egg_group->get_collide_mask();
2054 DeferredNodeProperty::F_has_from_collide_mask |
2055 DeferredNodeProperty::F_has_into_collide_mask;
2057 if (egg_group->has_from_collide_mask()) {
2058 def._from_collide_mask = egg_group->get_from_collide_mask();
2059 def._flags |= DeferredNodeProperty::F_has_from_collide_mask;
2061 if (egg_group->has_into_collide_mask()) {
2062 def._into_collide_mask = egg_group->get_into_collide_mask();
2063 def._flags |= DeferredNodeProperty::F_has_into_collide_mask;
2066 if (def._flags != 0) {
2067 _deferred_nodes[node] = def;
2078 if (egg_table->get_table_type() != EggTable::TT_bundle) {
2081 return make_node(DCAST(
EggGroupNode, egg_table), parent);
2087 parent->add_child(node);
2099 EggGroupNode::const_iterator ci;
2100 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2101 make_node(*ci, node);
2104 parent->add_child(node);
2113 check_for_polysets(
EggGroup *egg_group,
bool &all_polysets,
bool &any_hidden) {
2114 all_polysets = (!egg_group->empty());
2117 EggGroup::const_iterator ci;
2118 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2119 if ((*ci)->is_of_type(EggBin::get_class_type())) {
2121 if (egg_bin->get_bin_number() == EggBinner::BN_polyset) {
2124 EggGroup::const_iterator bci = egg_bin->begin();
2125 nassertv(bci != egg_bin->end());
2127 DCAST_INTO_V(first_prim, (*bci));
2129 DCAST_INTO_V(render_state, first_prim->get_user_data(EggRenderState::get_class_type()));
2131 if (render_state->_hidden) {
2135 all_polysets =
false;
2138 }
else if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2142 all_polysets =
false;
2158 bool ignore_color) {
2159 VertexPoolTransform vpt;
2160 vpt._vertex_pool = vertex_pool;
2161 vpt._bake_in_uvs = render_state->_bake_in_uvs;
2162 vpt._transform = transform;
2164 VertexPoolData::iterator di;
2165 di = _vertex_pool_data.find(vpt);
2166 if (di != _vertex_pool_data.end()) {
2167 return (*di).second;
2173 Geom::NT_stdfloat, Geom::C_point);
2176 array_format->add_column
2177 (InternalName::get_normal(), 3,
2178 Geom::NT_stdfloat, Geom::C_normal);
2181 if (!ignore_color) {
2185 array_format->add_column(InternalName::get_color(), 1,
2186 Geom::NT_packed_dabc, Geom::C_color);
2188 array_format->add_column(InternalName::get_color(), 4,
2189 Geom::NT_uint8, Geom::C_color);
2193 vector_string uv_names, uvw_names, tbn_names;
2194 vertex_pool->
get_uv_names(uv_names, uvw_names, tbn_names);
2195 vector_string::const_iterator ni;
2196 for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
2197 string name = (*ni);
2199 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2201 if (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end()) {
2203 array_format->add_column
2204 (iname, 3, Geom::NT_stdfloat, Geom::C_texcoord);
2206 array_format->add_column
2207 (iname, 2, Geom::NT_stdfloat, Geom::C_texcoord);
2210 for (ni = tbn_names.begin(); ni != tbn_names.end(); ++ni) {
2211 string name = (*ni);
2213 PT(
InternalName) iname_t = InternalName::get_tangent_name(name);
2214 PT(
InternalName) iname_b = InternalName::get_binormal_name(name);
2216 array_format->add_column
2217 (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector);
2218 array_format->add_column
2219 (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector);
2222 vector_string aux_names;
2224 for (ni = aux_names.begin(); ni != aux_names.end(); ++ni) {
2225 string name = (*ni);
2227 array_format->add_column
2228 (iname, 4, Geom::NT_stdfloat, Geom::C_other);
2234 string name = _data->get_egg_filename().get_basename_wo_extension();
2245 temp_format->set_animation(animation);
2249 (InternalName::get_transform_blend(), 1,
2250 Geom::NT_uint16, Geom::C_index, 0, 2);
2251 temp_format->add_array(anim_array_format);
2255 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2258 EggMorphVertexList::const_iterator mvi;
2259 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2260 slider_names[(*mvi).get_name()].set_bit(vertex->
get_index());
2261 record_morph(anim_array_format, character_maker, (*mvi).
get_name(),
2262 InternalName::get_vertex(), 3);
2264 if (vertex->has_normal()) {
2265 EggMorphNormalList::const_iterator mni;
2266 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2267 slider_names[(*mni).get_name()].set_bit(vertex->
get_index());
2268 record_morph(anim_array_format, character_maker, (*mni).
get_name(),
2269 InternalName::get_normal(), 3);
2272 if (!ignore_color && vertex->has_color()) {
2273 EggMorphColorList::const_iterator mci;
2274 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2275 slider_names[(*mci).get_name()].set_bit(vertex->
get_index());
2276 record_morph(anim_array_format, character_maker, (*mci).
get_name(),
2277 InternalName::get_color(), 4);
2283 string name = egg_uv->get_name();
2284 bool has_w = (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end());
2285 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2287 EggMorphTexCoordList::const_iterator mti;
2288 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2289 slider_names[(*mti).get_name()].set_bit(vertex->
get_index());
2290 record_morph(anim_array_format, character_maker, (*mti).
get_name(),
2291 iname, has_w ? 3 : 2);
2296 if (!slider_names.empty()) {
2302 for (si = slider_names.begin(); si != slider_names.end(); ++si) {
2304 slider_table->add_slider(slider, (*si).second);
2310 name = character_maker->
get_name();
2313 temp_format->maybe_align_columns_for_animation();
2316 GeomVertexFormat::register_format(temp_format);
2324 vertex_data->reserve_num_rows(vertex_pool->
size());
2326 vertex_data->set_transform_blend_table(blend_table);
2327 if (slider_table !=
nullptr) {
2328 vertex_data->set_slider_table(SliderTable::register_table(slider_table));
2333 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2342 EggMorphVertexList::const_iterator mvi;
2343 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2346 InternalName::get_morph(InternalName::get_vertex(), morph.get_name());
2348 gvw.
add_data3d(morph.get_offset() * transform);
2352 if (vertex->has_normal()) {
2354 LNormald orig_normal = vertex->get_normal();
2355 LNormald transformed_normal = normalize(orig_normal * transform);
2359 EggMorphNormalList::const_iterator mni;
2360 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2363 InternalName::get_morph(InternalName::get_normal(), morph.get_name());
2365 LNormald morphed_normal = orig_normal + morph.get_offset();
2366 LNormald transformed_morphed_normal = normalize(morphed_normal * transform);
2367 LVector3d delta = transformed_morphed_normal - transformed_normal;
2373 if (!ignore_color && vertex->has_color()) {
2378 EggMorphColorList::const_iterator mci;
2379 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2382 InternalName::get_morph(InternalName::get_color(), morph.get_name());
2392 LTexCoord3d orig_uvw = egg_uv->
get_uvw();
2393 LTexCoord3d uvw = egg_uv->
get_uvw();
2395 string name = egg_uv->get_name();
2396 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2399 BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname);
2400 if (buv != render_state->_bake_in_uvs.end()) {
2402 uvw = uvw * (*buv).second->get_transform3d();
2408 EggMorphTexCoordList::const_iterator mti;
2409 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2412 InternalName::get_morph(iname, morph.get_name());
2414 LTexCoord3d duvw = morph.get_offset();
2415 if (buv != render_state->_bake_in_uvs.end()) {
2416 LTexCoord3d new_uvw = orig_uvw + duvw;
2417 duvw = (new_uvw * (*buv).second->get_transform3d()) - uvw;
2425 if (egg_uv->has_tangent() && egg_uv->has_binormal()) {
2426 PT(
InternalName) iname = InternalName::get_tangent_name(name);
2429 LVector3d tangent = egg_uv->get_tangent();
2430 LVector3d binormal = egg_uv->get_binormal();
2432 gvw.
set_column(InternalName::get_binormal_name(name));
2441 LVecBase4d aux = egg_aux->
get_aux();
2443 string name = egg_aux->get_name();
2452 gvw.
set_column(InternalName::get_transform_blend());
2457 bool inserted = _vertex_pool_data.insert
2458 (VertexPoolData::value_type(vpt, vertex_data)).second;
2459 nassertr(inserted, vertex_data);
2476 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2485 nassertr(vt !=
nullptr,
nullptr);
2490 double quantize = egg_vertex_membership_quantize;
2491 EggVertex::GroupRef::const_iterator gri;
2495 if (quantize != 0.0) {
2496 membership = cfloor(membership / quantize + 0.5) * quantize;
2500 nassertr(vt !=
nullptr,
nullptr);
2504 if (egg_vertex_max_num_joints >= 0) {
2509 int table_index = blend_table->add_blend(blend);
2526 int num_components) {
2528 InternalName::get_morph(column_name, morph_name);
2531 (delta_name, num_components,
2532 Geom::NT_stdfloat, Geom::C_morph_delta);
2544 bool has_overall_color,
const LColor &overall_color) {
2546 if (egg_prim->
is_of_type(EggPolygon::get_class_type())) {
2547 if (egg_prim->size() == 3) {
2551 }
else if (egg_prim->
is_of_type(EggTriangleStrip::get_class_type())) {
2554 }
else if (egg_prim->
is_of_type(EggTriangleFan::get_class_type())) {
2557 }
else if (egg_prim->
is_of_type(EggLine::get_class_type())) {
2558 if (egg_prim->size() == 2) {
2559 primitive =
new GeomLines(Geom::UH_static);
2564 }
else if (egg_prim->
is_of_type(EggPoint::get_class_type())) {
2567 }
else if (egg_prim->
is_of_type(EggPatch::get_class_type())) {
2568 int num_vertices = egg_prim->size();
2569 primitive =
new GeomPatches(num_vertices, Geom::UH_static);
2572 if (primitive ==
nullptr) {
2574 egg2pg_cat.warning()
2575 <<
"Ignoring " << egg_prim->get_type() <<
"\n";
2579 if (render_state->_flat_shaded) {
2580 primitive->set_shade_model(GeomPrimitive::SM_flat_first_vertex);
2582 }
else if (egg_prim->
get_shading() == EggPrimitive::S_overall) {
2583 primitive->set_shade_model(GeomPrimitive::SM_uniform);
2586 primitive->set_shade_model(GeomPrimitive::SM_smooth);
2591 PrimitiveUnifier pu(primitive);
2592 std::pair<UniquePrimitives::iterator, bool> result =
2593 unique_primitives.insert(UniquePrimitives::value_type(pu, primitive));
2595 if (result.second) {
2597 primitives.push_back(primitive);
2599 if (egg2pg_cat.is_debug()) {
2601 <<
"First primitive of type " << primitive->get_type()
2602 <<
": " << primitive <<
"\n";
2610 if (orig_prim->
get_num_vertices() + egg_prim->size() <= (
unsigned int)egg_max_indices) {
2611 primitive = orig_prim;
2613 }
else if (orig_prim != primitive) {
2615 (*result.first).second = primitive;
2617 if (egg2pg_cat.is_debug()) {
2619 <<
"Next primitive of type " << primitive->get_type()
2620 <<
": " << primitive <<
"\n";
2622 primitives.push_back(primitive);
2626 EggPrimitive::const_iterator vi;
2627 for (vi = egg_prim->begin(); vi != egg_prim->end(); ++vi) {
2628 primitive->add_vertex((*vi)->get_index());
2630 primitive->close_primitive();
2640 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2641 if (poly !=
nullptr) {
2644 EggPolygon::const_iterator vi;
2645 for (vi = poly->begin(); vi != poly->end(); ++vi) {
2646 LVertexd vert = (*vi)->
get_pos3() * mat;
2657 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2658 if (poly !=
nullptr) {
2659 if (poly->size() != 4) {
2661 <<
"Invalid number of vertices for " << egg_group->get_name() <<
"\n";
2665 LPoint3d v0 = (*poly)[0]->get_pos3() * mat;
2666 LPoint3d v1 = (*poly)[1]->get_pos3() * mat;
2667 LPoint3d v2 = (*poly)[2]->get_pos3() * mat;
2668 LPoint3d v3 = (*poly)[3]->get_pos3() * mat;
2670 LCAST(PN_stdfloat, v1),
2671 LCAST(PN_stdfloat, v2),
2672 LCAST(PN_stdfloat, v3));
2685 find_first_polygon(
EggGroup *egg_group) {
2687 EggGroup::const_iterator ci;
2688 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2689 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2696 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2697 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2699 PT(
EggPolygon) found = find_first_polygon(child_group);
2700 if (found !=
nullptr) {
2716 make_sphere(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2717 LPoint3 ¢er, PN_stdfloat &radius, LColor &color) {
2718 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2719 if (geom_group !=
nullptr) {
2723 EggGroup::const_iterator ci;
2724 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2725 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2727 EggPrimitive::const_iterator pi;
2728 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2729 vertices.insert(*pi);
2735 int num_vertices = 0;
2736 LPoint3d d_center(0.0, 0.0, 0.0);
2739 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2745 if (num_vertices > 0) {
2746 d_center /= (double)num_vertices;
2750 double radius2 = 0.0;
2751 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2754 LVector3d v = p3 - d_center;
2755 radius2 = max(radius2, v.length_squared());
2758 center = LCAST(PN_stdfloat, d_center);
2759 radius = sqrtf(radius2);
2762 vi = vertices.begin();
2776 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2777 const LMatrix4 &xform, LPoint3 &min_p, LPoint3 &max_p) {
2778 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2779 if (geom_group !=
nullptr) {
2783 EggGroup::const_iterator ci;
2784 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2785 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2787 EggPrimitive::const_iterator pi;
2788 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2789 vertices.insert(*pi);
2796 vi = vertices.begin();
2798 if (vi == vertices.end()) {
2806 LPoint3 min_pd = LCAST(PN_stdfloat, vertex->
get_pos3()) * xform;
2807 LPoint3 max_pd = min_pd;
2809 for (++vi; vi != vertices.end(); ++vi) {
2811 LPoint3 pos = LCAST(PN_stdfloat, vertex->
get_pos3()) * xform;
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]));
2822 return (min_pd != max_pd);
2832 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2833 LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
2835 color.set(1.0, 1.0, 1.0, 1.0);
2836 return make_box(egg_group, flags, LMatrix4::ident_mat(), min_p, max_p);
2846 if (egg_group->get_cs_type() != EggGroup::CST_none) {
2847 start_group = egg_group;
2850 switch (start_group->get_cs_type()) {
2851 case EggGroup::CST_none:
2855 case EggGroup::CST_plane:
2856 make_collision_plane(egg_group, cnode, start_group->get_collide_flags());
2859 case EggGroup::CST_polygon:
2860 make_collision_polygon(egg_group, cnode, start_group->get_collide_flags());
2863 case EggGroup::CST_polyset:
2864 make_collision_polyset(egg_group, cnode, start_group->get_collide_flags());
2867 case EggGroup::CST_sphere:
2868 make_collision_sphere(egg_group, cnode, start_group->get_collide_flags());
2871 case EggGroup::CST_box:
2872 make_collision_box(egg_group, cnode, start_group->get_collide_flags());
2875 case EggGroup::CST_inv_sphere:
2876 make_collision_inv_sphere(egg_group, cnode, start_group->get_collide_flags());
2879 case EggGroup::CST_tube:
2880 make_collision_capsule(egg_group, cnode, start_group->get_collide_flags());
2883 case EggGroup::CST_floor_mesh:
2884 make_collision_floor_mesh(egg_group, cnode, start_group->get_collide_flags());
2888 if ((start_group->get_collide_flags() & EggGroup::CF_descend) != 0) {
2890 EggGroup::const_iterator ci;
2891 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2892 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2893 make_collision_solids(start_group, DCAST(
EggGroup, *ci), cnode);
2897 egg2pg_cat.warning()
2898 <<
"Using <Collide> without 'descend' is deprecated. 'descend' " 2899 <<
"will become the default in a future version of Panda3D.\n";
2909 EggGroup::CollideFlags flags) {
2910 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2911 if (geom_group !=
nullptr) {
2912 EggGroup::const_iterator ci;
2913 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2914 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2916 create_collision_plane(DCAST(
EggPolygon, *ci), egg_group);
2917 if (csplane !=
nullptr) {
2918 apply_collision_flags(csplane, flags);
2919 csplane->
xform(cnode->get_transform()->get_mat());
2923 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
2927 make_collision_plane(temp_group, cnode, flags);
2943 EggGroup::CollideFlags flags) {
2945 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2948 if (geom_group !=
nullptr) {
2949 create_collision_floor_mesh(cnode, geom_group,flags);
2959 EggGroup::CollideFlags flags) {
2961 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2962 if (geom_group !=
nullptr) {
2963 EggGroup::const_iterator ci;
2964 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2965 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2966 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
2968 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
2972 make_collision_polygon(temp_group, cnode, flags);
2987 EggGroup::CollideFlags flags) {
2988 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2989 if (geom_group !=
nullptr) {
2990 EggGroup::const_iterator ci;
2991 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2992 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2993 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
2995 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
2999 make_collision_polyset(temp_group, cnode, flags);
3012 EggGroup::CollideFlags flags) {
3016 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3019 apply_collision_flags(cssphere, flags);
3020 cssphere->xform(cnode->get_transform()->get_mat());
3031 EggGroup::CollideFlags flags) {
3035 if (make_box(egg_group, flags, transform->get_mat(), min_p, max_p)) {
3038 apply_collision_flags(csbox, flags);
3049 EggGroup::CollideFlags flags) {
3053 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3056 apply_collision_flags(cssphere, flags);
3057 cssphere->xform(cnode->get_transform()->get_mat());
3068 EggGroup::CollideFlags flags) {
3069 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3070 if (geom_group !=
nullptr) {
3074 EggGroup::const_iterator ci;
3075 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3076 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
3078 EggPrimitive::const_iterator pi;
3079 for (pi = prim->begin(); pi != prim->end(); ++pi) {
3080 vertices.insert(*pi);
3087 size_t num_vertices = vertices.size();
3088 if (num_vertices != 0) {
3090 vpos.reserve(num_vertices);
3092 LPoint3d center(0.0, 0.0, 0.0);
3094 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
3096 const LPoint3d &pos = vtx->
get_pos3();
3097 vpos.push_back(pos);
3100 center /= (double)num_vertices;
3106 double radius2 = 0.0;
3107 LPoint3d far_a = center;
3108 for (i = 0; i < num_vertices; i++) {
3109 double dist2 = (vpos[i] - center).length_squared();
3110 if (dist2 > radius2) {
3120 LPoint3d far_b = center;
3121 for (i = 0; i < num_vertices; i++) {
3122 double dist2 = (vpos[i] - far_a).length_squared();
3123 if (dist2 > radius2) {
3140 LPoint3d cap_a_center(0.0, 0.0, 0.0);
3141 LPoint3d cap_b_center(0.0, 0.0, 0.0);
3147 double center_length = (far_a - far_b).length() / 4.0;
3148 double center_length2 = center_length * center_length;
3150 for (i = 0; i < num_vertices; i++) {
3151 double dist2 = (vpos[i] - center).length_squared();
3152 if (dist2 > center_length2) {
3155 double dist_a2 = (vpos[i] - far_a).length_squared();
3156 double dist_b2 = (vpos[i] - far_b).length_squared();
3157 if (dist_a2 < dist_b2) {
3159 cap_a_center += vpos[i];
3163 cap_b_center += vpos[i];
3169 if (num_a > 0 && num_b > 0) {
3170 cap_a_center /= (double)num_a;
3171 cap_b_center /= (double)num_b;
3175 LVector3d axis = cap_b_center - cap_a_center;
3180 if (IS_THRESHOLD_ZERO(axis[0], 0.01)) {
3183 if (IS_THRESHOLD_ZERO(axis[1], 0.01)) {
3186 if (IS_THRESHOLD_ZERO(axis[2], 0.01)) {
3198 look_at(mat, axis, LVector3d(0.0, 0.0, 1.0), CS_zup_right);
3199 mat.set_row(3, center);
3201 inv_mat.invert_from(mat);
3203 for (i = 0; i < num_vertices; i++) {
3204 vpos[i] = vpos[i] * inv_mat;
3207 double max_radius2 = 0.0;
3210 for (i = 0; i < num_vertices; i++) {
3211 LVector2d v(vpos[i][0], vpos[i][2]);
3212 double radius2 = v.length_squared();
3213 if (radius2 > max_radius2) {
3214 max_radius2 = radius2;
3224 for (i = 0; i < num_vertices; i++) {
3225 LVector2d v(vpos[i][0], vpos[i][2]);
3226 double radius2 = v.length_squared();
3228 if (vpos[i][1] < min_y) {
3231 double factor = sqrt(max_radius2 - radius2);
3232 min_y = min(min_y, vpos[i][1] + factor);
3234 }
else if (vpos[i][1] > max_y) {
3235 double factor = sqrt(max_radius2 - radius2);
3236 max_y = max(max_y, vpos[i][1] - factor);
3240 double length = max_y - min_y;
3241 double radius = sqrt(max_radius2);
3244 LVector3d half = axis * (length / 2.0);
3245 LPoint3d point_a = center - half;
3246 LPoint3d point_b = center + half;
3249 new CollisionCapsule(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
3251 apply_collision_flags(cscapsule, flags);
3252 cscapsule->xform(cnode->get_transform()->get_mat());
3264 apply_collision_flags(
CollisionSolid *solid, EggGroup::CollideFlags flags) {
3265 if ((flags & EggGroup::CF_intangible) != 0) {
3268 if ((flags & EggGroup::CF_level) != 0) {
3278 find_collision_geometry(
EggGroup *egg_group, EggGroup::CollideFlags flags) {
3279 if ((flags & EggGroup::CF_descend) != 0) {
3286 EggGroup::const_iterator ci;
3287 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3288 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3296 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3297 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
3299 if (child_group->get_cs_type() == egg_group->get_cs_type()) {
3316 <<
"Ignoring degenerate collision plane in " << parent_group->get_name()
3322 egg2pg_cat.warning()
3323 <<
"Non-planar polygon defining collision plane in " 3324 << parent_group->get_name()
3329 if (!egg_poly->empty()) {
3330 EggPolygon::const_iterator vi;
3331 vi = egg_poly->begin();
3333 LVertexd vert = (*vi)->get_pos3();
3334 vertices.push_back(LCAST(PN_stdfloat, vert));
3336 LVertexd last_vert = vert;
3338 while (vi != egg_poly->end()) {
3339 vert = (*vi)->get_pos3();
3340 if (!vert.almost_equal(last_vert)) {
3341 vertices.push_back(LCAST(PN_stdfloat, vert));
3349 if (vertices.size() < 3) {
3352 LPlane plane(vertices[0], vertices[1], vertices[2]);
3363 EggGroup::CollideFlags flags) {
3369 <<
"Ignoring degenerate collision polygon in " 3370 << parent_group->get_name()
3375 if (group->size() != 1) {
3377 <<
"Triangulating concave or non-planar collision polygon in " 3378 << parent_group->get_name()
3382 EggGroup::iterator ci;
3383 for (ci = group->begin(); ci != group->end(); ++ci) {
3387 if (!poly->empty()) {
3388 EggPolygon::const_iterator vi;
3391 LVertexd vert = (*vi)->get_pos3();
3392 vertices.push_back(LCAST(PN_stdfloat, vert));
3394 LVertexd last_vert = vert;
3396 while (vi != poly->end()) {
3397 vert = (*vi)->get_pos3();
3398 if (!vert.almost_equal(last_vert)) {
3399 vertices.push_back(LCAST(PN_stdfloat, vert));
3407 if (vertices.size() >= 3) {
3408 const LVertex *vertices_begin = &vertices[0];
3409 const LVertex *vertices_end = vertices_begin + vertices.size();
3412 if (cspoly->is_valid()) {
3413 apply_collision_flags(cspoly, flags);
3414 cspoly->xform(cnode->get_transform()->get_mat());
3428 EggGroup::CollideFlags flags) {
3432 pool.local_object();
3433 EggGroup::const_iterator egi;
3434 for (egi = parent_group->begin(); egi != parent_group->end(); ++egi) {
3435 if ((*egi)->is_of_type(EggPolygon::get_class_type())) {
3439 <<
"Ignoring degenerate collision polygon in " 3440 << parent_group->get_name()
3447 if(group->size() == 0) {
3449 <<
"empty collision solid\n";
3455 EggGroup::iterator ci;
3456 for (ci = group->begin(); ci != group->end(); ++ci) {
3458 if (poly->get_num_vertices() == 3) {
3459 CollisionFloorMesh::TriangleIndices tri;
3462 tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
3463 tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
3464 tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
3466 triangles.push_back(tri);
3467 }
else if (poly->get_num_vertices() == 4) {
3470 CollisionFloorMesh::TriangleIndices tri;
3471 CollisionFloorMesh::TriangleIndices tri2;
3474 tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
3475 tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
3476 tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
3478 triangles.push_back(tri);
3483 tri2.p3=pool.create_unique_vertex(*poly->
get_vertex(3))->get_index();
3486 triangles.push_back(tri2);
3495 for (vi = pool.begin(); vi != pool.end(); vi++) {
3496 csfloor->add_vertex(LCAST(PN_stdfloat,(*vi)->get_pos3()));
3501 for (ti = triangles.begin(); ti != triangles.end(); ti++) {
3502 CollisionFloorMesh::TriangleIndices triangle = *ti;
3503 csfloor->add_triangle(triangle.p1, triangle.p2, triangle.p3);
3505 csfloor->xform(cnode->get_transform()->get_mat());
3519 DeferredNodes::const_iterator dni;
3520 dni = _deferred_nodes.find(node);
3522 if (dni != _deferred_nodes.end()) {
3528 next_prop.apply_to_node(node);
3531 for (
int i = 0; i < num_children; i++) {
3532 apply_deferred_nodes(node->
get_child(i), next_prop);
3545 expand_all_object_types(
EggNode *egg_node) {
3546 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
3549 if (egg_group->get_num_object_types() != 0) {
3552 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3560 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
3562 EggGroupNode::const_iterator ci;
3563 ci = egg_group_node->begin();
3564 while (ci != egg_group_node->end()) {
3565 EggGroupNode::const_iterator cnext = ci;
3568 if (!expand_all_object_types(*ci)) {
3570 egg_group_node->erase(ci);
3591 int num_object_types = egg_group->get_num_object_types();
3594 vector_string object_types;
3596 for (i = 0; i < num_object_types; i++) {
3597 object_types.push_back(egg_group->get_object_type(i));
3599 egg_group->clear_object_types();
3601 for (i = 0; i < num_object_types; i++) {
3602 string object_type = object_types[i];
3606 if (!new_expanded.insert(object_type).second) {
3608 <<
"Cycle in ObjectType expansions:\n";
3610 for (pi = expanded_history.begin();
3611 pi != expanded_history.end();
3613 egg2pg_cat.error(
false)
3616 egg2pg_cat.error(
false) << object_type <<
"\n";
3622 new_expanded_history.push_back(object_type);
3624 if (!do_expand_object_type(egg_group, new_expanded,
3625 new_expanded_history, object_type)) {
3641 const string &object_type) {
3646 (
"egg-object-type-" +
downcase(object_type),
"");
3647 string egg_syntax = egg_object_type;
3649 if (!egg_object_type.has_value()) {
3652 if (cmp_nocase_uh(object_type,
"barrier") == 0) {
3653 egg_syntax =
"<Collide> { Polyset descend }";
3655 }
else if (cmp_nocase_uh(object_type,
"solidpoly") == 0) {
3656 egg_syntax =
"<Collide> { Polyset descend solid }";
3658 }
else if (cmp_nocase_uh(object_type,
"turnstile") == 0) {
3659 egg_syntax =
"<Collide> { Polyset descend turnstile }";
3661 }
else if (cmp_nocase_uh(object_type,
"sphere") == 0) {
3662 egg_syntax =
"<Collide> { Sphere descend }";
3664 }
else if (cmp_nocase_uh(object_type,
"tube") == 0) {
3665 egg_syntax =
"<Collide> { Tube descend }";
3667 }
else if (cmp_nocase_uh(object_type,
"trigger") == 0) {
3668 egg_syntax =
"<Collide> { Polyset descend intangible }";
3670 }
else if (cmp_nocase_uh(object_type,
"trigger_sphere") == 0) {
3671 egg_syntax =
"<Collide> { Sphere descend intangible }";
3673 }
else if (cmp_nocase_uh(object_type,
"eye_trigger") == 0) {
3674 egg_syntax =
"<Collide> { Polyset descend intangible center }";
3676 }
else if (cmp_nocase_uh(object_type,
"bubble") == 0) {
3677 egg_syntax =
"<Collide> { Sphere keep descend }";
3679 }
else if (cmp_nocase_uh(object_type,
"ghost") == 0) {
3680 egg_syntax =
"<Scalar> collide-mask { 0 }";
3682 }
else if (cmp_nocase_uh(object_type,
"dcs") == 0) {
3683 egg_syntax =
"<DCS> { 1 }";
3685 }
else if (cmp_nocase_uh(object_type,
"model") == 0) {
3686 egg_syntax =
"<Model> { 1 }";
3688 }
else if (cmp_nocase_uh(object_type,
"none") == 0) {
3692 }
else if (cmp_nocase_uh(object_type,
"backstage") == 0) {
3698 <<
"Unknown ObjectType " << object_type <<
"\n";
3700 egg2pg_cat.debug() <<
"returning true\n";
3705 if (!egg_syntax.empty()) {
3706 if (!egg_group->
parse_egg(egg_syntax)) {
3708 <<
"Error while parsing definition for ObjectType " 3709 << object_type <<
"\n";
3715 if (egg_group->get_num_object_types() != 0) {
3716 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3730 TextureStage::CombineMode EggLoader::
3732 EggTexture::CombineChannel channel) {
3733 switch (egg_tex->get_combine_mode(channel)) {
3734 case EggTexture::CM_unspecified:
3737 case EggTexture::CM_modulate:
3738 return TextureStage::CM_modulate;
3740 case EggTexture::CM_replace:
3741 return TextureStage::CM_replace;
3743 case EggTexture::CM_add:
3744 return TextureStage::CM_add;
3746 case EggTexture::CM_add_signed:
3747 return TextureStage::CM_add_signed;
3749 case EggTexture::CM_interpolate:
3750 return TextureStage::CM_interpolate;
3752 case EggTexture::CM_subtract:
3753 return TextureStage::CM_subtract;
3755 case EggTexture::CM_dot3_rgb:
3756 return TextureStage::CM_dot3_rgb;
3758 case EggTexture::CM_dot3_rgba:
3759 return TextureStage::CM_dot3_rgba;
3762 return TextureStage::CM_undefined;
3769 TextureStage::CombineSource EggLoader::
3770 get_combine_source(
const EggTexture *egg_tex,
3771 EggTexture::CombineChannel channel,
int n) {
3772 switch (egg_tex->get_combine_source(channel, n)) {
3773 case EggTexture::CS_unspecified:
3778 return TextureStage::CS_previous;
3780 return TextureStage::CS_texture;
3782 return TextureStage::CS_constant;
3786 case EggTexture::CS_texture:
3787 return TextureStage::CS_texture;
3789 case EggTexture::CS_constant:
3790 return TextureStage::CS_constant;
3792 case EggTexture::CS_primary_color:
3793 return TextureStage::CS_primary_color;
3795 case EggTexture::CS_previous:
3796 return TextureStage::CS_previous;
3798 case EggTexture::CS_constant_color_scale:
3799 return TextureStage::CS_constant_color_scale;
3801 case EggTexture::CS_last_saved_result:
3802 return TextureStage::CS_last_saved_result;
3805 return TextureStage::CS_undefined;
3812 TextureStage::CombineOperand EggLoader::
3813 get_combine_operand(
const EggTexture *egg_tex,
3814 EggTexture::CombineChannel channel,
int n) {
3815 switch (egg_tex->get_combine_operand(channel, n)) {
3816 case EggTexture::CO_unspecified:
3817 if (channel == EggTexture::CC_rgb) {
3820 return n < 2 ? TextureStage::CO_src_color : TextureStage::CO_src_alpha;
3823 return TextureStage::CO_src_alpha;
3826 case EggTexture::CO_src_color:
3827 return TextureStage::CO_src_color;
3829 case EggTexture::CO_one_minus_src_color:
3830 return TextureStage::CO_one_minus_src_color;
3832 case EggTexture::CO_src_alpha:
3833 return TextureStage::CO_src_alpha;
3835 case EggTexture::CO_one_minus_src_alpha:
3836 return TextureStage::CO_one_minus_src_alpha;
3839 return TextureStage::CO_undefined;
3846 ColorBlendAttrib::Mode EggLoader::
3847 get_color_blend_mode(EggGroup::BlendMode mode) {
3849 case EggGroup::BM_unspecified:
3850 case EggGroup::BM_none:
3851 return ColorBlendAttrib::M_none;
3852 case EggGroup::BM_add:
3853 return ColorBlendAttrib::M_add;
3854 case EggGroup::BM_subtract:
3855 return ColorBlendAttrib::M_subtract;
3856 case EggGroup::BM_inv_subtract:
3857 return ColorBlendAttrib::M_inv_subtract;
3858 case EggGroup::BM_min:
3859 return ColorBlendAttrib::M_min;
3860 case EggGroup::BM_max:
3861 return ColorBlendAttrib::M_max;
3864 return ColorBlendAttrib::M_none;
3871 ColorBlendAttrib::Operand EggLoader::
3872 get_color_blend_operand(EggGroup::BlendOperand operand) {
3874 case EggGroup::BO_zero:
3875 return ColorBlendAttrib::O_zero;
3876 case EggGroup::BO_unspecified:
3877 case EggGroup::BO_one:
3878 return ColorBlendAttrib::O_one;
3879 case EggGroup::BO_incoming_color:
3880 return ColorBlendAttrib::O_incoming_color;
3881 case EggGroup::BO_one_minus_incoming_color:
3882 return ColorBlendAttrib::O_one_minus_incoming_color;
3883 case EggGroup::BO_fbuffer_color:
3884 return ColorBlendAttrib::O_fbuffer_color;
3885 case EggGroup::BO_one_minus_fbuffer_color:
3886 return ColorBlendAttrib::O_one_minus_fbuffer_color;
3887 case EggGroup::BO_incoming_alpha:
3888 return ColorBlendAttrib::O_incoming_alpha;
3889 case EggGroup::BO_one_minus_incoming_alpha:
3890 return ColorBlendAttrib::O_one_minus_incoming_alpha;
3891 case EggGroup::BO_fbuffer_alpha:
3892 return ColorBlendAttrib::O_fbuffer_alpha;
3893 case EggGroup::BO_one_minus_fbuffer_alpha:
3894 return ColorBlendAttrib::O_one_minus_fbuffer_alpha;
3895 case EggGroup::BO_constant_color:
3896 return ColorBlendAttrib::O_constant_color;
3897 case EggGroup::BO_one_minus_constant_color:
3898 return ColorBlendAttrib::O_one_minus_constant_color;
3899 case EggGroup::BO_constant_alpha:
3900 return ColorBlendAttrib::O_constant_alpha;
3901 case EggGroup::BO_one_minus_constant_alpha:
3902 return ColorBlendAttrib::O_one_minus_constant_alpha;
3903 case EggGroup::BO_incoming_color_saturate:
3904 return ColorBlendAttrib::O_incoming_color_saturate;
3905 case EggGroup::BO_color_scale:
3906 return ColorBlendAttrib::O_color_scale;
3907 case EggGroup::BO_one_minus_color_scale:
3908 return ColorBlendAttrib::O_one_minus_color_scale;
3909 case EggGroup::BO_alpha_scale:
3910 return ColorBlendAttrib::O_alpha_scale;
3911 case EggGroup::BO_one_minus_alpha_scale:
3912 return ColorBlendAttrib::O_one_minus_alpha_scale;
3915 return ColorBlendAttrib::O_zero;
3921 bool EggLoader::VertexPoolTransform::
3922 operator < (
const EggLoader::VertexPoolTransform &other)
const {
3923 if (_vertex_pool != other._vertex_pool) {
3924 return _vertex_pool < other._vertex_pool;
3926 int compare = _transform.compare_to(other._transform, 0.001);
3931 if (_bake_in_uvs.size() != other._bake_in_uvs.size()) {
3932 return _bake_in_uvs.size() < other._bake_in_uvs.size();
3935 BakeInUVs::const_iterator ai, bi;
3936 ai = _bake_in_uvs.begin();
3937 bi = other._bake_in_uvs.begin();
3938 while (ai != _bake_in_uvs.end()) {
3939 nassertr(bi != other._bake_in_uvs.end(),
false);
3940 if ((*ai) != (*bi)) {
3941 return (*ai) < (*bi);
3946 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.
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
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.