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) {
695 rope->set_curve(nurbs);
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);
734 const LMatrix4d &mat) {
735 assert(parent !=
nullptr);
742 nassertv(nurbs !=
nullptr);
746 <<
"Invalid NURBSCurve order for " << egg_curve->get_name() <<
": "
752 nurbs->set_order(egg_curve->
get_order());
754 EggPrimitive::const_iterator pi;
755 for (pi = egg_curve->begin(); pi != egg_curve->end(); ++pi) {
756 nurbs->append_cv(LCAST(PN_stdfloat, (*pi)->get_pos4() * mat));
760 if (num_knots != nurbs->get_num_knots()) {
762 <<
"Invalid NURBSCurve number of knots for "
763 << egg_curve->get_name() <<
": got " << num_knots
764 <<
" knots, expected " << nurbs->get_num_knots() <<
"\n";
769 for (
int i = 0; i < num_knots; i++) {
770 nurbs->set_knot(i, egg_curve->
get_knot(i));
774 case EggCurve::CT_xyz:
775 curve->set_curve_type(PCT_XYZ);
778 case EggCurve::CT_hpr:
779 curve->set_curve_type(PCT_HPR);
783 curve->set_curve_type(PCT_T);
789 curve->set_name(egg_curve->get_name());
791 if (!curve->recompute()) {
793 <<
"Invalid NURBSCurve " << egg_curve->get_name() <<
"\n";
798 parent->add_child(curve);
806 const LMatrix4d &mat) {
807 assert(parent !=
nullptr);
811 if (nurbs ==
nullptr) {
817 sheet->set_surface(nurbs);
821 int u_subdiv_per_segment =
822 (int)((egg_surface->
get_u_subdiv() + 0.5) / nurbs->get_num_u_segments());
823 sheet->set_num_u_subdiv(max(u_subdiv_per_segment, 1));
826 int v_subdiv_per_segment =
827 (int)((egg_surface->
get_v_subdiv() + 0.5) / nurbs->get_num_v_segments());
828 sheet->set_num_v_subdiv(max(v_subdiv_per_segment, 1));
832 DCAST_INTO_V(render_state, egg_surface->
get_user_data(EggRenderState::get_class_type()));
833 if (render_state->_hidden && egg_suppress_hidden) {
838 sheet->set_state(render_state->_state);
842 sheet->set_use_vertex_color(
true);
843 }
else if (egg_surface->has_color()) {
845 sheet->set_attrib(ColorAttrib::make_flat(egg_surface->
get_color()));
848 parent->add_child(sheet);
860 EggTextureCollection::iterator ti;
861 for (ti = tc.begin(); ti != tc.end(); ++ti) {
862 PT_EggTexture egg_tex = (*ti);
865 if (load_texture(def, egg_tex)) {
868 _textures[egg_tex] = def;
878 load_texture(TextureDef &def,
EggTexture *egg_tex) {
880 int wanted_channels = 0;
881 bool wanted_alpha =
false;
882 switch (egg_tex->get_format()) {
883 case EggTexture::F_red:
884 case EggTexture::F_green:
885 case EggTexture::F_blue:
886 case EggTexture::F_alpha:
887 case EggTexture::F_luminance:
889 wanted_alpha =
false;
892 case EggTexture::F_luminance_alpha:
893 case EggTexture::F_luminance_alphamask:
898 case EggTexture::F_rgb:
899 case EggTexture::F_rgb12:
900 case EggTexture::F_rgb8:
901 case EggTexture::F_rgb5:
902 case EggTexture::F_rgb332:
904 wanted_alpha =
false;
907 case EggTexture::F_rgba:
908 case EggTexture::F_rgbm:
909 case EggTexture::F_rgba12:
910 case EggTexture::F_rgba8:
911 case EggTexture::F_rgba4:
912 case EggTexture::F_rgba5:
917 case EggTexture::F_unspecified:
924 if (_record !=
nullptr) {
933 if (egg_preload_simple_textures) {
934 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_preload_simple);
937 if (!egg_ignore_filters && !egg_ignore_mipmaps) {
938 switch (egg_tex->get_minfilter()) {
939 case EggTexture::FT_nearest:
940 case EggTexture::FT_linear:
941 case EggTexture::FT_unspecified:
944 case EggTexture::FT_nearest_mipmap_nearest:
945 case EggTexture::FT_linear_mipmap_nearest:
946 case EggTexture::FT_nearest_mipmap_linear:
947 case EggTexture::FT_linear_mipmap_linear:
948 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_generate_mipmaps);
953 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_multiview);
960 if (egg_tex->get_compression_mode() == EggTexture::CM_on) {
961 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_compression);
965 switch (egg_tex->get_texture_type()) {
966 case EggTexture::TT_unspecified:
967 case EggTexture::TT_1d_texture:
968 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_1d);
971 case EggTexture::TT_2d_texture:
985 case EggTexture::TT_3d_texture:
990 case EggTexture::TT_cube_map:
996 if (tex ==
nullptr) {
1011 if (aux !=
nullptr &&
1012 aux->
is_of_type(EggTexture::get_class_type())) {
1015 if (aux_egg_tex->
get_alpha_mode() != EggTexture::AM_unspecified) {
1018 if (aux_egg_tex->get_format() != EggTexture::F_unspecified) {
1019 egg_tex->set_format(aux_egg_tex->get_format());
1021 if (aux_egg_tex->get_minfilter() != EggTexture::FT_unspecified) {
1022 egg_tex->set_minfilter(aux_egg_tex->get_minfilter());
1024 if (aux_egg_tex->get_magfilter() != EggTexture::FT_unspecified) {
1025 egg_tex->set_magfilter(aux_egg_tex->get_magfilter());
1032 apply_texture_attributes(tex, egg_tex);
1036 def._texture = DCAST(
TextureAttrib, TextureAttrib::make())->add_on_stage(stage, tex);
1038 def._egg_tex = egg_tex;
1049 if (egg_tex->get_compression_mode() != EggTexture::CM_default) {
1050 tex->
set_compression(convert_compression_mode(egg_tex->get_compression_mode()));
1059 if (wrap_u != EggTexture::WM_unspecified) {
1060 sampler.
set_wrap_u(convert_wrap_mode(wrap_u));
1062 if (wrap_v != EggTexture::WM_unspecified) {
1063 sampler.
set_wrap_v(convert_wrap_mode(wrap_v));
1065 if (wrap_w != EggTexture::WM_unspecified) {
1066 sampler.
set_wrap_w(convert_wrap_mode(wrap_w));
1073 switch (egg_tex->get_minfilter()) {
1074 case EggTexture::FT_nearest:
1078 case EggTexture::FT_linear:
1079 if (egg_ignore_filters) {
1080 egg2pg_cat.warning()
1081 <<
"Ignoring minfilter request\n";
1088 case EggTexture::FT_nearest_mipmap_nearest:
1089 if (egg_ignore_filters) {
1090 egg2pg_cat.warning()
1091 <<
"Ignoring minfilter request\n";
1093 }
else if (egg_ignore_mipmaps) {
1094 egg2pg_cat.warning()
1095 <<
"Ignoring mipmap request\n";
1098 sampler.
set_minfilter(SamplerState::FT_nearest_mipmap_nearest);
1102 case EggTexture::FT_linear_mipmap_nearest:
1103 if (egg_ignore_filters) {
1104 egg2pg_cat.warning()
1105 <<
"Ignoring minfilter request\n";
1107 }
else if (egg_ignore_mipmaps) {
1108 egg2pg_cat.warning()
1109 <<
"Ignoring mipmap request\n";
1112 sampler.
set_minfilter(SamplerState::FT_linear_mipmap_nearest);
1116 case EggTexture::FT_nearest_mipmap_linear:
1117 if (egg_ignore_filters) {
1118 egg2pg_cat.warning()
1119 <<
"Ignoring minfilter request\n";
1121 }
else if (egg_ignore_mipmaps) {
1122 egg2pg_cat.warning()
1123 <<
"Ignoring mipmap request\n";
1126 sampler.
set_minfilter(SamplerState::FT_nearest_mipmap_linear);
1130 case EggTexture::FT_linear_mipmap_linear:
1131 if (egg_ignore_filters) {
1132 egg2pg_cat.warning()
1133 <<
"Ignoring minfilter request\n";
1135 }
else if (egg_ignore_mipmaps) {
1136 egg2pg_cat.warning()
1137 <<
"Ignoring mipmap request\n";
1140 sampler.
set_minfilter(SamplerState::FT_linear_mipmap_linear);
1144 case EggTexture::FT_unspecified:
1148 switch (egg_tex->get_magfilter()) {
1149 case EggTexture::FT_nearest:
1150 case EggTexture::FT_nearest_mipmap_nearest:
1151 case EggTexture::FT_nearest_mipmap_linear:
1155 case EggTexture::FT_linear:
1156 case EggTexture::FT_linear_mipmap_nearest:
1157 case EggTexture::FT_linear_mipmap_linear:
1158 if (egg_ignore_filters) {
1159 egg2pg_cat.warning()
1160 <<
"Ignoring magfilter request\n";
1167 case EggTexture::FT_unspecified:
1190 switch (egg_tex->get_format()) {
1191 case EggTexture::F_red:
1194 case EggTexture::F_green:
1197 case EggTexture::F_blue:
1200 case EggTexture::F_alpha:
1203 case EggTexture::F_luminance:
1207 case EggTexture::F_unspecified:
1211 egg2pg_cat.warning()
1212 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1213 <<
" for 1-component texture " << egg_tex->get_name() <<
"\n";
1217 switch (egg_tex->get_format()) {
1218 case EggTexture::F_luminance_alpha:
1222 case EggTexture::F_luminance_alphamask:
1223 tex->
set_format(Texture::F_luminance_alphamask);
1226 case EggTexture::F_unspecified:
1230 egg2pg_cat.warning()
1231 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1232 <<
" for 2-component texture " << egg_tex->get_name() <<
"\n";
1236 switch (egg_tex->get_format()) {
1237 case EggTexture::F_rgb:
1240 case EggTexture::F_rgb12:
1245 egg2pg_cat.warning()
1246 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1247 <<
" for 8-bit texture " << egg_tex->get_name() <<
"\n";
1250 case EggTexture::F_rgb8:
1251 case EggTexture::F_rgba8:
1256 case EggTexture::F_rgb5:
1259 case EggTexture::F_rgb332:
1263 case EggTexture::F_unspecified:
1267 egg2pg_cat.warning()
1268 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1269 <<
" for 3-component texture " << egg_tex->get_name() <<
"\n";
1273 switch (egg_tex->get_format()) {
1274 case EggTexture::F_rgba:
1277 case EggTexture::F_rgbm:
1280 case EggTexture::F_rgba12:
1285 egg2pg_cat.warning()
1286 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1287 <<
" for 8-bit texture " << egg_tex->get_name() <<
"\n";
1290 case EggTexture::F_rgba8:
1293 case EggTexture::F_rgba4:
1296 case EggTexture::F_rgba5:
1300 case EggTexture::F_unspecified:
1304 egg2pg_cat.warning()
1305 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1306 <<
" for 4-component texture " << egg_tex->get_name() <<
"\n";
1310 switch (egg_tex->get_quality_level()) {
1311 case EggTexture::QL_unspecified:
1312 case EggTexture::QL_default:
1316 case EggTexture::QL_fastest:
1320 case EggTexture::QL_normal:
1324 case EggTexture::QL_best:
1335 Texture::CompressionMode EggLoader::
1336 convert_compression_mode(EggTexture::CompressionMode compression_mode)
const {
1337 switch (compression_mode) {
1338 case EggTexture::CM_off:
1339 return Texture::CM_off;
1341 case EggTexture::CM_on:
1342 return Texture::CM_on;
1344 case EggTexture::CM_fxt1:
1345 return Texture::CM_fxt1;
1347 case EggTexture::CM_dxt1:
1348 return Texture::CM_dxt1;
1350 case EggTexture::CM_dxt2:
1351 return Texture::CM_dxt2;
1353 case EggTexture::CM_dxt3:
1354 return Texture::CM_dxt3;
1356 case EggTexture::CM_dxt4:
1357 return Texture::CM_dxt4;
1359 case EggTexture::CM_dxt5:
1360 return Texture::CM_dxt5;
1362 case EggTexture::CM_default:
1363 return Texture::CM_default;
1366 egg2pg_cat.warning()
1367 <<
"Unexpected texture compression flag: " << (int)compression_mode <<
"\n";
1368 return Texture::CM_default;
1375 SamplerState::WrapMode EggLoader::
1376 convert_wrap_mode(EggTexture::WrapMode wrap_mode)
const {
1377 switch (wrap_mode) {
1378 case EggTexture::WM_clamp:
1379 return SamplerState::WM_clamp;
1381 case EggTexture::WM_repeat:
1382 return SamplerState::WM_repeat;
1384 case EggTexture::WM_mirror:
1385 return SamplerState::WM_mirror;
1387 case EggTexture::WM_mirror_once:
1388 return SamplerState::WM_mirror_once;
1390 case EggTexture::WM_border_color:
1391 return SamplerState::WM_border_color;
1393 case EggTexture::WM_unspecified:
1394 return SamplerState::WM_repeat;
1397 egg2pg_cat.warning()
1398 <<
"Unexpected texture wrap flag: " << (int)wrap_mode <<
"\n";
1399 return SamplerState::WM_repeat;
1406 make_texture_stage(
const EggTexture *egg_tex) {
1413 (egg_tex->get_env_type() == EggTexture::ET_unspecified ||
1414 egg_tex->get_env_type() == EggTexture::ET_modulate) &&
1415 egg_tex->get_combine_mode(EggTexture::CC_rgb) == EggTexture::CM_unspecified &&
1416 egg_tex->get_combine_mode(EggTexture::CC_alpha) == EggTexture::CM_unspecified &&
1426 switch (egg_tex->get_env_type()) {
1427 case EggTexture::ET_modulate:
1428 stage->set_mode(TextureStage::M_modulate);
1431 case EggTexture::ET_decal:
1432 stage->set_mode(TextureStage::M_decal);
1435 case EggTexture::ET_blend:
1436 stage->set_mode(TextureStage::M_blend);
1439 case EggTexture::ET_replace:
1440 stage->set_mode(TextureStage::M_replace);
1443 case EggTexture::ET_add:
1444 stage->set_mode(TextureStage::M_add);
1447 case EggTexture::ET_blend_color_scale:
1448 stage->set_mode(TextureStage::M_blend_color_scale);
1451 case EggTexture::ET_modulate_glow:
1452 stage->set_mode(TextureStage::M_modulate_glow);
1455 case EggTexture::ET_modulate_gloss:
1456 stage->set_mode(TextureStage::M_modulate_gloss);
1459 case EggTexture::ET_normal:
1460 stage->set_mode(TextureStage::M_normal);
1463 case EggTexture::ET_normal_height:
1464 stage->set_mode(TextureStage::M_normal_height);
1467 case EggTexture::ET_glow:
1468 stage->set_mode(TextureStage::M_glow);
1471 case EggTexture::ET_gloss:
1472 stage->set_mode(TextureStage::M_gloss);
1475 case EggTexture::ET_height:
1476 stage->set_mode(TextureStage::M_height);
1479 case EggTexture::ET_selector:
1480 stage->set_mode(TextureStage::M_selector);
1483 case EggTexture::ET_normal_gloss:
1484 stage->set_mode(TextureStage::M_normal_gloss);
1487 case EggTexture::ET_unspecified:
1491 switch (egg_tex->get_combine_mode(EggTexture::CC_rgb)) {
1492 case EggTexture::CM_replace:
1493 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1494 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1495 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0));
1498 case EggTexture::CM_modulate:
1499 case EggTexture::CM_add:
1500 case EggTexture::CM_add_signed:
1501 case EggTexture::CM_subtract:
1502 case EggTexture::CM_dot3_rgb:
1503 case EggTexture::CM_dot3_rgba:
1504 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1505 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1506 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
1507 get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
1508 get_combine_operand(egg_tex, EggTexture::CC_rgb, 1));
1511 case EggTexture::CM_interpolate:
1512 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1513 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1514 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
1515 get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
1516 get_combine_operand(egg_tex, EggTexture::CC_rgb, 1),
1517 get_combine_source(egg_tex, EggTexture::CC_rgb, 2),
1518 get_combine_operand(egg_tex, EggTexture::CC_rgb, 2));
1521 case EggTexture::CM_unspecified:
1525 switch (egg_tex->get_combine_mode(EggTexture::CC_alpha)) {
1526 case EggTexture::CM_replace:
1527 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1528 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1529 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0));
1532 case EggTexture::CM_modulate:
1533 case EggTexture::CM_add:
1534 case EggTexture::CM_add_signed:
1535 case EggTexture::CM_subtract:
1536 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1537 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1538 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
1539 get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
1540 get_combine_operand(egg_tex, EggTexture::CC_alpha, 1));
1543 case EggTexture::CM_interpolate:
1544 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1545 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1546 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
1547 get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
1548 get_combine_operand(egg_tex, EggTexture::CC_alpha, 1),
1549 get_combine_source(egg_tex, EggTexture::CC_alpha, 2),
1550 get_combine_operand(egg_tex, EggTexture::CC_alpha, 2));
1553 case EggTexture::CM_unspecified:
1554 case EggTexture::CM_dot3_rgb:
1555 case EggTexture::CM_dot3_rgba:
1562 InternalName::get_texcoord_name(egg_tex->
get_uv_name());
1563 stage->set_texcoord_name(name);
1595 separate_switches(
EggNode *egg_node) {
1596 bool parent_has_switch =
false;
1597 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
1599 parent_has_switch = egg_group->get_switch_flag();
1602 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1605 EggGroupNode::iterator ci;
1606 ci = egg_group->begin();
1607 while (ci != egg_group->end()) {
1608 EggGroupNode::iterator cnext;
1613 if (parent_has_switch &&
1614 child->is_of_type(EggPrimitive::get_class_type())) {
1617 egg_group->
replace(ci, new_group.p());
1618 new_group->add_child(child);
1621 separate_switches(child);
1634 emulate_bface(
EggNode *egg_node) {
1635 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1639 EggGroupNode::iterator ci;
1640 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1642 if (child->is_of_type(EggPolygon::get_class_type())) {
1648 dup_poly->reverse_vertex_ordering();
1649 if (dup_poly->has_normal()) {
1650 dup_poly->set_normal(-dup_poly->get_normal());
1654 EggPolygon::iterator vi;
1655 for (vi = dup_poly->begin(); vi != dup_poly->end(); ++vi) {
1657 if (vertex->has_normal()) {
1659 dup_vertex.set_normal(-dup_vertex.get_normal());
1661 if (new_vertex != vertex) {
1663 dup_poly->replace(vi, new_vertex);
1667 dup_prims->add_child(dup_poly);
1671 emulate_bface(child);
1685 if (egg_node->
is_of_type(EggBin::get_class_type())) {
1686 return make_node(DCAST(
EggBin, egg_node), parent);
1687 }
else if (egg_node->
is_of_type(EggGroup::get_class_type())) {
1688 return make_node(DCAST(
EggGroup, egg_node), parent);
1689 }
else if (egg_node->
is_of_type(EggTable::get_class_type())) {
1690 return make_node(DCAST(
EggTable, egg_node), parent);
1691 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1692 return make_node(DCAST(
EggGroupNode, egg_node), parent);
1706 switch (egg_bin->get_bin_number()) {
1707 case EggBinner::BN_polyset:
1708 case EggBinner::BN_patches:
1709 make_polyset(egg_bin, parent,
nullptr, _dynamic_override, _dynamic_override_char_maker);
1712 case EggBinner::BN_lod:
1713 return make_lod(egg_bin, parent);
1715 case EggBinner::BN_nurbs_surface:
1717 nassertr(!egg_bin->empty(),
nullptr);
1720 DCAST_INTO_R(egg_nurbs, child,
nullptr);
1722 make_nurbs_surface(egg_nurbs, parent, mat);
1726 case EggBinner::BN_nurbs_curve:
1728 nassertr(!egg_bin->empty(),
nullptr);
1731 DCAST_INTO_R(egg_nurbs, child,
nullptr);
1733 make_nurbs_curve(egg_nurbs, parent, mat);
1737 case EggBinner::BN_none:
1750 PT(
LODNode) lod_node = LODNode::make_default_lod(egg_bin->get_name());
1754 EggGroup::const_iterator ci;
1755 for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
1756 LODInstance instance(*ci);
1757 instances.push_back(instance);
1762 sort(instances.begin(), instances.end());
1764 if (!instances.empty()) {
1767 lod_node->set_center(LCAST(PN_stdfloat, instances[0]._d->_center));
1770 for (
size_t i = 0; i < instances.size(); i++) {
1772 const LODInstance &instance = instances[i];
1773 make_node(instance._egg_node, lod_node);
1777 nassertr(lod_node->get_center().almost_equal
1778 (LCAST(PN_stdfloat, instance._d->_center), 0.01),
nullptr);
1781 lod_node->add_switch(instance._d->_switch_in, instance._d->_switch_out);
1784 _groups[egg_bin] = lod_node;
1785 return create_group_arc(egg_bin, parent, lod_node);
1795 if (egg_group->get_dart_type() != EggGroup::DT_none) {
1797 bool structured = (egg_group->get_dart_type() == EggGroup::DT_structured);
1801 node = char_maker.make_node();
1805 _dynamic_override =
true;
1806 _dynamic_override_char_maker = &char_maker;
1807 EggGroup::const_iterator ci;
1808 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1809 make_node(*ci, node);
1811 _dynamic_override_char_maker =
nullptr;
1812 _dynamic_override =
false;
1815 }
else if (egg_group->get_cs_type() != EggGroup::CST_none) {
1821 node->set_transform(TransformState::make_mat(LCAST(PN_stdfloat, egg_group->
get_vertex_to_node())));
1822 make_collision_solids(egg_group, egg_group, (
CollisionNode *)node.p());
1823 node->clear_transform();
1825 if ((egg_group->get_collide_flags() & EggGroup::CF_keep) != 0) {
1830 parent->add_child(combined);
1831 combined->add_child(node);
1834 EggGroup::const_iterator ci;
1835 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1836 make_node(*ci, combined);
1840 node = create_group_arc(egg_group, parent, node);
1843 }
else if (egg_group->get_portal_flag()) {
1850 set_portal_polygon(egg_group, pnode);
1852 egg2pg_cat.warning()
1853 <<
"Portal " << egg_group->get_name() <<
" has no vertices!\n";
1856 }
else if (egg_group->get_occluder_flag()) {
1863 set_occluder_polygon(egg_group, pnode);
1865 egg2pg_cat.warning()
1866 <<
"Occluder " << egg_group->get_name() <<
" has no vertices!\n";
1869 }
else if (egg_group->get_polylight_flag()) {
1877 if (!make_sphere(egg_group, EggGroup::CF_none, center, radius, color)) {
1878 egg2pg_cat.warning()
1879 <<
"Polylight " << egg_group->get_name() <<
" make_sphere failed!\n";
1890 }
else if (egg_group->get_switch_flag()) {
1891 if (egg_group->get_switch_fps() != 0.0) {
1894 ((
SequenceNode *)node.p())->set_frame_rate(egg_group->get_switch_fps());
1895 _sequences.insert(node);
1898 node =
new SwitchNode(egg_group->get_name());
1901 EggGroup::const_iterator ci;
1902 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1903 make_node(*ci, node);
1905 }
else if (egg_group->has_scrolling_uvs()) {
1906 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());
1908 EggGroup::const_iterator ci;
1909 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1910 make_node(*ci, node);
1913 }
else if (egg_group->get_model_flag() || egg_group->
has_dcs_type()) {
1915 node =
new ModelNode(egg_group->get_name());
1916 switch (egg_group->get_dcs_type()) {
1917 case EggGroup::DC_net:
1918 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_net);
1921 case EggGroup::DC_no_touch:
1922 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_no_touch);
1925 case EggGroup::DC_local:
1926 case EggGroup::DC_default:
1927 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_local);
1930 case EggGroup::DC_none:
1931 case EggGroup::DC_unspecified:
1935 EggGroup::const_iterator ci;
1936 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1937 make_node(*ci, node);
1945 bool all_polysets =
false;
1946 bool any_hidden =
false;
1951 check_for_polysets(egg_group, all_polysets, any_hidden);
1954 if (all_polysets && !any_hidden) {
1955 node =
new GeomNode(egg_group->get_name());
1957 node =
new PandaNode(egg_group->get_name());
1960 EggGroup::const_iterator ci;
1961 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1962 make_node(*ci, node);
1966 if (node ==
nullptr) {
1972 for (
int gri = 0; gri < num_group_refs; ++gri) {
1974 Groups::const_iterator gi = _groups.find(group_ref);
1975 if (gi != _groups.end()) {
1977 node->add_child(node_ref);
1981 _groups[egg_group] = node;
1982 return create_group_arc(egg_group, parent, node);
1992 parent->add_child(node);
2002 switch (egg_group->get_billboard_type()) {
2003 case EggGroup::BT_point_camera_relative:
2004 node->
set_effect(BillboardEffect::make_point_eye());
2007 case EggGroup::BT_point_world_relative:
2008 node->
set_effect(BillboardEffect::make_point_world());
2011 case EggGroup::BT_axis:
2012 node->
set_effect(BillboardEffect::make_axis());
2015 case EggGroup::BT_none:
2019 if (egg_group->get_decal_flag()) {
2020 if (egg_ignore_decals) {
2022 <<
"Ignoring decal flag on " << egg_group->get_name() <<
"\n";
2029 _decals.insert(node);
2033 EggGroup::TagData::const_iterator ti;
2035 node->
set_tag((*ti).first, (*ti).second);
2038 if (egg_group->get_blend_mode() != EggGroup::BM_unspecified &&
2039 egg_group->get_blend_mode() != EggGroup::BM_none) {
2041 ColorBlendAttrib::Mode mode = get_color_blend_mode(egg_group->get_blend_mode());
2042 ColorBlendAttrib::Operand a = get_color_blend_operand(egg_group->get_blend_operand_a());
2043 ColorBlendAttrib::Operand b = get_color_blend_operand(egg_group->get_blend_operand_b());
2045 node->
set_attrib(ColorBlendAttrib::make(mode, a, b, color));
2052 if (egg_group->has_collide_mask()) {
2053 def._from_collide_mask = egg_group->get_collide_mask();
2054 def._into_collide_mask = egg_group->get_collide_mask();
2056 DeferredNodeProperty::F_has_from_collide_mask |
2057 DeferredNodeProperty::F_has_into_collide_mask;
2059 if (egg_group->has_from_collide_mask()) {
2060 def._from_collide_mask = egg_group->get_from_collide_mask();
2061 def._flags |= DeferredNodeProperty::F_has_from_collide_mask;
2063 if (egg_group->has_into_collide_mask()) {
2064 def._into_collide_mask = egg_group->get_into_collide_mask();
2065 def._flags |= DeferredNodeProperty::F_has_into_collide_mask;
2068 if (def._flags != 0) {
2069 _deferred_nodes[node] = def;
2080 if (egg_table->get_table_type() != EggTable::TT_bundle) {
2083 return make_node(DCAST(
EggGroupNode, egg_table), parent);
2089 parent->add_child(node);
2101 EggGroupNode::const_iterator ci;
2102 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2103 make_node(*ci, node);
2106 parent->add_child(node);
2115 check_for_polysets(
EggGroup *egg_group,
bool &all_polysets,
bool &any_hidden) {
2116 all_polysets = (!egg_group->empty());
2119 EggGroup::const_iterator ci;
2120 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2121 if ((*ci)->is_of_type(EggBin::get_class_type())) {
2123 if (egg_bin->get_bin_number() == EggBinner::BN_polyset) {
2126 EggGroup::const_iterator bci = egg_bin->begin();
2127 nassertv(bci != egg_bin->end());
2129 DCAST_INTO_V(first_prim, (*bci));
2131 DCAST_INTO_V(render_state, first_prim->
get_user_data(EggRenderState::get_class_type()));
2133 if (render_state->_hidden) {
2137 all_polysets =
false;
2140 }
else if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2144 all_polysets =
false;
2160 bool ignore_color) {
2161 VertexPoolTransform vpt;
2162 vpt._vertex_pool = vertex_pool;
2163 vpt._bake_in_uvs = render_state->_bake_in_uvs;
2164 vpt._transform = transform;
2166 VertexPoolData::iterator di;
2167 di = _vertex_pool_data.find(vpt);
2168 if (di != _vertex_pool_data.end()) {
2169 return (*di).second;
2175 Geom::NT_stdfloat, Geom::C_point);
2178 array_format->add_column
2179 (InternalName::get_normal(), 3,
2180 Geom::NT_stdfloat, Geom::C_normal);
2183 if (!ignore_color) {
2187 array_format->add_column(InternalName::get_color(), 1,
2188 Geom::NT_packed_dabc, Geom::C_color);
2190 array_format->add_column(InternalName::get_color(), 4,
2191 Geom::NT_uint8, Geom::C_color);
2195 vector_string uv_names, uvw_names, tbn_names;
2196 vertex_pool->
get_uv_names(uv_names, uvw_names, tbn_names);
2197 vector_string::const_iterator ni;
2198 for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
2199 string name = (*ni);
2201 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2203 if (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end()) {
2205 array_format->add_column
2206 (iname, 3, Geom::NT_stdfloat, Geom::C_texcoord);
2208 array_format->add_column
2209 (iname, 2, Geom::NT_stdfloat, Geom::C_texcoord);
2212 for (ni = tbn_names.begin(); ni != tbn_names.end(); ++ni) {
2213 string name = (*ni);
2215 PT(
InternalName) iname_t = InternalName::get_tangent_name(name);
2216 PT(
InternalName) iname_b = InternalName::get_binormal_name(name);
2218 array_format->add_column
2219 (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector);
2220 array_format->add_column
2221 (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector);
2224 vector_string aux_names;
2226 for (ni = aux_names.begin(); ni != aux_names.end(); ++ni) {
2227 string name = (*ni);
2229 array_format->add_column
2230 (iname, 4, Geom::NT_stdfloat, Geom::C_other);
2236 string name = _data->get_egg_filename().get_basename_wo_extension();
2247 temp_format->set_animation(animation);
2251 (InternalName::get_transform_blend(), 1,
2252 Geom::NT_uint16, Geom::C_index, 0, 2);
2253 temp_format->add_array(anim_array_format);
2257 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2260 EggMorphVertexList::const_iterator mvi;
2261 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2262 slider_names[(*mvi).get_name()].set_bit(vertex->
get_index());
2263 record_morph(anim_array_format, character_maker, (*mvi).
get_name(),
2264 InternalName::get_vertex(), 3);
2266 if (vertex->has_normal()) {
2267 EggMorphNormalList::const_iterator mni;
2268 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2269 slider_names[(*mni).get_name()].set_bit(vertex->
get_index());
2270 record_morph(anim_array_format, character_maker, (*mni).
get_name(),
2271 InternalName::get_normal(), 3);
2274 if (!ignore_color && vertex->has_color()) {
2275 EggMorphColorList::const_iterator mci;
2276 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2277 slider_names[(*mci).get_name()].set_bit(vertex->
get_index());
2278 record_morph(anim_array_format, character_maker, (*mci).
get_name(),
2279 InternalName::get_color(), 4);
2285 string name = egg_uv->get_name();
2286 bool has_w = (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end());
2287 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2289 EggMorphTexCoordList::const_iterator mti;
2290 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2291 slider_names[(*mti).get_name()].set_bit(vertex->
get_index());
2292 record_morph(anim_array_format, character_maker, (*mti).
get_name(),
2293 iname, has_w ? 3 : 2);
2298 if (!slider_names.empty()) {
2304 for (si = slider_names.begin(); si != slider_names.end(); ++si) {
2306 slider_table->add_slider(slider, (*si).second);
2312 name = character_maker->
get_name();
2315 temp_format->maybe_align_columns_for_animation();
2318 GeomVertexFormat::register_format(temp_format);
2326 vertex_data->reserve_num_rows(vertex_pool->
size());
2328 vertex_data->set_transform_blend_table(blend_table);
2329 if (slider_table !=
nullptr) {
2330 vertex_data->set_slider_table(SliderTable::register_table(slider_table));
2335 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2344 EggMorphVertexList::const_iterator mvi;
2345 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2348 InternalName::get_morph(InternalName::get_vertex(), morph.get_name());
2350 gvw.
add_data3d(morph.get_offset() * transform);
2354 if (vertex->has_normal()) {
2356 LNormald orig_normal = vertex->get_normal();
2357 LNormald transformed_normal = normalize(orig_normal * transform);
2361 EggMorphNormalList::const_iterator mni;
2362 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2365 InternalName::get_morph(InternalName::get_normal(), morph.get_name());
2367 LNormald morphed_normal = orig_normal + morph.get_offset();
2368 LNormald transformed_morphed_normal = normalize(morphed_normal * transform);
2369 LVector3d delta = transformed_morphed_normal - transformed_normal;
2375 if (!ignore_color && vertex->has_color()) {
2380 EggMorphColorList::const_iterator mci;
2381 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2384 InternalName::get_morph(InternalName::get_color(), morph.get_name());
2394 LTexCoord3d orig_uvw = egg_uv->
get_uvw();
2395 LTexCoord3d uvw = egg_uv->
get_uvw();
2397 string name = egg_uv->get_name();
2398 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2401 BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname);
2402 if (buv != render_state->_bake_in_uvs.end()) {
2404 uvw = uvw * (*buv).second->get_transform3d();
2410 EggMorphTexCoordList::const_iterator mti;
2411 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2414 InternalName::get_morph(iname, morph.get_name());
2416 LTexCoord3d duvw = morph.get_offset();
2417 if (buv != render_state->_bake_in_uvs.end()) {
2418 LTexCoord3d new_uvw = orig_uvw + duvw;
2419 duvw = (new_uvw * (*buv).second->get_transform3d()) - uvw;
2427 if (egg_uv->has_tangent() && egg_uv->has_binormal()) {
2428 PT(
InternalName) iname = InternalName::get_tangent_name(name);
2431 LVector3d tangent = egg_uv->get_tangent();
2432 LVector3d binormal = egg_uv->get_binormal();
2434 gvw.
set_column(InternalName::get_binormal_name(name));
2443 LVecBase4d aux = egg_aux->
get_aux();
2445 string name = egg_aux->get_name();
2454 gvw.
set_column(InternalName::get_transform_blend());
2459 bool inserted = _vertex_pool_data.insert
2460 (VertexPoolData::value_type(vpt, vertex_data)).second;
2461 nassertr(inserted, vertex_data);
2478 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2487 nassertr(vt !=
nullptr,
nullptr);
2492 double quantize = egg_vertex_membership_quantize;
2493 EggVertex::GroupRef::const_iterator gri;
2497 if (quantize != 0.0) {
2498 membership = cfloor(membership / quantize + 0.5) * quantize;
2502 nassertr(vt !=
nullptr,
nullptr);
2506 if (egg_vertex_max_num_joints >= 0) {
2511 int table_index = blend_table->add_blend(blend);
2528 int num_components) {
2530 InternalName::get_morph(column_name, morph_name);
2533 (delta_name, num_components,
2534 Geom::NT_stdfloat, Geom::C_morph_delta);
2546 bool has_overall_color,
const LColor &overall_color) {
2548 if (egg_prim->
is_of_type(EggPolygon::get_class_type())) {
2549 if (egg_prim->size() == 3) {
2553 }
else if (egg_prim->
is_of_type(EggTriangleStrip::get_class_type())) {
2556 }
else if (egg_prim->
is_of_type(EggTriangleFan::get_class_type())) {
2559 }
else if (egg_prim->
is_of_type(EggLine::get_class_type())) {
2560 if (egg_prim->size() == 2) {
2561 primitive =
new GeomLines(Geom::UH_static);
2566 }
else if (egg_prim->
is_of_type(EggPoint::get_class_type())) {
2569 }
else if (egg_prim->
is_of_type(EggPatch::get_class_type())) {
2570 int num_vertices = egg_prim->size();
2571 primitive =
new GeomPatches(num_vertices, Geom::UH_static);
2574 if (primitive ==
nullptr) {
2576 egg2pg_cat.warning()
2577 <<
"Ignoring " << egg_prim->get_type() <<
"\n";
2581 if (render_state->_flat_shaded) {
2582 primitive->set_shade_model(GeomPrimitive::SM_flat_first_vertex);
2584 }
else if (egg_prim->
get_shading() == EggPrimitive::S_overall) {
2585 primitive->set_shade_model(GeomPrimitive::SM_uniform);
2588 primitive->set_shade_model(GeomPrimitive::SM_smooth);
2593 PrimitiveUnifier pu(primitive);
2594 std::pair<UniquePrimitives::iterator, bool> result =
2595 unique_primitives.insert(UniquePrimitives::value_type(pu, primitive));
2597 if (result.second) {
2599 primitives.push_back(primitive);
2601 if (egg2pg_cat.is_debug()) {
2603 <<
"First primitive of type " << primitive->get_type()
2604 <<
": " << primitive <<
"\n";
2612 if (orig_prim->
get_num_vertices() + egg_prim->size() <= (
unsigned int)egg_max_indices) {
2613 primitive = orig_prim;
2615 }
else if (orig_prim != primitive) {
2617 (*result.first).second = primitive;
2619 if (egg2pg_cat.is_debug()) {
2621 <<
"Next primitive of type " << primitive->get_type()
2622 <<
": " << primitive <<
"\n";
2624 primitives.push_back(primitive);
2628 EggPrimitive::const_iterator vi;
2629 for (vi = egg_prim->begin(); vi != egg_prim->end(); ++vi) {
2630 primitive->add_vertex((*vi)->get_index());
2632 primitive->close_primitive();
2642 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2643 if (poly !=
nullptr) {
2646 EggPolygon::const_iterator vi;
2647 for (vi = poly->begin(); vi != poly->end(); ++vi) {
2648 LVertexd vert = (*vi)->
get_pos3() * mat;
2659 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2660 if (poly !=
nullptr) {
2661 if (poly->size() != 4) {
2663 <<
"Invalid number of vertices for " << egg_group->get_name() <<
"\n";
2667 LPoint3d v0 = (*poly)[0]->get_pos3() * mat;
2668 LPoint3d v1 = (*poly)[1]->get_pos3() * mat;
2669 LPoint3d v2 = (*poly)[2]->get_pos3() * mat;
2670 LPoint3d v3 = (*poly)[3]->get_pos3() * mat;
2672 LCAST(PN_stdfloat, v1),
2673 LCAST(PN_stdfloat, v2),
2674 LCAST(PN_stdfloat, v3));
2687 find_first_polygon(
EggGroup *egg_group) {
2689 EggGroup::const_iterator ci;
2690 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2691 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2698 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2699 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2701 PT(
EggPolygon) found = find_first_polygon(child_group);
2702 if (found !=
nullptr) {
2718 make_sphere(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2719 LPoint3 ¢er, PN_stdfloat &radius, LColor &color) {
2720 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2721 if (geom_group !=
nullptr) {
2725 EggGroup::const_iterator ci;
2726 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2727 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2729 EggPrimitive::const_iterator pi;
2730 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2731 vertices.insert(*pi);
2737 int num_vertices = 0;
2738 LPoint3d d_center(0.0, 0.0, 0.0);
2741 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2747 if (num_vertices > 0) {
2748 d_center /= (double)num_vertices;
2752 double radius2 = 0.0;
2753 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2756 LVector3d v = p3 - d_center;
2757 radius2 = max(radius2, v.length_squared());
2760 center = LCAST(PN_stdfloat, d_center);
2761 radius = sqrtf(radius2);
2764 vi = vertices.begin();
2778 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2779 const LMatrix4 &xform, LPoint3 &min_p, LPoint3 &max_p) {
2780 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2781 if (geom_group !=
nullptr) {
2785 EggGroup::const_iterator ci;
2786 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2787 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2789 EggPrimitive::const_iterator pi;
2790 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2791 vertices.insert(*pi);
2798 vi = vertices.begin();
2800 if (vi == vertices.end()) {
2808 LPoint3 min_pd = LCAST(PN_stdfloat, vertex->
get_pos3()) * xform;
2809 LPoint3 max_pd = min_pd;
2811 for (++vi; vi != vertices.end(); ++vi) {
2813 LPoint3 pos = LCAST(PN_stdfloat, vertex->
get_pos3()) * xform;
2814 min_pd.set(min(min_pd[0], pos[0]),
2815 min(min_pd[1], pos[1]),
2816 min(min_pd[2], pos[2]));
2817 max_pd.set(max(max_pd[0], pos[0]),
2818 max(max_pd[1], pos[1]),
2819 max(max_pd[2], pos[2]));
2824 return (min_pd != max_pd);
2834 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2835 LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
2837 color.set(1.0, 1.0, 1.0, 1.0);
2838 return make_box(egg_group, flags, LMatrix4::ident_mat(), min_p, max_p);
2848 if (egg_group->get_cs_type() != EggGroup::CST_none) {
2849 start_group = egg_group;
2852 switch (start_group->get_cs_type()) {
2853 case EggGroup::CST_none:
2857 case EggGroup::CST_plane:
2858 make_collision_plane(egg_group, cnode, start_group->get_collide_flags());
2861 case EggGroup::CST_polygon:
2862 make_collision_polygon(egg_group, cnode, start_group->get_collide_flags());
2865 case EggGroup::CST_polyset:
2866 make_collision_polyset(egg_group, cnode, start_group->get_collide_flags());
2869 case EggGroup::CST_sphere:
2870 make_collision_sphere(egg_group, cnode, start_group->get_collide_flags());
2873 case EggGroup::CST_box:
2874 make_collision_box(egg_group, cnode, start_group->get_collide_flags());
2877 case EggGroup::CST_inv_sphere:
2878 make_collision_inv_sphere(egg_group, cnode, start_group->get_collide_flags());
2881 case EggGroup::CST_tube:
2882 make_collision_capsule(egg_group, cnode, start_group->get_collide_flags());
2885 case EggGroup::CST_floor_mesh:
2886 make_collision_floor_mesh(egg_group, cnode, start_group->get_collide_flags());
2890 if ((start_group->get_collide_flags() & EggGroup::CF_descend) != 0) {
2892 EggGroup::const_iterator ci;
2893 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2894 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2895 make_collision_solids(start_group, DCAST(
EggGroup, *ci), cnode);
2899 egg2pg_cat.warning()
2900 <<
"Using <Collide> without 'descend' is deprecated. 'descend' "
2901 <<
"will become the default in a future version of Panda3D.\n";
2911 EggGroup::CollideFlags flags) {
2912 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2913 if (geom_group !=
nullptr) {
2914 EggGroup::const_iterator ci;
2915 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2916 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2918 create_collision_plane(DCAST(
EggPolygon, *ci), egg_group);
2919 if (csplane !=
nullptr) {
2920 apply_collision_flags(csplane, flags);
2921 csplane->
xform(cnode->get_transform()->get_mat());
2925 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
2929 make_collision_plane(temp_group, cnode, flags);
2945 EggGroup::CollideFlags flags) {
2947 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2950 if (geom_group !=
nullptr) {
2951 create_collision_floor_mesh(cnode, geom_group,flags);
2961 EggGroup::CollideFlags flags) {
2963 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2964 if (geom_group !=
nullptr) {
2965 EggGroup::const_iterator ci;
2966 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2967 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2968 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
2970 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
2974 make_collision_polygon(temp_group, cnode, flags);
2989 EggGroup::CollideFlags flags) {
2990 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2991 if (geom_group !=
nullptr) {
2992 EggGroup::const_iterator ci;
2993 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2994 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2995 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
2997 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
3001 make_collision_polyset(temp_group, cnode, flags);
3014 EggGroup::CollideFlags flags) {
3018 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3021 apply_collision_flags(cssphere, flags);
3022 cssphere->xform(cnode->get_transform()->get_mat());
3033 EggGroup::CollideFlags flags) {
3037 if (make_box(egg_group, flags, transform->get_mat(), min_p, max_p)) {
3040 apply_collision_flags(csbox, flags);
3051 EggGroup::CollideFlags flags) {
3055 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3058 apply_collision_flags(cssphere, flags);
3059 cssphere->xform(cnode->get_transform()->get_mat());
3070 EggGroup::CollideFlags flags) {
3071 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3072 if (geom_group !=
nullptr) {
3076 EggGroup::const_iterator ci;
3077 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3078 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
3080 EggPrimitive::const_iterator pi;
3081 for (pi = prim->begin(); pi != prim->end(); ++pi) {
3082 vertices.insert(*pi);
3089 size_t num_vertices = vertices.size();
3090 if (num_vertices != 0) {
3092 vpos.reserve(num_vertices);
3094 LPoint3d center(0.0, 0.0, 0.0);
3096 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
3098 const LPoint3d &pos = vtx->
get_pos3();
3099 vpos.push_back(pos);
3102 center /= (double)num_vertices;
3108 double radius2 = 0.0;
3109 LPoint3d far_a = center;
3110 for (i = 0; i < num_vertices; i++) {
3111 double dist2 = (vpos[i] - center).length_squared();
3112 if (dist2 > radius2) {
3122 LPoint3d far_b = center;
3123 for (i = 0; i < num_vertices; i++) {
3124 double dist2 = (vpos[i] - far_a).length_squared();
3125 if (dist2 > radius2) {
3142 LPoint3d cap_a_center(0.0, 0.0, 0.0);
3143 LPoint3d cap_b_center(0.0, 0.0, 0.0);
3149 double center_length = (far_a - far_b).length() / 4.0;
3150 double center_length2 = center_length * center_length;
3152 for (i = 0; i < num_vertices; i++) {
3153 double dist2 = (vpos[i] - center).length_squared();
3154 if (dist2 > center_length2) {
3157 double dist_a2 = (vpos[i] - far_a).length_squared();
3158 double dist_b2 = (vpos[i] - far_b).length_squared();
3159 if (dist_a2 < dist_b2) {
3161 cap_a_center += vpos[i];
3165 cap_b_center += vpos[i];
3171 if (num_a > 0 && num_b > 0) {
3172 cap_a_center /= (double)num_a;
3173 cap_b_center /= (double)num_b;
3177 LVector3d axis = cap_b_center - cap_a_center;
3182 if (IS_THRESHOLD_ZERO(axis[0], 0.01)) {
3185 if (IS_THRESHOLD_ZERO(axis[1], 0.01)) {
3188 if (IS_THRESHOLD_ZERO(axis[2], 0.01)) {
3200 look_at(mat, axis, LVector3d(0.0, 0.0, 1.0), CS_zup_right);
3201 mat.set_row(3, center);
3203 inv_mat.invert_from(mat);
3205 for (i = 0; i < num_vertices; i++) {
3206 vpos[i] = vpos[i] * inv_mat;
3209 double max_radius2 = 0.0;
3212 for (i = 0; i < num_vertices; i++) {
3213 LVector2d v(vpos[i][0], vpos[i][2]);
3214 double radius2 = v.length_squared();
3215 if (radius2 > max_radius2) {
3216 max_radius2 = radius2;
3226 for (i = 0; i < num_vertices; i++) {
3227 LVector2d v(vpos[i][0], vpos[i][2]);
3228 double radius2 = v.length_squared();
3230 if (vpos[i][1] < min_y) {
3233 double factor = sqrt(max_radius2 - radius2);
3234 min_y = min(min_y, vpos[i][1] + factor);
3236 }
else if (vpos[i][1] > max_y) {
3237 double factor = sqrt(max_radius2 - radius2);
3238 max_y = max(max_y, vpos[i][1] - factor);
3242 double length = max_y - min_y;
3243 double radius = sqrt(max_radius2);
3246 LVector3d half = axis * (length / 2.0);
3247 LPoint3d point_a = center - half;
3248 LPoint3d point_b = center + half;
3251 new CollisionCapsule(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
3253 apply_collision_flags(cscapsule, flags);
3254 cscapsule->xform(cnode->get_transform()->get_mat());
3266 apply_collision_flags(
CollisionSolid *solid, EggGroup::CollideFlags flags) {
3267 if ((flags & EggGroup::CF_intangible) != 0) {
3270 if ((flags & EggGroup::CF_level) != 0) {
3280 find_collision_geometry(
EggGroup *egg_group, EggGroup::CollideFlags flags) {
3281 if ((flags & EggGroup::CF_descend) != 0) {
3288 EggGroup::const_iterator ci;
3289 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3290 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3298 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3299 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
3301 if (child_group->get_cs_type() == egg_group->get_cs_type()) {
3318 <<
"Ignoring degenerate collision plane in " << parent_group->get_name()
3324 egg2pg_cat.warning()
3325 <<
"Non-planar polygon defining collision plane in "
3326 << parent_group->get_name()
3331 if (!egg_poly->empty()) {
3332 EggPolygon::const_iterator vi;
3333 vi = egg_poly->begin();
3335 LVertexd vert = (*vi)->get_pos3();
3336 vertices.push_back(LCAST(PN_stdfloat, vert));
3338 LVertexd last_vert = vert;
3340 while (vi != egg_poly->end()) {
3341 vert = (*vi)->get_pos3();
3342 if (!vert.almost_equal(last_vert)) {
3343 vertices.push_back(LCAST(PN_stdfloat, vert));
3351 if (vertices.size() < 3) {
3354 LPlane plane(vertices[0], vertices[1], vertices[2]);
3365 EggGroup::CollideFlags flags) {
3371 <<
"Ignoring degenerate collision polygon in "
3372 << parent_group->get_name()
3377 if (group->size() != 1) {
3379 <<
"Triangulating concave or non-planar collision polygon in "
3380 << parent_group->get_name()
3384 EggGroup::iterator ci;
3385 for (ci = group->begin(); ci != group->end(); ++ci) {
3389 if (!poly->empty()) {
3390 EggPolygon::const_iterator vi;
3393 LVertexd vert = (*vi)->get_pos3();
3394 vertices.push_back(LCAST(PN_stdfloat, vert));
3396 LVertexd last_vert = vert;
3398 while (vi != poly->end()) {
3399 vert = (*vi)->get_pos3();
3400 if (!vert.almost_equal(last_vert)) {
3401 vertices.push_back(LCAST(PN_stdfloat, vert));
3409 if (vertices.size() >= 3) {
3410 const LVertex *vertices_begin = &vertices[0];
3411 const LVertex *vertices_end = vertices_begin + vertices.size();
3414 if (cspoly->is_valid()) {
3415 apply_collision_flags(cspoly, flags);
3416 cspoly->xform(cnode->get_transform()->get_mat());
3430 EggGroup::CollideFlags flags) {
3434 pool.local_object();
3435 EggGroup::const_iterator egi;
3436 for (egi = parent_group->begin(); egi != parent_group->end(); ++egi) {
3437 if ((*egi)->is_of_type(EggPolygon::get_class_type())) {
3441 <<
"Ignoring degenerate collision polygon in "
3442 << parent_group->get_name()
3449 if(group->size() == 0) {
3451 <<
"empty collision solid\n";
3457 EggGroup::iterator ci;
3458 for (ci = group->begin(); ci != group->end(); ++ci) {
3460 if (poly->get_num_vertices() == 3) {
3461 CollisionFloorMesh::TriangleIndices tri;
3464 tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
3465 tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
3466 tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
3468 triangles.push_back(tri);
3469 }
else if (poly->get_num_vertices() == 4) {
3472 CollisionFloorMesh::TriangleIndices tri;
3473 CollisionFloorMesh::TriangleIndices tri2;
3476 tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
3477 tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
3478 tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
3480 triangles.push_back(tri);
3485 tri2.p3=pool.create_unique_vertex(*poly->
get_vertex(3))->get_index();
3488 triangles.push_back(tri2);
3497 for (vi = pool.begin(); vi != pool.end(); vi++) {
3498 csfloor->add_vertex(LCAST(PN_stdfloat,(*vi)->get_pos3()));
3503 for (ti = triangles.begin(); ti != triangles.end(); ti++) {
3504 CollisionFloorMesh::TriangleIndices triangle = *ti;
3505 csfloor->add_triangle(triangle.p1, triangle.p2, triangle.p3);
3507 csfloor->xform(cnode->get_transform()->get_mat());
3521 DeferredNodes::const_iterator dni;
3522 dni = _deferred_nodes.find(node);
3524 if (dni != _deferred_nodes.end()) {
3530 next_prop.apply_to_node(node);
3533 for (
int i = 0; i < num_children; i++) {
3534 apply_deferred_nodes(node->
get_child(i), next_prop);
3547 expand_all_object_types(
EggNode *egg_node) {
3548 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
3551 if (egg_group->get_num_object_types() != 0) {
3554 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3562 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
3564 EggGroupNode::const_iterator ci;
3565 ci = egg_group_node->begin();
3566 while (ci != egg_group_node->end()) {
3567 EggGroupNode::const_iterator cnext = ci;
3570 if (!expand_all_object_types(*ci)) {
3572 egg_group_node->erase(ci);
3593 int num_object_types = egg_group->get_num_object_types();
3596 vector_string object_types;
3598 for (i = 0; i < num_object_types; i++) {
3599 object_types.push_back(egg_group->get_object_type(i));
3601 egg_group->clear_object_types();
3603 for (i = 0; i < num_object_types; i++) {
3604 string object_type = object_types[i];
3608 if (!new_expanded.insert(object_type).second) {
3610 <<
"Cycle in ObjectType expansions:\n";
3612 for (pi = expanded_history.begin();
3613 pi != expanded_history.end();
3615 egg2pg_cat.error(
false)
3618 egg2pg_cat.error(
false) << object_type <<
"\n";
3624 new_expanded_history.push_back(object_type);
3626 if (!do_expand_object_type(egg_group, new_expanded,
3627 new_expanded_history, object_type)) {
3643 const string &object_type) {
3648 (
"egg-object-type-" +
downcase(object_type),
"");
3649 string egg_syntax = egg_object_type;
3651 if (!egg_object_type.has_value()) {
3654 if (cmp_nocase_uh(object_type,
"barrier") == 0) {
3655 egg_syntax =
"<Collide> { Polyset descend }";
3657 }
else if (cmp_nocase_uh(object_type,
"solidpoly") == 0) {
3658 egg_syntax =
"<Collide> { Polyset descend solid }";
3660 }
else if (cmp_nocase_uh(object_type,
"turnstile") == 0) {
3661 egg_syntax =
"<Collide> { Polyset descend turnstile }";
3663 }
else if (cmp_nocase_uh(object_type,
"sphere") == 0) {
3664 egg_syntax =
"<Collide> { Sphere descend }";
3666 }
else if (cmp_nocase_uh(object_type,
"tube") == 0) {
3667 egg_syntax =
"<Collide> { Tube descend }";
3669 }
else if (cmp_nocase_uh(object_type,
"trigger") == 0) {
3670 egg_syntax =
"<Collide> { Polyset descend intangible }";
3672 }
else if (cmp_nocase_uh(object_type,
"trigger_sphere") == 0) {
3673 egg_syntax =
"<Collide> { Sphere descend intangible }";
3675 }
else if (cmp_nocase_uh(object_type,
"eye_trigger") == 0) {
3676 egg_syntax =
"<Collide> { Polyset descend intangible center }";
3678 }
else if (cmp_nocase_uh(object_type,
"bubble") == 0) {
3679 egg_syntax =
"<Collide> { Sphere keep descend }";
3681 }
else if (cmp_nocase_uh(object_type,
"ghost") == 0) {
3682 egg_syntax =
"<Scalar> collide-mask { 0 }";
3684 }
else if (cmp_nocase_uh(object_type,
"dcs") == 0) {
3685 egg_syntax =
"<DCS> { 1 }";
3687 }
else if (cmp_nocase_uh(object_type,
"model") == 0) {
3688 egg_syntax =
"<Model> { 1 }";
3690 }
else if (cmp_nocase_uh(object_type,
"none") == 0) {
3694 }
else if (cmp_nocase_uh(object_type,
"backstage") == 0) {
3700 <<
"Unknown ObjectType " << object_type <<
"\n";
3702 egg2pg_cat.debug() <<
"returning true\n";
3707 if (!egg_syntax.empty()) {
3708 if (!egg_group->
parse_egg(egg_syntax)) {
3710 <<
"Error while parsing definition for ObjectType "
3711 << object_type <<
"\n";
3717 if (egg_group->get_num_object_types() != 0) {
3718 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3732 TextureStage::CombineMode EggLoader::
3734 EggTexture::CombineChannel channel) {
3735 switch (egg_tex->get_combine_mode(channel)) {
3736 case EggTexture::CM_unspecified:
3739 case EggTexture::CM_modulate:
3740 return TextureStage::CM_modulate;
3742 case EggTexture::CM_replace:
3743 return TextureStage::CM_replace;
3745 case EggTexture::CM_add:
3746 return TextureStage::CM_add;
3748 case EggTexture::CM_add_signed:
3749 return TextureStage::CM_add_signed;
3751 case EggTexture::CM_interpolate:
3752 return TextureStage::CM_interpolate;
3754 case EggTexture::CM_subtract:
3755 return TextureStage::CM_subtract;
3757 case EggTexture::CM_dot3_rgb:
3758 return TextureStage::CM_dot3_rgb;
3760 case EggTexture::CM_dot3_rgba:
3761 return TextureStage::CM_dot3_rgba;
3764 return TextureStage::CM_undefined;
3771 TextureStage::CombineSource EggLoader::
3772 get_combine_source(
const EggTexture *egg_tex,
3773 EggTexture::CombineChannel channel,
int n) {
3774 switch (egg_tex->get_combine_source(channel, n)) {
3775 case EggTexture::CS_unspecified:
3780 return TextureStage::CS_previous;
3782 return TextureStage::CS_texture;
3784 return TextureStage::CS_constant;
3788 case EggTexture::CS_texture:
3789 return TextureStage::CS_texture;
3791 case EggTexture::CS_constant:
3792 return TextureStage::CS_constant;
3794 case EggTexture::CS_primary_color:
3795 return TextureStage::CS_primary_color;
3797 case EggTexture::CS_previous:
3798 return TextureStage::CS_previous;
3800 case EggTexture::CS_constant_color_scale:
3801 return TextureStage::CS_constant_color_scale;
3803 case EggTexture::CS_last_saved_result:
3804 return TextureStage::CS_last_saved_result;
3807 return TextureStage::CS_undefined;
3814 TextureStage::CombineOperand EggLoader::
3815 get_combine_operand(
const EggTexture *egg_tex,
3816 EggTexture::CombineChannel channel,
int n) {
3817 switch (egg_tex->get_combine_operand(channel, n)) {
3818 case EggTexture::CO_unspecified:
3819 if (channel == EggTexture::CC_rgb) {
3822 return n < 2 ? TextureStage::CO_src_color : TextureStage::CO_src_alpha;
3825 return TextureStage::CO_src_alpha;
3828 case EggTexture::CO_src_color:
3829 return TextureStage::CO_src_color;
3831 case EggTexture::CO_one_minus_src_color:
3832 return TextureStage::CO_one_minus_src_color;
3834 case EggTexture::CO_src_alpha:
3835 return TextureStage::CO_src_alpha;
3837 case EggTexture::CO_one_minus_src_alpha:
3838 return TextureStage::CO_one_minus_src_alpha;
3841 return TextureStage::CO_undefined;
3848 ColorBlendAttrib::Mode EggLoader::
3849 get_color_blend_mode(EggGroup::BlendMode mode) {
3851 case EggGroup::BM_unspecified:
3852 case EggGroup::BM_none:
3853 return ColorBlendAttrib::M_none;
3854 case EggGroup::BM_add:
3855 return ColorBlendAttrib::M_add;
3856 case EggGroup::BM_subtract:
3857 return ColorBlendAttrib::M_subtract;
3858 case EggGroup::BM_inv_subtract:
3859 return ColorBlendAttrib::M_inv_subtract;
3860 case EggGroup::BM_min:
3861 return ColorBlendAttrib::M_min;
3862 case EggGroup::BM_max:
3863 return ColorBlendAttrib::M_max;
3866 return ColorBlendAttrib::M_none;
3873 ColorBlendAttrib::Operand EggLoader::
3874 get_color_blend_operand(EggGroup::BlendOperand operand) {
3876 case EggGroup::BO_zero:
3877 return ColorBlendAttrib::O_zero;
3878 case EggGroup::BO_unspecified:
3879 case EggGroup::BO_one:
3880 return ColorBlendAttrib::O_one;
3881 case EggGroup::BO_incoming_color:
3882 return ColorBlendAttrib::O_incoming_color;
3883 case EggGroup::BO_one_minus_incoming_color:
3884 return ColorBlendAttrib::O_one_minus_incoming_color;
3885 case EggGroup::BO_fbuffer_color:
3886 return ColorBlendAttrib::O_fbuffer_color;
3887 case EggGroup::BO_one_minus_fbuffer_color:
3888 return ColorBlendAttrib::O_one_minus_fbuffer_color;
3889 case EggGroup::BO_incoming_alpha:
3890 return ColorBlendAttrib::O_incoming_alpha;
3891 case EggGroup::BO_one_minus_incoming_alpha:
3892 return ColorBlendAttrib::O_one_minus_incoming_alpha;
3893 case EggGroup::BO_fbuffer_alpha:
3894 return ColorBlendAttrib::O_fbuffer_alpha;
3895 case EggGroup::BO_one_minus_fbuffer_alpha:
3896 return ColorBlendAttrib::O_one_minus_fbuffer_alpha;
3897 case EggGroup::BO_constant_color:
3898 return ColorBlendAttrib::O_constant_color;
3899 case EggGroup::BO_one_minus_constant_color:
3900 return ColorBlendAttrib::O_one_minus_constant_color;
3901 case EggGroup::BO_constant_alpha:
3902 return ColorBlendAttrib::O_constant_alpha;
3903 case EggGroup::BO_one_minus_constant_alpha:
3904 return ColorBlendAttrib::O_one_minus_constant_alpha;
3905 case EggGroup::BO_incoming_color_saturate:
3906 return ColorBlendAttrib::O_incoming_color_saturate;
3907 case EggGroup::BO_color_scale:
3908 return ColorBlendAttrib::O_color_scale;
3909 case EggGroup::BO_one_minus_color_scale:
3910 return ColorBlendAttrib::O_one_minus_color_scale;
3911 case EggGroup::BO_alpha_scale:
3912 return ColorBlendAttrib::O_alpha_scale;
3913 case EggGroup::BO_one_minus_alpha_scale:
3914 return ColorBlendAttrib::O_one_minus_alpha_scale;
3917 return ColorBlendAttrib::O_zero;
3923 bool EggLoader::VertexPoolTransform::
3924 operator < (
const EggLoader::VertexPoolTransform &other)
const {
3925 if (_vertex_pool != other._vertex_pool) {
3926 return _vertex_pool < other._vertex_pool;
3928 int compare = _transform.compare_to(other._transform, 0.001);
3933 if (_bake_in_uvs.size() != other._bake_in_uvs.size()) {
3934 return _bake_in_uvs.size() < other._bake_in_uvs.size();
3937 BakeInUVs::const_iterator ai, bi;
3938 ai = _bake_in_uvs.begin();
3939 bi = other._bake_in_uvs.begin();
3940 while (ai != _bake_in_uvs.end()) {
3941 nassertr(bi != other._bake_in_uvs.end(),
false);
3942 if ((*ai) != (*bi)) {
3943 return (*ai) < (*bi);
3948 nassertr(bi == other._bake_in_uvs.end(),
false);